Files
admin-edu-space/docs/CHANGELOG_VIRTUAL_CLASSES_AND_DASHBOARDS.md

8.0 KiB

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.