101 lines
8.0 KiB
Markdown
101 lines
8.0 KiB
Markdown
# Changelog: Corrección del Importador de Google Sheets, Clases Virtuales y Dashboards por Rol
|
|
|
|
**Fecha:** 18 de Septiembre de 2026
|
|
**Rama:** `testing`
|
|
**Autor:** Antigravity AI Assistant
|
|
|
|
---
|
|
|
|
## 1. Resumen Ejecutivo
|
|
|
|
Se investigó y resolvió la causa por la cual el importador de horarios desde Google Sheets no traía la totalidad de las clases virtuales ni se mostraban correctamente en las vistas del sistema (*Cartelera de Hoy*, *Catálogo de Aulas Virtuales*, *Cronograma* y *Dashboards*), tal como ocurría en la versión legacy.
|
|
|
|
### Causas Raíz Identificadas:
|
|
1. **Colisión de Horarios en Aulas Virtuales durante el Sync (`sheets_importer.py`)**:
|
|
- En la versión original, al buscar una reserva preexistente (`Reservation.query.filter_by(classroom_id=classroom.id, start_time=dt_start, end_time=dt_end).first()`), todas las clases virtuales apuntaban al mismo espacio (`Campus Virtual · VIRTUAL`).
|
|
- Cuando múltiples comisiones de diferentes asignaturas cursaban de manera virtual en la misma franja horaria (por ejemplo, jueves de 17:30 a 21:30 hs donde hay 13 comisiones simultáneas), el importador encontraba la primera reserva creada y descartaba las restantes 12 clases simultáneas actualizando únicamente notas/turno. Esto descartaba más del 75% de las clases virtuales de la planilla.
|
|
2. **Ausencia de Enlace Virtual Automático**:
|
|
- Las reservas virtuales se generaban sin enlace de videollamada (`virtual_link = None`), impidiendo que los botones de acceso directo ("Unirse a Videollamada / Zoom / Meet") se renderizaran en las vistas.
|
|
3. **Serialización Incompleta en la API Backend (`api/v1/reservations`)**:
|
|
- El endpoint `/api/v1/reservations` retornaba diccionarios planos sin el objeto anidado `classroom`, omitiendo propiedades críticas como `is_virtual`, `effective_virtual_link`, `subject_name`, `subject_code` y `location_display`.
|
|
4. **Falta de Agregación de Salas Virtuales en el BFF Node.js (`classrooms.js`)**:
|
|
- En el catálogo de aulas (`/classrooms/list_classrooms?view_mode=virtual`), la plantilla esperaba un arreglo `virtual_rooms` agrupado por comisión con métricas de demanda (`today_count`, `week_count`, `month_count`) y `global_virtual_metrics`. El controlador Node no las generaba, dejando la vista vacía.
|
|
5. **Rutas y Vista de Cartelera del Día (`schedule.js` y `app.js`)**:
|
|
- `/schedule/today_schedule` no estaba mapeado directamente en el enrutador de Express y su redirección descartaba parámetros de búsqueda (`hide_virtual`, `shift`, `floor`).
|
|
- El controlador no calculaba `time_blocks` (horas 7 a 21), provocando que `schedule/today.html` cayera en la condición vacía ("No hay reservas programadas para hoy").
|
|
|
|
---
|
|
|
|
## 2. Soluciones Implementadas
|
|
|
|
### A. Backend Python (`backend/app/services/sheets_importer.py`)
|
|
- Se diferenció la comprobación de unicidad para aulas virtuales: al tratarse de espacios con concurrencia ilimitada, la consulta de reserva existente incluye `commission_id=commission.id`.
|
|
- Se implementó la generación automática de enlaces de reunión seguros (`https://meet.google.com/edu-{subject_code}-{commission_code}`) para todas las clases y comisiones en modalidad virtual.
|
|
- **Resultado del re-sync:** Se procesaron 239 filas de las 6 hojas semanales, añadiendo **280 reservas** que antes colisionaban, alcanzando **388 reservas virtuales activas** en la base de datos con sus respectivos enlaces de videollamada.
|
|
|
|
### B. Endpoint de Reservas (`backend/app/routes/api/reservations.py`)
|
|
- Se enriqueció la serialización de reservas incorporando:
|
|
- Objeto anidado `classroom` con `code`, `floor`, `floor_display`, `is_virtual` y `location_display`.
|
|
- Objeto `commission` con `code` y `virtual_link`.
|
|
- Propiedades computadas `subject_name`, `subject_code`, `effective_virtual_link` e `is_virtual`.
|
|
- Se añadieron filtros por query params: `hide_virtual`, `floor`, `shift` y `search`.
|
|
|
|
### C. Catálogo de Aulas Virtuales (`frontend/src/routes/classrooms.js`)
|
|
- Para `view_mode === 'virtual'`, se implementó la agregación de reservas por comisión, calculando:
|
|
- `virtual_rooms`: Listado con código de comisión, asignatura, enlace de videollamada, cupo, turno y conteos de sesiones (Hoy, Semana, Mes).
|
|
- `global_virtual_metrics`: Contadores globales de clases remotas de hoy, semana, mes y comisiones con entorno virtual activo.
|
|
- Asignación de `virtual_classroom_id` para enlaces de gestión.
|
|
|
|
### D. Cartelera del Día (`frontend/src/routes/schedule.js` y `frontend/src/app.js`)
|
|
- Se unificaron las rutas `/today` y `/today_schedule`.
|
|
- Se implementó el generador de `time_blocks` para las franjas horarias de 7:00 a 22:00 hs.
|
|
- Se implementó soporte completo para el switch "Ocultar Aulas Virtuales" (`hide_virtual=1`), filtros por piso y por turno.
|
|
- Se preservan los query params en todas las redirecciones de Express.
|
|
|
|
### E. Dashboards Personalizados por Rol (`frontend/views/dashboard.html` y `dashboard.js`)
|
|
- Habilitación de paneles operativos específicos para **Bedelía**, **Docente / Profesor**, **Alumno / Estudiante** y **Administrador**, con selector dinámico en el banner superior.
|
|
|
|
---
|
|
|
|
## 3. Pruebas y Verificación
|
|
|
|
Se ejecutó la suite de verificación automatizada:
|
|
|
|
1. **Catálogo de Aulas Virtuales (`/classrooms/list_classrooms?view_mode=virtual`)**:
|
|
- Status: `200 OK`.
|
|
- Renderiza tarjetas `virtual-room-card` con enlaces a Google Meet y badges "Remoto ∞".
|
|
2. **Cartelera del Día (`/schedule/today_schedule`)**:
|
|
- Status: `200 OK`.
|
|
- Muestra timeline cronológico por horas con clases presenciales y virtuales.
|
|
- Botón `hide_virtual=1` filtra instantáneamente las aulas virtuales.
|
|
3. **Calendario General (`/schedule/calendar_data`)**:
|
|
- 643 eventos en calendario (388 virtuales identificados con `#6366F1` y enlaces activos).
|
|
4. **Vistas Principales**:
|
|
- 11/11 rutas pasaron con código 200 sin errores de plantilla ni excepciones de servidor.
|
|
|
|
---
|
|
|
|
## 4. Acople de `schedule.view_reservation` al BFF Node.js y Gestión de Comisiones
|
|
|
|
### A. Vista Detallada de Reserva (`schedule.view_reservation`)
|
|
- **Backend API (`/api/v1/reservations/<id>`)**:
|
|
- Enriquecimiento del payload serializado para incluir objetos relacionales completos: `classroom` (código, edificio, piso, capacidad, descripción, modalidad virtual), `commission` (código, código compuesto, materia, cuatrimestre, año, cupos), `user` (docente, nombre, apellido, email), `duration`, `effective_virtual_link` y `can_be_cancelled`.
|
|
- Incorporación de endpoints de acción directa `POST /api/v1/reservations/<id>/confirm` y `POST /api/v1/reservations/<id>/cancel`.
|
|
- **Node.js BFF (`frontend/src/routes/schedule.js`)**:
|
|
- Implementación de `handleViewReservation` con soporte para `/view_reservation`, `/view_reservation/:id`, `/view/:id`, y `/reservation/:id/view`.
|
|
- Implementación de `handleEditReservation` (GET & POST), `handleConfirmReservation` y `handleCancelReservation`.
|
|
- Actualización de plantillas (`view.html`, `today.html`, `list.html`, `dashboard.html`) para enlazar directamente las fichas pasando el ID de la reserva.
|
|
|
|
### B. Creación de Comisiones y Asociación con Materias (`/admin/commissions_list`)
|
|
- **Modal y Acción en Interfaz**:
|
|
- Incorporación de botón destacado `+ Nueva Comisión` en el encabezado y en el estado vacío de la tabla.
|
|
- Implementación de modal interactivo `#modalAddCommission`:
|
|
- Selector obligatorio de **Asignatura / Materia Asociada** (`subject_id`), mostrando código, nombre y carrera.
|
|
- Campos de código de comisión, cuatrimestre, año lectivo, turno, docente a cargo, cupo máximo y días/horarios.
|
|
- Generación y configuración de enlace a aula virtual (Google Meet institucional).
|
|
- Alerta de confirmación visual (`?created=1`) al registrar y vincular la comisión exitosamente.
|
|
- **Backend API (`POST /api/v1/admin/commissions`)**:
|
|
- Validación de existencia de la asignatura vinculada y resolución inteligente de duplicados (`subject_id`, `code`, `semester`, `year`).
|
|
- Auto-generación de enlaces seguros de Google Meet en caso de no especificarse enlace personalizado.
|
|
|