feat: gestion RBAC granular, importacion sheets, filtrado de aulas virtuales y pisos, capacidad infinita y traduccion
This commit is contained in:
+205
-36
@@ -12,7 +12,7 @@
|
||||
* Manual de despliegue en producción con arquitectura WSGI (Gunicorn), Nginx como proxy inverso, Systemd unit y contenedorización Docker / Docker Compose.
|
||||
* **Archivos Base:**
|
||||
* Creación de `.env.example` con todas las variables requeridas (PostgreSQL, Flask, Secret Key, Babel).
|
||||
* Creación de `init_db.py` para bootstrap inicial seguro de base de datos y usuario administrador por defecto (`admin@edu-space.com` / `admin123`).
|
||||
* Creación y posterior actualización de `init_db.py` para bootstrap inicial seguro de base de datos, roles RBAC y usuario administrador por defecto (`admin@edu-space.com` / `admin123`).
|
||||
|
||||
---
|
||||
|
||||
@@ -20,65 +20,234 @@
|
||||
* **Preferencia de Idioma Persistente:**
|
||||
* Migración en PostgreSQL agregando la columna `preferred_language VARCHAR(10)` a la tabla `users`.
|
||||
* Actualización del modelo `User` en `app/models/user.py` con el campo `preferred_language`.
|
||||
* **Preferencia de Tema Visual Persistente:**
|
||||
* Migración agregando la columna `theme_preference VARCHAR(10) DEFAULT 'auto' NOT NULL` a la tabla `users`.
|
||||
* Soporte en el modelo `User` para valores `'auto'`, `'light'` y `'dark'`.
|
||||
* **Control de Acceso Basado en Roles (RBAC):**
|
||||
* Migración creando las tablas `roles` y `permissions`, y agregando la clave foránea `role_id` a la tabla `users`.
|
||||
* Modelos `Role` y `Permission` en `app/models/role.py`.
|
||||
* Métodos `has_permission(module, min_level)` y `can_manage()` en `User`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Implementación de Vistas y Plantillas Faltantes
|
||||
## 3. Implementación de Vistas y Plantillas
|
||||
* **Perfil de Usuario (`app/templates/auth/profile.html`):**
|
||||
* Vista completa con datos del usuario, rol, estado, fecha de registro y reservas recientes.
|
||||
* Formulario interactivo para configurar la **Preferencia de Idioma** (*Detectar automáticamente del navegador*, *Español*, *English*).
|
||||
* Formulario integral para configurar **Idioma de la interfaz** (*Detectar automáticamente del navegador*, *Español*, *English*) y **Tema visual** (*Automático*, *Modo Claro*, *Modo Oscuro*).
|
||||
* **Cambio de Contraseña (`app/templates/auth/change_password.html`):**
|
||||
* Formulario seguro para actualización de credenciales.
|
||||
* **Manejo de Errores (`app/templates/auth/403.html`):**
|
||||
* Pantalla de error 403 Forbidden estilizada.
|
||||
* Pantalla de error 403 Forbidden estilizada e integrada con el sistema de diseño.
|
||||
|
||||
---
|
||||
|
||||
## 4. Correcciones de UX y Bugs de Rutas
|
||||
## 4. Correcciones de UX, Linter y Bugs de Rutas
|
||||
* **Navbar Limpio (`app/templates/base.html`):**
|
||||
* Eliminación del bloque duplicado del menú de usuario `System Administrator`.
|
||||
* **Corrección de BuildError en Comisiones:**
|
||||
* En `app/routes/classrooms.py`, se agregó el alias de ruta `@classrooms_bp.route('/', endpoint='index')` para resolver enlaces a `classrooms.index`.
|
||||
* En `app/templates/schedule/commissions.html`, se reemplazó el filtro inválido de Django `truncatewords(20)` por el filtro estándar de Jinja2 `truncate(100)`.
|
||||
* **Corrección Visual en `/genetic-optimizer` (`app/templates/genetic_optimizer.html`):**
|
||||
* Se agregó el espaciado `pt-5 mt-4` evitando que la barra de navegación fija superior (`fixed-top`) se monte sobre el contenido.
|
||||
* Se agregó el espaciado `pt-5 mt-4` evitando que la barra fija superior se monte sobre el contenido.
|
||||
* Rediseño de tarjeta hero con contraste óptimo y reemplazo de iconos faltantes por Bootstrap Icons (`bi bi-...`).
|
||||
* **Corrección en Calendario (`app/templates/schedule/calendar.html`):**
|
||||
* Inclusión de contenedor con espaciado superior y bundle de localización `locales-all.min.js` para FullCalendar.
|
||||
* **Corrección de Errores del Linter en `schedule/add.html` y `schedule/view.html`:**
|
||||
* En `add.html`: Desacople de iteraciones Jinja a `<script type="application/json" id="classroom-data">` y parseo con `JSON.parse()`, eliminando 19 errores sintácticos del editor.
|
||||
* En `view.html`: Formateo de la propiedad inline `style` en barras de progreso para cumplir con el validador CSS.
|
||||
|
||||
---
|
||||
|
||||
## 5. Internacionalización (i18n) y Localización al Español
|
||||
* **Configuración del Motor Babel (`config/config.py` y `babel.cfg`):**
|
||||
* Configuración de `BABEL_TRANSLATION_DIRECTORIES` con ruta absoluta.
|
||||
* Actualización del método de extracción Jinja2 en `babel.cfg`.
|
||||
* **Formularios con Traducción Lazy (`lazy_gettext`):**
|
||||
* `app/forms/auth.py` (`LoginForm`).
|
||||
* `app/forms/classroom.py` (`ClassroomForm`, `ClassroomResourceForm`).
|
||||
* `app/forms/reservation.py` (`ReservationForm`).
|
||||
* **Traducción Integral de Plantillas:**
|
||||
* `app/templates/auth/login.html`: Pantalla de login traducida y con selector de idioma visible.
|
||||
* `app/templates/dashboard.html`: Todas las tarjetas estadísticas, acciones rápidas y tablas.
|
||||
* `app/templates/classrooms/list.html` y `add.html`: Filtros, estados vacíos, cabeceras y formularios.
|
||||
* `app/templates/schedule/today.html`: Horario del día, métricas y botones.
|
||||
* `app/templates/schedule/calendar.html`: Vistas, leyendas y eventos.
|
||||
* `app/templates/genetic_optimizer.html`: Estado del algoritmo y controles.
|
||||
* `app/templates/partials/language_switcher.html`: Muestra "Español" en lugar de "Spanish".
|
||||
* **Compilación de Catálogos:**
|
||||
* Compilación binaria de `messages.po` a `messages.mo` en `translations/es/` y `translations/en/` con 0 mensajes pendientes.
|
||||
## 5. Rediseño UI/UX, Assets Institucionales y Modo Claro/Oscuro
|
||||
* **Exploración e Integración de Assets Gráficos:**
|
||||
* Sincronización desde `app/resources` hacia `app/static/img/`:
|
||||
* `logo_unicaba.png`: Logo institucional principal para el login.
|
||||
* `logo_unicaba_mini.png`: Isotipo oficial para el navbar.
|
||||
* `favicon.png`: Favicon vinculado en las plantillas base.
|
||||
* `icons/`: Paquete de resoluciones WebApp/PWA.
|
||||
* **Sistema de Diseño y Tokens de Color (`app/static/css/theme.css`):**
|
||||
* Paleta institucional basada en Magenta/Uva (`#B43E8E`), acentos violetas (`#682CAD` / `#AE7FFF`) y secundarios magentas.
|
||||
* Tokens CSS para `:root` (Modo Claro) y `[data-bs-theme="dark"]` (Modo Oscuro).
|
||||
* Clases especializadas: `.auth-card`, `.navbar-app`, `.user-avatar-small`, `.theme-toggle-btn`, `.badge-brand`.
|
||||
* **Modo Claro / Modo Oscuro Dinámico (`app/static/js/theme-toggle.js`):**
|
||||
* Script anti-flickering en `<head>` para evitar parpadeos visuales al cargar la página.
|
||||
* Botón toggle interactivo con persistencia en `localStorage`.
|
||||
* En Modo Claro: Isotipo del navbar con filtro blanco puro (`brightness(0) invert(1)`) sobre el fondo magenta.
|
||||
* Selector de idioma (`#languageDropdown`) con fondo y bordes de alto contraste y tilde de verificación blanca (`bi-check-lg`) visible **únicamente** en el idioma activo sobre gradiente magenta.
|
||||
|
||||
---
|
||||
|
||||
## 6. Lógica de Detección y Precedencia de Idiomas
|
||||
En `app/__init__.py` (`get_locale()`):
|
||||
1. **Parámetro URL (`?lang=`):** Máxima prioridad para cambio explícito.
|
||||
2. **Preferencia en Perfil del Usuario (`current_user.preferred_language`):** Sobrescribe la configuración del navegador en toda la sesión si el usuario está autenticado.
|
||||
3. **Preferencia de Sesión (`session['language']`):** Cambio manual mediante el dropdown.
|
||||
4. **Detección Automática del Navegador (`request.accept_languages.best_match()`):** Valor por defecto para visitantes no autenticados y pantalla de login.
|
||||
* Al cerrar sesión (`logout`), se limpia la sesión para que el login use el navegador.
|
||||
* Al cambiar el idioma en el selector siendo usuario autenticado, se sincroniza automáticamente con su perfil en base de datos.
|
||||
## 6. Internacionalización (i18n), Localización y Formateo de Fechas
|
||||
* **Detección Inteligente de Subtags Regionales (`get_locale` en `app/__init__.py`):**
|
||||
* Extracción del subtag primario (`es` a partir de `es-419`, `es-AR`, `es-ES`), resolviendo el fallo donde Werkzeug saltaba erróneamente a inglés.
|
||||
* Configuración institucional: `BABEL_DEFAULT_LOCALE = 'es'` y `LANGUAGES = ['es', 'en']`.
|
||||
* **Reglas de Idioma para la Pantalla de Login:**
|
||||
* Resuelve según el navegador del visitante o recurre a español por defecto.
|
||||
* Inmunidad contra cookies o sesiones residuales de otros usuarios.
|
||||
* Flash messages traducidos (`¡Bienvenido de nuevo!`, `Has cerrado sesión correctamente`).
|
||||
* **Formateador de Fechas Localizadas en Jinja2:**
|
||||
* Registro de `format_date` y `format_datetime` de Flask-Babel.
|
||||
* Fechas en español natural en `schedule/today.html` (`Jueves, 3 de septiembre de 2026`), `view.html` y `list.html`.
|
||||
* **Traducción Integral de `schedule/add.html`:**
|
||||
* Formulario y textos de ayuda 100% traducidos.
|
||||
* Caja dinámica de resumen (JavaScript e `i18n-strings`) con cálculo de duración y validación de sobrecupo en español.
|
||||
|
||||
---
|
||||
|
||||
## 7. Configuración del Entorno de Desarrollo
|
||||
* Se creó `.vscode/settings.json` apuntando al intérprete del entorno virtual (`venv\Scripts\python.exe`), solucionando falsos positivos del analizador estático para `flask_wtf` y `flask_babel`.
|
||||
## 7. Módulo de Gestión de Accesos (RBAC) con Matriz FortiGate
|
||||
* **Modelos y Persistencia:**
|
||||
* Módulo `app/models/role.py` con `Role` y `Permission`.
|
||||
* Roles iniciales sembrados: `Admin` (total, protegido), `Docente` (reservas y horarios), `Operador` (aulas y reservas), `Consulta` (solo lectura).
|
||||
* Vinculación del usuario inicial `admin@edu-space.com` al rol `Admin`.
|
||||
* **Matriz de Permisos Estilo FortiGate (`/admin/roles/edit/<id>`):**
|
||||
* Tabla interactiva con columnas **Access Control** y **Permissions**.
|
||||
* Segmented control por módulo con tres estados: `🚫 None`, `👁️ Read` y `✏️ Read/Write`.
|
||||
* Color activo verde esmeralda FortiGate (`#2D9F6F`) con texto e icono en blanco puro.
|
||||
* Menú desplegable masivo **Set All ▾** (*Set All to None*, *Set All to Read*, *Set All to Read/Write*).
|
||||
* **Módulo de Administración (`app/routes/admin.py`):**
|
||||
* `/admin/roles`: Listado de roles, conteo de miembros, visualización de permisos en badges (RW, R, -) y modal de borrado seguro.
|
||||
* `/admin/users`: Listado de cuentas con filtros por nombre, rol y estado (Activo/Inactivo), paginación y switch rápido para alternar accesos.
|
||||
* `/admin/users/add` y `/admin/users/edit/<id>`: Formularios de alta y edición con asignación de rol y contraseña opcional.
|
||||
* **Seguridad y Decoradores (`app/utils/decorators.py`):**
|
||||
* `@permission_required(module, min_level)` y `@admin_required`.
|
||||
* Pestaña **Management** en el navbar visible exclusivamente para administradores.
|
||||
* Botones de acción sensibles en el navbar (*Add Classroom*, *New Reservation*) condicionados a permisos de escritura.
|
||||
|
||||
---
|
||||
|
||||
## 8. Sincronización y Actualización de `init_db.py`
|
||||
* Migraciones DDL automáticas (`ALTER TABLE ... ADD COLUMN IF NOT EXISTS`) para `preferred_language`, `theme_preference`, `role_id`, y para la tabla `careers` y columna `career_id` en `subjects`.
|
||||
* Creación y siembra de roles institucionales y permisos en PostgreSQL.
|
||||
* Configuración de salida con codificación UTF-8 segura en Windows para evitar excepciones de `cp1252`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Sincronización e Importación de Datos Académicos (Google Sheets)
|
||||
* **Modelo `Career` (`app/models/career.py`):**
|
||||
* Entidad de carreras universitarias vinculada con `Subject` vía relación uno a muchos.
|
||||
* Migración en PostgreSQL de la tabla `careers` y campo `career_id` en `subjects`.
|
||||
* **Servicio de Extracción ([app/services/sheets_importer.py](file:///c:/Workspace/admin-edu-space/app/services/sheets_importer.py)):**
|
||||
* Integración con la cartelera oficial UniCABA 2026 a través de 6 hojas CSV (`Lunes` a `Sábado`).
|
||||
* Normalización inteligente de espacios áulicos físicos (`Aula 402`, `Aula 302`), espacios virtuales (`VIRTUAL`), auditorios y salas de reunión.
|
||||
* Extracción y parseo de franjas horarias (`8:00 a 9:00hs`, `17:30 a 21:30hs`).
|
||||
* Rutina de **upsert** transaccional e idempotente que previene la duplicación de datos.
|
||||
* Generación de reservas/clases en el calendario para poblar instantáneamente las vistas de horario diario y semanal.
|
||||
* **Interfaz de Gestión (`/admin/import`):**
|
||||
* Vista interactiva con métricas en tiempo real (total de carreras, asignaturas, aulas, comisiones y clases).
|
||||
* Botón de ejecución manual de sincronización con indicador visual de progreso (`spinner`).
|
||||
* Reporte detallado de resultados y tabla con vista previa de asignaturas y comisiones sincronizadas.
|
||||
* **Acceso Rápido en Navbar (`app/templates/base.html`):**
|
||||
* Nueva opción **"Import from Google Sheets"** incorporada en el menú desplegable **Management**, restringida a roles con permisos administrativos.
|
||||
|
||||
---
|
||||
|
||||
## 10. Correcciones en la Vista de Calendario (FullCalendar) y Códigos de Asignatura
|
||||
* **Carga de Eventos y Corrección de Error 500 (`/schedule/calendar-data`):**
|
||||
* Se identificó y corrigió el error `AttributeError: 'str' object has no attribute 'value'` provocado por llamadas a `.status.value` sobre campos de estado textuales.
|
||||
* Se implementó el TypeDecorator `StatusType` con la clase `StatusString` en `app/models/reservation.py` garantizando compatibilidad total tanto para `.status` como para `.status.value`.
|
||||
* Sanitización de fechas ISO 8601 con zona horaria (`Z`, `-03:00`) enviadas por FullCalendar para comparación adecuada con campos `TIMESTAMP WITHOUT TIME ZONE` en PostgreSQL.
|
||||
* Anclaje de fecha inicial con `initialDate: '{{ today_date }}'` para posicionar el calendario en la semana activa de cursada 2026.
|
||||
* **Corrección del Código de Asignatura (`subject_code`):**
|
||||
* Se reemplazó la concatenación de código extendido de comisión (`Commission.get_full_code()` que arrojaba cadenas distorsionadas como `INGA0003-C1-2026-22026`) por el **código de asignatura real** del Sheet (`Subject.code`, ej. `INGA0003`, `ASIG00165`).
|
||||
* Propiedades de acceso directo añadidas en `Reservation`: `subject_code`, `subject_name` y `classroom_name`.
|
||||
* **Jerarquía Visual y Renderizado de Tarjetas (`calendar.html`):**
|
||||
* Implementación del hook `eventContent` en FullCalendar 5 para construir tarjetas personalizadas.
|
||||
* **Nombre de la Asignatura** destacado como elemento principal con tipografía grande y en negrita (`font-weight: 700; font-size: 0.88rem`).
|
||||
* **Código de Asignatura** y **Aula** mostrados como datos secundarios en badges de alto contraste (código con fondo oscuro translúcido y aula con isotipo y fondo blanco translúcido).
|
||||
* Modal interactivo instantáneo al hacer clic en cualquier evento con todos los detalles académicos de la clase y enlace a la ficha completa.
|
||||
|
||||
---
|
||||
|
||||
## 11. Filtros por Aula y Materia en el Calendario de Reservas
|
||||
* **Barra de Herramientas de Filtros Interactiva (`calendar.html`):**
|
||||
* **Filtrar por Aula:** Desplegable dinámico con todas las aulas activas ordenadas por edificio y código (físicas y virtuales). Al seleccionar un aula (ej. `Aula 402`), se eliminan todas las superposiciones visuales mostrando el cronograma limpio de ese espacio.
|
||||
* **Filtrar por Materia:** Desplegable ordenado alfabéticamente con formato `[Código] Nombre de la Asignatura`. Permite aislar todas las clases de una asignatura en particular.
|
||||
* **Filtrar por Carrera:** Filtro adicional por plan académico/carrera.
|
||||
* **Botón Limpiar Filtros:** Restablece instantáneamente todos los controles y refresca la vista.
|
||||
* **Insignias de Estado:** Indicador en tiempo real de los filtros aplicados y contador de clases visibles (`X clases visibles`).
|
||||
* **Soporte en Backend (`app/routes/schedule.py`):**
|
||||
* `calendar_view`: Suministra las listas de `classrooms`, `subjects` y `careers` a la plantilla.
|
||||
* `calendar_data`: Procesa `classroom_id`, `subject_id`, `career_id` y `search` aplicando cláusulas `filter()` con `JOIN` en SQLAlchemy.
|
||||
* `refetchEvents()` de FullCalendar conectado a los eventos `change` de cada selector para recarga inmediata vía AJAX sin parpadeo de pantalla.
|
||||
|
||||
---
|
||||
|
||||
## 12. Módulo de Gestión de Edificios y Corrección de Vistas de Aulas
|
||||
* **Corrección de Plantillas de Aulas Faltantes:**
|
||||
* Se crearon las plantillas [app/templates/classrooms/edit.html](file:///c:/Workspace/admin-edu-space/app/templates/classrooms/edit.html) y [app/templates/classrooms/view.html](file:///c:/Workspace/admin-edu-space/app/templates/classrooms/view.html), solucionando el error HTTP 500 (`TemplateNotFound: classrooms/edit.html`) y la redirección 302 que ocurría al hacer clic en cualquier aula.
|
||||
* La vista de ficha técnica del aula ahora muestra detalles de capacidad, piso, estado, edificio y la tabla interactiva de próximas reservas.
|
||||
* **Modelo y Base de Datos de Edificios (`Building`):**
|
||||
* Se creó el modelo [app/models/building.py](file:///c:/Workspace/admin-edu-space/app/models/building.py) (`id`, `name`, `code`, `address`, `floors`, `description`, `is_active`, timestamps y relación con `Classroom`).
|
||||
* Migración DDL en PostgreSQL (`CREATE TABLE buildings`, `ALTER TABLE classrooms ADD COLUMN building_id`).
|
||||
* Actualización de [init_db.py](file:///c:/Workspace/admin-edu-space/init_db.py) y siembra de edificios institucionales iniciales (`Edificio Central` y `Campus Virtual`) con vinculación de las 25 aulas existentes.
|
||||
* **Rutas y Gestión Completa (`app/routes/buildings.py`):**
|
||||
* `/buildings`: Listado con métricas de infraestructura (total de edificios, aulas activas, capacidad total y plantas/pisos), barra de búsqueda y filtros por estado.
|
||||
* `/buildings/<id>`: Vista de detalle con distribución de aulas organizadas visualmente por piso (Planta Baja, Piso 1, Piso 2, etc.), capacidad por sala y acciones directas.
|
||||
* `/buildings/add` y `/buildings/<id>/edit`: Formularios con validación WTForms para alta y actualización.
|
||||
* `/buildings/<id>/toggle` y `/buildings/<id>/delete`: Control de activación y eliminación protegida (impide borrar edificios que contengan aulas asignadas).
|
||||
* **Navegación (`app/templates/base.html`):**
|
||||
* Enlace a **Edificios** (`/buildings`) incorporado en el menú **Classrooms** y en el menú administrativo **Management**.
|
||||
|
||||
---
|
||||
|
||||
## 13. Mapeo de Campos del Google Sheet y Concepto de Turno (Mañana / Tarde)
|
||||
* **Uso de los 5 Campos de la Cartelera Oficial:**
|
||||
* **Codigo (`Subject.code` y `Commission.code`):** Almacena el código académico real (`INGA0003`, `ASIG00165`). Se expone como badge monoespaciado en eventos de calendario, comisiones y vistas administrativas.
|
||||
* **Asignatura (`Subject.name`):** Título principal de la materia destacado en texto grande y en negrita en FullCalendar y en la cartelera diaria.
|
||||
* **Aula (`Classroom.code`, `Classroom.building`, `Classroom.floor`, `Classroom.capacity`):** Normalización de espacios físicos y virtuales vinculados al nuevo modelo `Building`.
|
||||
* **Carrera (`Career.name` y `Subject.career_id`):** Entidad de carrera universitaria con relaciones relacionales normalizadas.
|
||||
* **Horarios (`Commission.schedule`, `Reservation.start_time`, `Reservation.end_time`):** Rango horario parseado hacia objetos `datetime` nativos para el motor de reservas y el calendario.
|
||||
* **Modelado y Captura de Turnos (`TURNO MAÑANA` y `TURNO VESPERTINO`):**
|
||||
* Se agregó la columna `shift` en las tablas `commissions` y `reservations` de PostgreSQL y en sus respectivos modelos de SQLAlchemy.
|
||||
* El parser de [app/services/sheets_importer.py](file:///c:/Workspace/admin-edu-space/app/services/sheets_importer.py) identifica las filas delimitadoras de bloque (`TURNO MAÑANA` vs `TURNO VESPERTINO / TARDE`) y corrobora la hora de inicio (< 13:00hs = Mañana, $\ge$ 14:00hs = Tarde).
|
||||
* Se sincronizaron todas las comisiones y reservas de cursada: 15 comisiones y 48 reservas en `Turno Mañana`; 191 comisiones y 364 reservas en `Turno Tarde / Vespertino`.
|
||||
* En el Calendario de Reservas (`/schedule/calendar`) se añadió el selector **Filtrar por Turno** (`Todos`, `Mañana`, `Tarde / Vespertino`), permitiendo a los usuarios aislar las franjas horarias y resolver la alta concentración de clases en el horario vespertino (17:30 a 21:30hs).
|
||||
|
||||
---
|
||||
|
||||
## 14. Accesos Directos en Panel, Ocultamiento de Virtuales, Filtro por Piso, Dirección Oficial y Traducción
|
||||
* **Tarjetas Estadísticas como Accesos Directos Interactivos ([app/templates/dashboard.html](file:///c:/Workspace/admin-edu-space/app/templates/dashboard.html)):**
|
||||
* **Total de Aulas (25):** Redirige a `/classrooms/list` con feedback visual de hover y elevación.
|
||||
* **Total de Materias (206):** Redirige a `/schedule/commissions`.
|
||||
* **Reservas de Hoy (18):** Redirige a `/schedule/today`.
|
||||
* **Esta Semana (103):** Redirige a `/schedule/calendar`.
|
||||
* Se añadieron microinteracciones CSS en [app/static/css/style.css](file:///c:/Workspace/admin-edu-space/app/static/css/style.css) (`.dashboard-stat-card`).
|
||||
* **Ocultar Aulas Virtuales y Filtro por Piso:**
|
||||
* **Calendario ([app/templates/schedule/calendar.html](file:///c:/Workspace/admin-edu-space/app/templates/schedule/calendar.html)):** Switch interactivo *Ocultar Aulas Virtuales* (indica capacidad ilimitada) y selector *Filtrar por Piso* (`Planta Baja`, `Piso 1`, `Piso 2`, `Piso 3`, `Piso 4`). El backend `/schedule/calendar-data` excluye las aulas virtuales o filtra por número de piso.
|
||||
* **Cartelera del Día ([app/templates/schedule/today.html](file:///c:/Workspace/admin-edu-space/app/templates/schedule/today.html)):** Barra de filtros completa con soporte para ocultar virtuales, piso y turno.
|
||||
* **Listado de Reservas ([app/templates/schedule/list.html](file:///c:/Workspace/admin-edu-space/app/templates/schedule/list.html)):** Endpoint `/schedule/list` totalmente operativo con paginación de 20 registros, preservación de query params y filtros de piso, turno, virtuales, estado y rango de fechas.
|
||||
* **Dirección Oficial de la Sede Central:**
|
||||
* Se configuró la dirección oficial de la Universidad de la Ciudad de Buenos Aires (UniCABA): **`Tte. Gral. Juan Domingo Perón 802, CABA`** en la base de datos, en [init_db.py](file:///c:/Workspace/admin-edu-space/init_db.py) y en el importador [app/services/sheets_importer.py](file:///c:/Workspace/admin-edu-space/app/services/sheets_importer.py).
|
||||
* **Traducción Integral al Español y Catálogo Babel:**
|
||||
* Se agregaron traducciones en [translations/es/LC_MESSAGES/messages.po](file:///c:/Workspace/admin-edu-space/translations/es/LC_MESSAGES/messages.po) y se recompiló el binario `.mo` con `pybabel`.
|
||||
* Textos traducidos: `Buildings` $\rightarrow$ *Edificios*, `Management` $\rightarrow$ *Gestión*, `Timeline View` $\rightarrow$ *Vista Cronológica*, `Grid View` $\rightarrow$ *Vista en Tabla*, `Active Classrooms` $\rightarrow$ *Aulas Ocupadas*, `All Reservations` $\rightarrow$ *Todas las Reservas*, `AI Room Optimizer` $\rightarrow$ *Optimizador de Aulas*, etc.
|
||||
|
||||
---
|
||||
|
||||
## 15. Actualización Integral de Roles RBAC, Capacidad Infinita (∞) y Horarios de Próximas Clases
|
||||
* **Actualización de Roles, Grupos de Acceso y Matriz de Permisos ([app/models/role.py](file:///c:/Workspace/admin-edu-space/app/models/role.py), [init_db.py](file:///c:/Workspace/admin-edu-space/init_db.py)):**
|
||||
* Se amplió `SYSTEM_MODULES` para cubrir los 8 módulos del sistema:
|
||||
1. `classrooms`: **Aulas y Espacios** (físicas, virtuales y capacidades).
|
||||
2. `buildings`: **Edificios y Sedes** (Sede Central, Campus Virtual, plantas).
|
||||
3. `reservations`: **Reservas de Aulas** (aprobación, confirmación, cancelación).
|
||||
4. `schedule`: **Cartelera y Cronograma** (calendario, cartelera del día, comisiones).
|
||||
5. `academic`: **Gestión Académica** (carreras, asignaturas, códigos).
|
||||
6. `import`: **Sincronización Sheets** (importador Google Sheets).
|
||||
7. `optimizer`: **Optimizador IA** (algoritmo genético áulico).
|
||||
8. `users`: **Usuarios y Accesos RBAC** (cuentas, roles y matriz).
|
||||
* Se actualizaron los perfiles estándar (`Admin`, `Docente`, `Operador`, `Consulta`) en PostgreSQL y en `init_db.py`.
|
||||
* Se tradujeron completamente las plantillas [app/templates/admin/roles/list.html](file:///c:/Workspace/admin-edu-space/app/templates/admin/roles/list.html) y [app/templates/admin/roles/edit.html](file:///c:/Workspace/admin-edu-space/app/templates/admin/roles/edit.html) al español.
|
||||
* **Soporte de Capacidad Infinita (∞) y Aclaración ([app/forms/classroom.py](file:///c:/Workspace/admin-edu-space/app/forms/classroom.py), [app/templates/classrooms/edit.html](file:///c:/Workspace/admin-edu-space/app/templates/classrooms/edit.html)):**
|
||||
* Se actualizó `ClassroomForm.capacity` con validador personalizado que admite el símbolo **`∞`**, `inf`, `0` o cualquier capacidad numérica positiva.
|
||||
* Se corrigió la validación de `floor` con `InputRequired` y `NumberRange(min=0)` para aceptar Planta Baja (Piso 0).
|
||||
* En la interfaz de edición y alta de aulas se incluyó el botón de acción rápida **`Ilimitada (∞)`** que rellena automáticamente el campo con el símbolo `∞`.
|
||||
* Se añadió una leyenda explicativa directa: *"Para aulas virtuales o eventos sin aforo restringido, ingrese ∞ o 0 (Capacidad ilimitada)"*.
|
||||
* Se tradujo el botón de guardado a *"Guardar Cambios"* (reemplazando *"Save Changes"*).
|
||||
* El aula virtual institucional (`Campus Virtual - VIRTUAL`) se actualizó a capacidad `0` (`∞`), renderizando el badge `∞ Ilimitada` en listados y fichas.
|
||||
* **Próximas Clases: Visualización Exclusiva del Horario ([app/templates/dashboard.html](file:///c:/Workspace/admin-edu-space/app/templates/dashboard.html), [app/templates/classrooms/view.html](file:///c:/Workspace/admin-edu-space/app/templates/classrooms/view.html)):**
|
||||
* En la tabla de *Próximas Reservas* del panel y en la ficha del aula se cambió la columna a **"Horario"**, removiendo la fecha del calendario y destacando únicamente el rango horario de cursada (ej. `17:30 - 21:30 hs`).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user