37 KiB
37 KiB
Changelog Oficial — Admin Edu-Space (UniCABA)
Todas las modificaciones notables a este proyecto serán documentadas en este archivo. El formato está basado en Keep a Changelog y este proyecto se adhiere a Semantic Versioning.
[Unreleased]
Planificado (Fase 6 del Roadmap MVP)
- Despliegue e Infraestructura (Fase 6):
docker-compose.ymlproductivo orquestando Flask (Gunicorn), Node.js BFF (PM2) y PostgreSQL 15, con proxy inverso Nginx, SSL/TLS y compresión. - Sincronización Continua Moodle (Fase 6): Automatización de workers persistentes en background para el procesamiento continuo de la cola de Web Services Moodle 4.1.
- Pruebas de Carga y Hardening (Fase 6): Pruebas de estrés de concurrencia y validación final de producción.
[3.1.0] - 2026-09-23
Añadido
- ABM Integral de Ciclos Lectivos (
AcademicTerm):- Gestión End-to-End de Períodos Académicos: Implementación de ciclo de vida completo para ciclos lectivos: Alta, Edición, Establecimiento de Ciclo Actual, Toggle de Habilitación rápida y Eliminación protegida (
DELETE /api/v1/admin/academic-terms/<id>yPOST /api/v1/admin/academic-terms/<id>/toggle). - Integridad Relacional Protegida: Bloqueo de eliminación si el ciclo es el activo corriente, y fallback seguro a desactivación (
is_active = False) si el ciclo tiene comisiones históricas asociadas. - Interfaz Enriquecida en Bedelía / Admin: Botones de acción contextuales, switches y modales interactivos de confirmación (
#modalDeleteTerm) enfrontend/views/admin/academic_terms/list.html.
- Gestión End-to-End de Períodos Académicos: Implementación de ciclo de vida completo para ciclos lectivos: Alta, Edición, Establecimiento de Ciclo Actual, Toggle de Habilitación rápida y Eliminación protegida (
- ABM Completo de Espacios y Aulas (
Classroom):- Control de Estado y Borrado Seguro: Incorporación de toggle activo/inactivo (
POST /api/v1/classrooms/<id>/toggle) y endpoint de baja de aulas integrado con el frontend BFF (/classrooms/toggle_classroomy/classrooms/delete_classroom). - Acciones Rápidas en Vista Lista y Ficha: Botones de edición, alternancia de estado y eliminación con modales de advertencia en las vistas de cuadrícula/tabla (
list.html) y detalle (view.html).
- Control de Estado y Borrado Seguro: Incorporación de toggle activo/inactivo (
- ABM Completo de Reservas (
Reservation):- Eliminación Definitiva (Hard Delete): Soporte en backend para purga física de reservas (
DELETE /api/v1/reservations/<id>?hard=trueyPOST /api/v1/reservations/<id>/delete) complementando el flujo de cancelación lógica (CANCELLED). - Control Operativo en Vista Detalle: Botón de "Eliminar Reserva Definitivamente" con diálogo modal de confirmación en
/schedule/view.html.
- Eliminación Definitiva (Hard Delete): Soporte en backend para purga física de reservas (
- Auditoría y Cobertura 100% de ABMs en la Plataforma:
- Verificación y garantía de operaciones ABM completas en todos los componentes centrales: Sedes/Edificios (
Building), Aulas (Classroom), Ciclos Lectivos (AcademicTerm), Carreras (Career), Materias (Subject), Comisiones (Commission) y Reservas (Reservation).
- Verificación y garantía de operaciones ABM completas en todos los componentes centrales: Sedes/Edificios (
- Circuito Integral y Simplificado de Bedelía:
- Flujo Operativo Ágil para Bedelía:
- Circuito intuitivo de 3 pasos: Catálogo de Aulas (
/classrooms/list_classrooms) -> Creación/Edición con validación física/virtual y aforo real -> Asignación de Comisiones (/schedule/add_reservation). - Botón de acción rápida
Asignar Aula(bi-calendar-plus) en cada fila de/admin/commissions_list, permitiendo asignar espacio y horario a cualquier comisión en 1 solo clic. - Sincronización bidireccional de parámetros por URL (
?commission_id=...y?classroom_id=...) precargando automáticamente en el formulario de reserva la materia, código, cupo máximo de alumnos y enlace virtual de Google Meet / Teams. - Selectores inteligentes en cascada en
/schedule/add.htmlcon autoselección de Edificio, Piso y Aula al navegar desde el catálogo de espacios.
- Circuito intuitivo de 3 pasos: Catálogo de Aulas (
- Conexión REST en Vivo para Reservas:
- Sustitución de listas fijas/mockeadas en
frontend/src/routes/schedule.jspor consulta dinámica a/commissionsen vivo, permitiendo reservar aulas para cualquiera de las comisiones reales de la plataforma.
- Sustitución de listas fijas/mockeadas en
- Soporte Multisede Consistente en Aulas:
- Resolución robusta de
building_idy flagis_virtualenfrontend/src/routes/classrooms.js, eliminando hardcodes y asegurando que las aulas físicas pertenezcan a la sede seleccionada.
- Resolución robusta de
- Flujo Operativo Ágil para Bedelía:
- Personalización de Interfaz y Saludo en Dashboard (Configuración Global):
- Nueva Pestaña de Interfaz & Dashboard (
/admin/settings): Módulo en el panel de configuración global para personalizar elementos visuales del sistema. - Desactivación Opcional del Saludo y Selector de Rol: Switch interactivo para habilitar o deshabilitar el banner superior
¡Hola, {Usuario}!y el selector de perspectiva de roles endashboard.html. Al deshabilitarlo, el usuario accede directamente a los indicadores y accesos operativos de su rol sin distracciones ni dudas de contexto. - Persistencia y Endpoint REST: Parámetro
dashboard_role_banner_enabledadministrado víaPOST /api/v1/admin/settings/ui, respaldado porSystemSettingy registrado enAuditLog.
- Nueva Pestaña de Interfaz & Dashboard (
Corregido
- Motor de Purga y Reinicio de Datos Académicos:
- Solución al botón inerte de Purga: En
/admin/google_sheets_import, el botón "Ejecutar Purga de Datos Seleccionados" llamaba aopenPurgeModal(), el cual no ejecutaba ninguna acción por ausencia del modal#purgeConfirmModalen el DOM. Se incorporó el modal interactivo completo con desglose dinámico de elementos marcados para borrado, advertencia de preservación de usuarios y estado de carga (spinner). - Integridad Referencial en Purga Backend: En
backend/scripts/reset_academic_data.py, se reordenó la secuencia de borrado para respetar las restricciones de clave foránea (FK):Reservation->MilestoneGrade/AcademicMilestone->CommissionTeacher->StudentEnrollment->Commission->Subject->Career->ClassroomResource/Classroom. Esto previene fallos silenciosos por FK y garantiza que las carreras, asignaturas y comisiones se eliminen de manera limpia cuando son seleccionadas. - Preservación de Usuarios y Roles: La purga garantiza que ningún usuario (
User), contraseña administrativa ni rol (Role) sea alterado o eliminado durante el reseteo académico.
- Solución al botón inerte de Purga: En
- Saneamiento de Métricas y Edición de Edificios:
- Corrección de métricas de edificios en
/buildings/list_buildings: la capacidad virtual (9999) ya no distorsiona el cómputo de bancos físicos ni los percentiles de ocupación institucional. - Formulario de edición de sedes (
/buildings/edit/:id) corregido y persistido adecuadamente.
- Corrección de métricas de edificios en
- Instalador
install.sh:- Inclusión de banderas
--keep-dby--keep-userspara evitar sobreescritura de contraseñas y usuarios en reinstalaciones o actualizaciones.
- Inclusión de banderas
[3.0.0] - 2026-09-23
Añadido
- Fase 5 — Integración Auth, Email & Moodle Backend:
- Épica 1: Panel de Configuración Global (Perfil ADMIN):
- Cifrado simétrico de credenciales y secretos con Fernet (
CryptoServiceenbackend/app/services/crypto_service.py). - Migración y extensión de
SystemSettingcon columnascategoryeis_encrypted, junto con métodos polimórficosget_decrypted_value()yget_masked_value(). - Endpoints REST
/api/v1/admin/settings/*para administración dinámica de parámetros SMTP, toggles de proveedores SSO, Google OAuth y Web Services de Moodle 4.1. - Nueva vista responsiva
frontend/views/admin/settings/global_config.htmlcon soporte optimizado para pantallas 720p, 1360x768 y 1080p, y enlace integrado en el menú de navegación lateral.
- Cifrado simétrico de credenciales y secretos con Fernet (
- Épica 2: Infraestructura Asíncrona y Caché:
- Servicio híbrido de caché
CacheServicecon integración Redis y fallback en memoria/TTL. - Modelo
MoodleSyncTasky procesador asíncronoMoodleQueueServicecon Exponential Backoff y Dead Letter Queue (DLQ). - Métricas en vivo y reintentos manuales individuales y masivos para tareas en DLQ.
- Servicio híbrido de caché
- Épica 3: Autenticación Híbrida (SSO & Local):
- Login nativo como fallback con contingencia para cuentas con rol ADMIN.
- Integración de Google OAuth 2.0 basada en la arquitectura de AlumnosLS con filtrado estricto por dominios institucionales (
google_allowed_domains). - Autenticación delegada contra Moodle 4.1 vía
/login/token.php, mapeo inicial de roles (Admin/Docente/Alumno) y gestión de roles 100% desacoplada en Edu-Space.
- Épica 4: Integración Bidireccional Moodle 4.1:
- Adaptador
MoodleClientcon Web Services de Moodle 4.1 (core_user_*,enrol_manual_*,core_enrol_*,core_role_*). - Encolado no bloqueante de sincronización al crear o editar usuarios en Edu-Space.
- Adaptador
- Épica 5: Motor de Notificaciones (Email Server):
- Cliente SMTP dinámico en
EmailServicecon desencriptación en caliente de contraseñas. - Plantillas HTML transaccionales para asignación de comisiones a profesores, citación a exámenes y pruebas en vivo de conectividad.
- Cliente SMTP dinámico en
- Pruebas y Verificación:
- Suite de integración automatizada
backend/tests/test_phase6_integration.pycon 7 pruebas aprobadas al 100%. Regresión completa de 30 pruebas en verde en los módulos core.
- Suite de integración automatizada
- Épica 1: Panel de Configuración Global (Perfil ADMIN):
[2.8.0] - 2026-09-23
Añadido
- Fase 4 del Roadmap MVP — UI/UX Avanzada para Bedelía & Modo Impersonación:
- Estadio 4.1 — Grilla Semanal Interactiva (Drag-and-Drop) con Detección de Colisiones:
- Activación de arrastre y edición interactiva en FullCalendar (
editable: true,droppable: true,eventDurationEditable: true). - Panel lateral integrado de comisiones sin aula asignada (
unassigned_commissions) con arrastre fluido hacia la grilla semanal o diaria. - Endpoint REST
POST /api/v1/reservations/drag-updatecon validación previa de la matriz integral de conflictos (ReservationService.check_full_conflicts_matrix): colisión física de aula, colisión de horario docente y aforo de estudiantes. - Si existe colisión, retorna HTTP 409 (
status: conflict), revierte automáticamente la posición del evento en la grilla (info.revert()) y notifica al usuario con un Toast detallado del motivo del choque. - Si el espacio está disponible, actualiza o crea la reserva en base de datos, asienta la acción en
AuditLogy muestra confirmación visual de éxito.
- Activación de arrastre y edición interactiva en FullCalendar (
- Estadio 4.2 — Modo Impersonación del Superadmin:
- Soporte completo de cabecera
X-Impersonate-Useren el decorador JWT del Backend Flask (jwt_required) para administradores. - Endpoints administrativos
POST /api/v1/admin/impersonateyPOST /api/v1/admin/stop-impersonatingcon registro estricto enAuditLogbajo las accionesIMPERSONATE_STARTeIMPERSONATE_END. - Inyección contextual de impersonación en el Frontend BFF (
authMiddlewarey proxy transparente/api) mediante cookies segurasimpersonate_user_ideimpersonate_user_data. - Banner de advertencia visual permanente en la barra superior (
base.html) indicando el usuario y rol impersonado, con botón de salida inmediata hacia la sesión del administrador. - Botón de acceso directo para impersonar (
bi-incognito) en cada fila de usuario activo en/admin/users_list.
- Soporte completo de cabecera
- Estadio 4.3 — Acople del Optimizador Genético a Datos y Turnos Reales:
- Algoritmo genético (
ReservationOptimizer) adaptado a las franjas horarias y turnos institucionales reales de UniCABA (Mañana08:00-12:00,Tarde14:00-18:00,Vespertino/Noche18:30-22:30). - Soporte de guardado masivo en base de datos (
POST /api/genetic/apply-optimizationyapply_optimized_reservations) con prevención de solapamientos físicos y conversión estricta de fechas ISO.
- Algoritmo genético (
- Suite de Pruebas Unitarias de Fase 4:
- Archivo
backend/tests/test_phase4_interactive_impersonation.pycon 6 tests unitarios cubriendo los criterios de aceptación: impersonación como docente y estudiante, trazabilidad en auditoría, rechazo de impersonación para usuarios no administradores, finalización de impersonación, drag-update con bloqueo por colisión 409 y drag-update exitoso 200. - Regresión global de 18 tests (Fases 2, 3 y 4) aprobada al 100% (18/18 OK).
- Archivo
- Estadio 4.1 — Grilla Semanal Interactiva (Drag-and-Drop) con Detección de Colisiones:
[2.7.0] - 2026-09-23
Añadido
- Fase 3 del Roadmap MVP — Gestión de Hitos Evaluativos y Libro de Calificaciones (Gradebook):
- Estadio 3.1 — Calendario de Evaluación y Notificaciones Preventivas:
- Modelo relacional
MilestoneGrade(milestone_grades) asociado a estudiantes (User) y reservas de tipo hito (Reservation). - Servicio
GradebookService.get_student_upcoming_milestones: consulta inteligente de exámenes parciales, recuperatorios y entregas de TP de las comisiones en las que el alumno está matriculado. - Endpoint REST
GET /api/v1/students/my-upcoming-milestonescon cálculo de días restantes (days_remaining). - Cartelera y Widget de Próximos Exámenes en el Dashboard del Alumno (
/dashboard?role=alumno) con badges dinámicos de cuenta regresiva (¡Hoy!, ¡Mañana!, Faltan X días).
- Modelo relacional
- Estadio 3.2 — Libro de Calificaciones (Gradebook) y Cierre de Actas:
- Extensiones al modelo
Commission: camposgrades_closed(booleano),grades_closed_at(timestamp),grades_closed_by(ID usuario) yacta_number(código oficial de acta). - Servicio académico
GradebookService(backend/app/services/gradebook_service.py):get_commission_gradebook: matriz bidimensional consolidada de alumnos inscriptos y notas por hito evaluativo.save_single_gradeybulk_save_grades: registro y actualización de calificaciones con validación estricta de escala (1.0 a 10.0), flag de ausente (is_absent) y soporte de retroalimentación pedagógica (feedback).- Bloqueo por inmutabilidad: rechazo de modificaciones cuando el acta se encuentra cerrada.
close_gradebook: sellado oficial del acta con generación de identificador inmutable (ACTA-YYYY-Sem-ID), registro de auditoría enAuditLogy congelamiento de calificaciones.reopen_gradebook: reapertura excepcional para Bedelía/Admin con justificación administrativa obligatoria y registro en auditoría.get_student_grades: consolidado para el alumno de todas sus materias cursadas, notas por evaluación, promedio general y condición académica final (Promocionado, Regular, Libre).
- Endpoints REST de Calificaciones:
GET /api/v1/commissions/<id>/gradebook: estructura completa para la matriz del libro de calificaciones.PUT /api/v1/commissions/<id>/gradebook/grades: guardado masivo o individual de notas vía JSON.POST /api/v1/commissions/<id>/gradebook/close: cierre formal de acta.POST /api/v1/commissions/<id>/gradebook/reopen: reapertura justificada de acta.GET /api/v1/students/my-grades: consulta individual de notas y regularidad del estudiante.
- Interfaz de Usuario y Vistas Frontend BFF:
- Vista
/schedule/gradebook/:id: matriz interactiva con cálculo de promedio en tiempo real en el DOM, asignación de condición en vivo, autoguardado asíncrono debounced (500ms) con indicador flotante de estado (Guardando..., ✓ Todos los cambios guardados), filtro de búsqueda instantánea por alumno/legajo, modal de cierre formal de acta y modal de reapertura. - Vista
/schedule/my_grades(/mis-materias/mis-notas): portal del estudiante para consultar calificaciones por hito, promedios finales, condición de cursada y actas emitidas, con soporte de impresión de certificado de cursada. - Acceso directo integrado al Libro de Calificaciones en la tarjeta de comisión de
/admin/commission_detail. - Acceso directo a "Mis Calificaciones" en el launchpad de navegación del alumno en
/dashboard.
- Vista
- Script de migración de base de datos SQLite
backend/migrate_phase3_fields.py.
- Extensiones al modelo
- Suite de Pruebas Unitarias de Fase 3:
- Archivo
backend/tests/test_phase3_gradebook.pycon 6 tests unitarios cubriendo los criterios de aceptación de Fase 3: estructura de matriz, autoguardado de notas, validaciones de rango numérico, cierre formal de acta e inmutabilidad, consulta individual de notas y cuenta regresiva de próximos exámenes. 100% de tests aprobados (12/12 en suite global Fase 2 + Fase 3).
- Archivo
- Estadio 3.1 — Calendario de Evaluación y Notificaciones Preventivas:
[2.6.1] - 2026-09-23
Modificado
- Optimización de Espacio Vertical y Compatibilidad de Pantallas (720p / 1360x768 y 1080p):
- Navbar Compacta: Reducción de altura a 46px eliminando desperdicio de espacio superior para maximizar el área visible de trabajo de Bedelía.
- Botón de Toggle de Sidebar: Reingeniería visual del botón de alternancia del menú lateral con diseño circular limpio, micro-animación en hover y centrado perfecto.
- Soporte Multipantalla: Media queries CSS especializadas para resoluciones compactas habituales en puestos de trabajo de administración y bedelía argentina (1360x768 / 1366x768) y escalado equilibrado a 1920x1080 Full HD.
- Densidad de Información: Espaciados y márgenes optimizados para evitar scrolling innecesario en formularios y catálogos de comisiones y aulas.
[2.6.0] - 2026-09-19
Añadido
- Fase 2 del Roadmap MVP — Co-docencia, Matriz de Conflictos y Regla Diaria:
- Estadio 2.1 — Modelo y Gestión Integral de Co-docencia:
- Modelo relacional
CommissionTeacher(commission_teachers) con roles de cátedra (Titular,Adjunto,JTP,Ayudante) y flags de docente principal. - Endpoints REST de cátedra:
POST /api/v1/commissions/<id>/teachersyDELETE /api/v1/commissions/<id>/teachers/<user_id>con control de duplicados y asignación dinámica. - Integración visual en el detalle de la comisión (
/admin/commission_detail) con tarjeta interactiva para vincular/desvincular integrantes del equipo docente y badges de rol en la grilla general (/admin/commissions_list).
- Modelo relacional
- Estadio 2.2 — Matriz de Conflictos y Validación Integral:
- Conflicto Físico Estricto: Bloqueo estricto de superposición horaria en la misma aula física (
ReservationRepository.find_overlapping&check_physical_conflicts). - Conflicto Docente Inteligente: Detección de doble reserva simultánea para un mismo profesor (
ReservationRepository.find_teacher_conflicts&check_teacher_conflicts). - Excepción Justificada por Co-docencia: Si un docente asignado presenta solapamiento pero la comisión cuenta con co-docentes registrados en
CommissionTeacher, el motor de conflictos autoriza la reserva validando la cobertura del equipo de cátedra. - Conflicto de Aforo: Bloqueo estricto cuando la cantidad de asistentes esperados (
expected_attendees) excede la capacidad física declarada del aula (classroom.capacity). - Endpoint unificado
POST /api/v1/reservations/check-conflictspara pre-validación asíncrona de conflictos físicos, docentes y de capacidad antes del guardado.
- Conflicto Físico Estricto: Bloqueo estricto de superposición horaria en la misma aula física (
- Estadio 2.3 — Regla de Restricción Diaria del Alumno y Motor de Excepciones:
- Servicio académico
EnrollmentService(backend/app/services/enrollment_service.py) para control de cupos, inscripciones activas y análisis de días de cursada. - Regla Diaria: Un alumno no puede matricularse en dos materias regulares programadas para el mismo día de la semana.
- Excepción Automática por Curso Corto: Indicador
is_short_courseen modeloSubject; si una de las asignaturas es un taller, seminario o curso corto, el sistema autoriza automáticamente la cursada simultánea en el mismo día. - Excepción Expresa de Bedelía: Parámetros
allow_same_day_exceptionyexception_reasonen el modeloStudentEnrollment, permitiendo a Bedelía inscribir alumnos con justificación administrativa expresa (cambio de plan, equivalencias, etc.). - Endpoints de gestión de matrículas por comisión:
GET /api/v1/commissions/<id>/enrollments,POST /api/v1/commissions/<id>/enrollments,DELETE /api/v1/commissions/<id>/enrollments/<student_id>yPUT /api/v1/commissions/<id>/enrollments/<student_id>. - Adaptación completa de UI en
/admin/commission_detailcon selector de estudiantes, toggle interactivo de excepción de Bedelía, campo de motivo justificado, y tabla de estudiantes matriculados con badges de excepción.
- Servicio académico
- Suite de Pruebas Unitarias e Integrales de Reglas de Negocio:
- Archivo
backend/tests/test_phase2_rules.pycon 6 tests completos verificando: bloqueo físico, conflicto de aforo, detección docente con bypass de co-docencia, restricción diaria de cursada, excepción por curso corto y excepción por autorización manual de Bedelía. 100% de tests aprobados.
- Archivo
- Mejoras UI/UX en Dashboard de Bedelía:
- Paneles interactivos para visualizar Comisiones Sin Reserva de Aula y Aulas Disponibles con soporte de filtrado temporal (Semana/Mes) directamente consumiendo estadísticas en tiempo real del motor backend.
- Fase 1: Auditoría y Seguridad Automatizada:
- Control de Entorno Dev: Aislamiento de herramientas de seguridad en
requirements-dev.txt. - Automatización Local e Integración Continua: Correcciones de evaluación en
security_audit.batpara Windows y actualización de.gitea/workflows/security-audit.yamlpara asegurar la correcta ejecución del stack de auditoría (Bandit, pip-audit, njsscan y Schemathesis).
- Control de Entorno Dev: Aislamiento de herramientas de seguridad en
- Estadio 2.1 — Modelo y Gestión Integral de Co-docencia:
[2.5.0] - 2026-09-19
Añadido
- Auditoría y Seguridad Automatizada Completa (Python & Node.js):
- Python SAST (
bandit): Escaneo estático del backend Flask de más de 8.400 líneas. Corrección de vulnerabilidad B310 ensheets_importer.pymediante validación estricta de esquema HTTP/HTTPS para prevenir ataques de tipo SSRF. Resultado: 0 fallos detectados. - Python SCA (
pip-audit): Análisis de dependencias con base OSV; detección de 24 CVEs históricas en paquetes desactualizados y actualización completa a versiones seguras (Flask>=3.1.3,Werkzeug>=3.1.8,requests>=2.34.2,bleach>=6.4.0,python-dotenv>=1.2.3). Resultado: 0 CVEs activas. - Python DAST / Fuzzing (
schemathesis): Especificación OpenAPI 3.0.3 enbackend/app/routes/api/openapi.py(/api/v1/openapi.json). Ejecución de 114 casos de prueba dinámicos con mutación de datos. Detección y corrección de caída 500 por payload de tipo JSON inválido en/auth/login. Resultado: 114/114 pruebas aprobadas con 0 errores de servidor. - Node.js SAST (
njsscan): Análisis de patrones de código inseguro en el BFF Express (frontend/src). Resultado: 0 hallazgos. - Node.js SCA (
npm audit): Auditoría continua de paquetes npm con 0 vulnerabilidades reportadas. - Blindaje Activo (
helmet&express-rate-limit): Incorporación de cabeceras HTTP defensivas (HSTS,nosniff,SAMEORIGIN,X-Permitted-Cross-Domain-Policies) y limitadores de tasa ante fuerza bruta en/auth/login(30 req / 15 min) y/api(180 req / min). - Script Unificado de Auditoría (
security_audit.bat): Ejecutable centralizado para correr los 5 controles en un solo comando. - Documento Formal de Seguridad (
SECURITY_AUDIT_REPORT.md): Reporte ejecutivo de auditoría y controles continuos.
- Python SAST (
[2.4.0] - 2026-09-19
Añadido
- Perfil Extendido de Usuarios y Tipificaciones de Documentos Oficiales (Argentina y Extranjeros):
- Incorporación en el modelo
Userde los campos:first_name(Nombre),last_name(Apellido),email(Email Institucional de acceso),personal_email(Email Personal/Particular de contacto),phone(Teléfono con código de área),address(Domicilio/Dirección),document_type(Tipo de documento) ydocument_number(Número de documento validado). - Catálogo formal de reglas de negocio en
backend/app/constants/document_types.pycon tipificaciones oficiales de Argentina y extranjeros (DNI, CUIL, Pasaporte Argentino, Pasaporte Extranjero, DNI Extranjero, Cédula de Identidad PFA, Cédula Mercosur, Libreta Cívica y Libreta de Enrolamiento). - Validaciones de formato, expresiones regulares, y verificación de unicidad de documento por tipo en endpoints
POST /api/v1/usersyPUT /api/v1/users/<id>. - Búsqueda dinámica en
/admin/users_listhabilitada para filtrar por número de documento o email personal/institucional además de nombre. - Rediseño del formulario
/admin/users/formestructurado en secciones: Identidad y Documentación, Contacto y Domicilio (con Teléfono, Email Personal y Dirección), y Cuenta y Rol Institucional (con Email Institucional y Clave), permitiendo al Administrador General gestionar la totalidad de los datos. - Script de migración SQLite
backend/migrate_user_profile_fields.pypara agregar las columnas e inicializar nombres desglosados de los usuarios existentes.
- Incorporación en el modelo
- Co-Docencia y Cátedras Múltiples en Comisiones:
- Creación del modelo relacional
CommissionTeacher(commission_teachers) para asociar múltiples docentes a una misma comisión con roles académicos diferenciados (Titular,Adjunto,JTP,Ayudante). - Nuevos endpoints en la API REST:
POST /api/v1/commissions/<id>/teachersyDELETE /api/v1/commissions/<id>/teachers/<user_id>, junto con la serialización completa de cátedras enGET /api/v1/commissions. - Nueva tarjeta interactiva "Equipo Docente / Cátedra" en el detalle de la comisión (
/admin/commission_detail?id=...) permitiendo agregar y desvincular docentes con sus respectivos roles. - Actualización de la grilla de comisiones (
/admin/commissions_list) para exhibir a todos los profesores asignados con badges distintivos de rol.
- Creación del modelo relacional
- Eliminación y Gestión Segura de Asignaturas:
- Incorporación de botón y modal interactivo de confirmación de eliminación de asignaturas en
/admin/subjects_list. - Implementación de regla de negocio de integridad académica: eliminación física si la materia no tiene comisiones asociadas, o desactivación automática si posee historial o cursadas vinculadas.
- Incorporación de botón y modal interactivo de confirmación de eliminación de asignaturas en
Corregido
- Bug Visual en Modificación de Asignaturas (
/admin/subjects_list):- Solucionado el problema de modales recortados o cubiertos por el fondo oscuro (
modal-backdrop), originado por la presencia de 206 modales inline dentro de celdas<td>en una tabla conoverflow(.table-responsive). Se refactorizó hacia un único modal global#modalEditSubjectinstanciado fuera de la tabla e inicializado dinámicamente con JavaScript.
- Solucionado el problema de modales recortados o cubiertos por el fondo oscuro (
Añadido
- Monitoreo y Percentiles de Asignación de Aulas Físicas (Admin & Bedelía):
- Panel analítico "Estado y Percentiles de Asignación de Aulas Físicas" incorporado en los dashboards de Administrador (
/dashboard?role=admin) y Bedelía (/dashboard?role=bedelia). - Cálculo dinámico en tiempo real de Aulas Asignadas en número y percentil (26 aulas · 96.3%) con enlace directo a cursadas activas.
- Cálculo dinámico en tiempo real de Aulas Sin Asignar / Libres en número y percentil (1 aula · 3.7%) con enlace directo al formulario de asignación de espacios.
- Barras de progreso visuales con desglose dual: Planificación Cuatrimestral (96.3% asignado vs 3.7% disponible) y Ocupación Operativa del Día (aulas con clases hoy vs aulas libres).
- Exposición de métricas de asignación y percentiles en el endpoint de la API REST
GET /api/v1/dashboard/stats.
- Panel analítico "Estado y Percentiles de Asignación de Aulas Físicas" incorporado en los dashboards de Administrador (
- Módulo de Cursadas Asignadas y Métricas Reales en Catálogo Presencial (
/classrooms/list_classrooms?view_mode=physical):- Incorporación de la sección "Cursadas Asignadas" dentro de cada tarjeta de aula física y columna en vista de tabla, detallando asignaturas, comisiones y turnos.
- Métricas de ocupación física real por período (Día, Semana, Mes) con porcentajes calculados dinámicamente (6%, 11%, 17%, 22% según la carga horaria del aula).
- Botones de acción directa con ID dinámico: Ficha (
/classrooms/view_classroom?id=...), Horarios en Calendario (/schedule/calendar_view?classroom_id=...) y Editar. - Conexión de la tabla "Próximas Clases y Reservas" en la ficha individual del aula (
/classrooms/view_classroom) con las reservas reales del cuatrimestre y enlaces a cada reserva (/schedule/view_reservation?id=...).
Modificado
- Dashboard Docente (
/dashboard?role=docente):- Eliminado el botón flotante "Reservar Aula / Solicitar espacio para clase" (
/schedule/add_reservation) a petición de los requerimientos funcionales del cuerpo docente. - Reorganizada la grilla superior a 3 columnas simétricas (
col-md-4) para las tarjetas de Mis Clases Hoy, Mis Reservas Activas y Aulas Virtuales.
- Eliminado el botón flotante "Reservar Aula / Solicitar espacio para clase" (
Corregido
- Fallo Crítico de Renderizado en Nunjucks (
memberLookupcon.items):- Solucionada la incompatibilidad de
nunjucks/src/jinja-compatque interceptaba la propiedad.itemsconvirtiendoclassrooms.itemsen una función interna en lugar de un array, lo que impedía dibujar las tarjetas de aulas presenciales enfrontend/views/classrooms/list.html. - Implementado interceptor en
memberLookupenfrontend/src/app.jspara preservar arrays intactos.
- Solucionada la incompatibilidad de
- Clasificación Errónea de Reservas Físicas como Virtuales (
is_virtual):- Corregida la propiedad
@property is_virtualenReservation(backend/app/models/reservation.py) para garantizar que si una reserva tiene aula física asignada (self.classroom and not self.classroom.is_virtual), siempre sea clasificada como presencial (is_virtual = False), evitando falsos positivos cuando la comisión posee un enlace virtual predeterminado.
- Corregida la propiedad
- Excepción de SQLAlchemy en Estadísticas de Dashboard:
- Corregido el error de ejecución generado al invocar
.ilike()sobre la propiedad Python@property Classroom.room_numberenbackend/app/routes/api/dashboard.py, migrando la clasificación de aulas presenciales y virtuales a una evaluación robusta en memoria Python (Classroom.codeyClassroom.building).
- Corregido el error de ejecución generado al invocar
[2.2.0] - 2026-09-19
Añadido
- Herramienta de Purga y Reinicio de Datos Académicos (
reset_academic_data):- Script CLI
backend/scripts/reset_academic_data.pycon argumentos de limpieza granular (--all,--reservations,--classrooms,--careers,--yes). - Endpoint de API
POST /api/v1/admin/reset-academic-dataprotegido por JWT (roladmin) con registro enAuditLog. - Panel interactivo "Zona de Reinicio y Purga Académica" en
/admin/google_sheets_importcon checkboxes independientes para reservas, aulas, comisiones, asignaturas y carreras. - Modal modal de confirmación con advertencias de seguridad para prevenir purgas accidentales.
- Preservación íntegra de usuarios del sistema, credenciales de acceso, roles RBAC y registros de auditoría.
- Script CLI
- Configuración Global Dinámica de Google Sheets:
- Nuevo modelo
SystemSetting(backend/app/models/setting.py) para almacenamiento persistente clave-valor en base de datos. - Endpoints
GET /api/v1/admin/sheets-configyPOST /api/v1/admin/sheets-config. - Normalizador de enlaces en
GoogleSheetsImportercompatible con URLs compartidas de edición (/spreadsheets/d/.../edit) o enlaces publicados (/pub?output=csv). - Interfaz web con formulario de edición de URL, botón de guardado en caliente, restauración a URL oficial predeterminada y acceso directo a Google Docs.
- Nuevo modelo
- Visualización de Asignaturas Reales:
- Tabla de asignaturas recientemente sincronizadas conectada a la base de datos real en lugar de datos de muestra (mock).
Corregido
- Fallo por Timeout en Google Sheets Academic Sync:
- Solucionado el corte prematuro de conexión en el BFF (
frontend/src/services/apiClient.js), aumentando el timeout base a 25s y el timeout específico de sincronización a 90s (anteriormente limitado a 5s en operaciones que toman ~6.7s). - Eliminado el enmascaramiento silencioso de errores en el BFF, permitiendo reportar fallos reales o éxitos detallados (+carreras, +aulas, +materias, +comisiones, +reservas).
- Solucionado el corte prematuro de conexión en el BFF (
[2.1.0] - 2026-09-19
Añadido
- Ficha Detallada de Reserva (
schedule.view_reservation):- Implementación en BFF Node.js de la ruta
/schedule/view_reservation(soportando parámetros:id,?id=o selección automática del primer registro). - Vistas y controladores para modificar reservas con selectores en cascada (
/schedule/edit_reservation). - Endpoints de acción rápida en backend y BFF:
POST /schedule/confirm_reservationyPOST /schedule/cancel_reservation. - Actualización de enlaces en
today.html,list.html,dashboard.htmlyview.htmlpara navegar directamente con el identificador de la reserva (?id=...).
- Implementación en BFF Node.js de la ruta
- Creación y Asociación de Comisiones a Asignaturas (
admin/commissions_list):- Botón destacado
+ Nueva Comisiónen el encabezado y en el estado vacío de la tabla. - Modal interactivo
#modalAddCommissioncon selección obligatoria y clara de la Asignatura / Materia Asociada (<select name="subject_id" required>), mostrando código oficial, nombre y carrera. - Campos completos de cursada: cuatrimestre (1C/2C/Anual), año lectivo, turno, docente a cargo, cupo máximo y días/horarios.
- Generación y configuración automática de enlace a Google Meet institucional cuando no se ingresa un enlace personalizado.
- Alerta de confirmación visual (
?created=1) al registrar y vincular una comisión exitosamente. - Tabla de comisiones actualizada con visualización explícita del código de materia, nombre y badge de carrera.
- Botón destacado
- Enriquecimiento de la API REST:
- Endpoint
GET /api/v1/reservations/<id>ampliado con objetos relacionales anidados:classroom(código, edificio, piso, capacidad, descripción, virtualidad),commission(código, código compuesto, materia),user(docente, nombre, apellido, correo), duración en minutos y enlaces virtuales. - Endpoint
POST /api/v1/admin/commissionscon validación estricta de existencia de asignatura y resolución inteligente de unicidad.
- Endpoint
[2.0.0] - 2026-09-18
Añadido
- Reingeniería de Arquitectura Fullstack (Desacople Monolito -> Backend + BFF):
- Desacople completo del backend Python/Flask como una API REST pura bajo
/api/v1/retornando exclusivamente JSON. - Implementación del Frontend BFF en Node.js + Express con renderizado de servidor mediante Nunjucks.
- Autenticación sin estado (Stateless) basada en tokens JWT firmados con algoritmo HS256.
- Almacenamiento seguro del token de acceso en cookies del navegador con directivas
HttpOnly,SameSite=LaxySecure. - Inyección transparente del token
Beareren peticiones internas mediante cliente Axios centralizado.
- Desacople completo del backend Python/Flask como una API REST pura bajo
- Dashboards Personalizados por Rol Institucional:
- Dashboard de Bedelía (
/dashboard?role=bedelia): Métricas operativas de campus físico y virtual, cartelera del día y panel de aprobación de solicitudes pendientes. - Dashboard de Docente (
/dashboard?role=docente): Sesiones del día con botones directos para ingresar a reuniones virtuales (Meet/Teams/Zoom) y formulario de solicitud de aulas. - Dashboard de Alumno (
/dashboard?role=alumno): Brújula de cursada "¿Dónde curso hoy?" con ubicación por piso/aula o enlace virtual, junto al calendario de exámenes y entregas. - Dashboard de Administrador (
/dashboard?role=admin): Cockpit institucional de capacidad, usuarios, auditoría RBAC y distribución de comisiones. - Selector dinámico de vista previa de roles en el banner superior para administradores.
- Dashboard de Bedelía (
- Cartelera del Día Interactiva (
/schedule/today_schedule):- Grilla estructurada en bloques horarios (07:00 a 21:00 hs) con métricas en tiempo real de ocupación y reservas confirmadas/pendientes.
- Filtro dinámico para ocultar clases virtuales (
hide_virtual=1) y segmentación por pisos o turnos.
- Seguridad Enterprise (SecurityFilterChain):
- Pipeline centralizado de cabeceras de blindaje OWASP (
nosniff,SAMEORIGIN,X-XSS-Protection,Strict-Transport-Security). - Rate limiting dinámico contra ataques de fuerza bruta en endpoints de autenticación.
- Pipeline centralizado de cabeceras de blindaje OWASP (
Corregido
- Resolución de Colisión de Horarios en Clases Virtuales (Importador de Google Sheets):
- Corrección de la búsqueda de duplicados en
sheets_importer.pyque limitaba indebidamente la unicidad a(classroom_id, start_time, end_time). - Habilitación de concurrencia ilimitada para el aula virtual (
Campus Virtual · VIRTUAL) mediante discriminación porcommission_id. - El total de reservas registradas aumentó de 363 a 643 (incorporando 280 clases virtuales que eran descartadas por falso conflicto).
- Generación y guardado automático de enlaces institucionales de Google Meet (
https://meet.google.com/edu-{materia}-{comision}).
- Corrección de la búsqueda de duplicados en
[1.0.0] - 2026-09-04
Añadido
- Versión Monolítica Base (
legacy_admin-edu-space):- Aplicación monolítica en Flask con plantillas Jinja2 y persistencia SQLAlchemy (SQLite / PostgreSQL).
- Modelado de datos inicial para sedes, aulas físicas, materias, comisiones, usuarios y reservas.
- Sistema de roles inicial (Admin, Bedelía, Docente, Alumno) basado en sesión tradicional de Flask-Login.
- Calendario de reservas mensual y semanal con FullCalendar.
- Prototipo experimental de algoritmo genético para optimización de ocupación áulica.
- Módulo de sincronización inicial con planillas de Google Sheets.