Files
admin-edu-space/README.md
T

17 KiB

Panel de Administración Edu-Space (UniCABA)

Plataforma integral de gestión áulica, asignación de espacios, control de horarios, seguimiento académico y reservas para la Universidad de la Ciudad de Buenos Aires (UniCABA).

El proyecto se basa en una arquitectura desacoplada (Frontend / Backend) en formato monorepo.

Versión Actual: 3.1.0 (Fases 0 a 5 completadas, Fase 5.1 Bedelía UX & ABMs finalizada)
Institución: Universidad de la Ciudad de Buenos Aires (UniCABA)


🗺️ Estado del Roadmap MVP

Fase 0: Desacople y Arquitectura Base    [████████████████████] 100% (Completado)
Fase 1: Paridad Legacy y Estabilización  [████████████████████] 100% (Completado)
Fase 2: Co-docencia y Matriz Conflictos  [████████████████████] 100% (Completado)
Fase 3: Hitos Evaluativos y Calificaciones[████████████████████] 100% (Completado)
Fase 4: UI/UX Drag & Drop e Impersonación[████████████████████] 100% (Completado)
Fase 5: Integración Auth, Email & Moodle [████████████████████] 100% (Completado)
Fase 5.1: Bedelía UX, ABMs y Purga Datos [████████████████████] 100% (Completado)
Fase 6: Despliegue Producción e Infraest.[███████░░░░░░░░░░░░░]  35% (En Curso)

🏛️ Sede Institucional y Ubicaciones

  • Sede Central UniCABA: Tte. Gral. Juan Domingo Perón 802, Ciudad Autónoma de Buenos Aires (CABA) — Aulas de grado, auditorio principal y laboratorios distribuidos desde Planta Baja (Piso 0) hasta el 4.° Piso.
  • Campus Virtual: Espacio áulico digital integrado (Microsoft Teams / Moodle) configurado con capacidad ilimitada (\infty).

🏗️ Arquitectura del Proyecto (Monorepo)

El repositorio implementa un patrón desacoplado en formato monorepo compuesto por la Core API (Backend), la capa de mediación y vistas BFF (Frontend), herramientas unificadas de despliegue, auditoría automatizada y flujos de CI/CD:

/
├── backend/                  # Capa Core API (Python 3.10+ / Flask / SQLAlchemy)
│   ├── app/                  # Lógica de negocio y arquitectura desacoplada
│   │   ├── models/           # Modelos ORM (User, Role, Classroom, Reservation, etc.)
│   │   ├── routes/api/       # Endpoints REST JSON v1 (/auth, /classrooms, /admin, etc.)
│   │   ├── schemas/          # DTOs y validación de contratos (Pydantic v2)
│   │   ├── services/         # Servicios de dominio (JWT, Email SMTP, Moodle, Queue)
│   │   └── security/         # Pipeline de filtros y validación stateless de JWT
│   ├── tests/                # Suite activa de pruebas unitarias y de integración (pytest)
│   ├── init_db.py            # Inicializador idempotente de esquema, roles RBAC y semillas
│   ├── backup_db.sh          # Generador automatizado de backups para PostgreSQL
│   ├── classrooms_db.sql     # Snapshot integral de base de datos para despliegue
│   ├── wsgi.py               # Entrada WSGI para ejecución con Gunicorn
│   └── requirements.txt      # Dependencias Python auditadas (0 vulnerabilidades / CVEs)
│
├── frontend/                 # Backend-For-Frontend BFF (Node.js 20 LTS / Express)
│   ├── src/                  # Capa servidora de mediación web
│   │   ├── app.js            # Servidor Express, seguridad Helmet, rate-limiting
│   │   ├── controllers/      # Controladores de orquestación y mediación
│   │   ├── middlewares/      # Sesión por Cookie HttpOnly, JWT injection y RBAC
│   │   ├── routes/           # Enrutamiento web (auth, schedule, classrooms, admin)
│   │   └── services/         # Cliente Axios centralizado hacia Flask API
│   ├── views/                # Plantillas y componentes dinámicos en Nunjucks (.html)
│   │   ├── admin/            # Paneles de gestión institucional y configuración
│   │   ├── classrooms/       # Catálogo de aulas y visualización de sedes
│   │   ├── schedule/         # Cronograma de comisiones, reservas y calendario
│   │   ├── my_subjects/      # Libreta de calificaciones, hitos evaluativos y cursada
│   │   └── partials/         # Componentes reutilizables, modales y navegación
│   ├── public/               # Assets estáticos (CSS responsive 720p/1080p, JS cliente)
│   └── package.json          # Dependencias y manifiesto de Node.js
│
├── install.sh                # Instalador nativo unificado para Linux / Proxmox LXC
├── security_audit.bat        # Suite automatizada de auditoría (SAST, SCA, DAST)
├── .gitea/workflows/         # Pipelines de integración continua (CI/CD en Gitea)
├── docs/                     # Especificaciones técnicas, auditorías y changelogs
├── ROADMAP_MVP.md            # Plan de evolución, estadios y fases del proyecto
├── SECURITY_AUDIT_REPORT.md  # Informe formal de auditoría y hardening
└── README.md                 # Documentación general y guía operativa

🐍 Backend Core API (Python + Flask)

  • Funciona exclusivamente como una REST API que expone endpoints bajo /api/v1/ retornando JSON.
  • Encargado de la persistencia de datos (SQLAlchemy / PostgreSQL o SQLite), lógica de negocio, servicio de tokens JWT (Access & Refresh), matriz RBAC, y algoritmos de optimización heurística (Módulo Predictivo).
  • Prohibido retornar HTML o utilizar Jinja2/render_template en este entorno.

🟢 Frontend BFF (Node.js + Express)

  • Aplicación Backend-For-Frontend que renderiza las vistas para el cliente mediante Nunjucks.
  • Gestiona la sesión segura del usuario almacenando el token JWT recibido de Flask en una Cookie HttpOnly.
  • Actúa como proxy de conexión con el Backend de Python empleando Axios (inyectando el Bearer token interceptado).
  • Blindado con Helmet (cabeceras de seguridad HTTP) y express-rate-limit para mitigar ataques de fuerza bruta.
  • Interfaz adaptativa y responsive diseñada para pantallas estándar argentinas (720p, 1366x768 y 1080p) con gráficos dinámicos (Chart.js).

🎯 Dashboards Personalizados por Rol

La plataforma cuenta con paneles adaptados a las necesidades operativas de cada perfil institucional:

  • Administrador (/dashboard?role=admin): Cockpit institucional con métricas globales, auditoría de seguridad RBAC, tendencias mensuales y panel interactivo de Estado y Percentiles de Asignación de Aulas Físicas (asignadas vs disponibles en número y porcentaje).
  • Bedelía (/dashboard?role=bedelia): Control operativo del campus en tiempo real, balance de aulas presenciales asignadas (96.3%) y libres (3.7%), cartelera del día y bandeja de aprobación de reservas pendientes.
  • Docente / Profesor (/dashboard?role=docente): Sesiones del día con accesos directos a videollamadas y gestión de comisiones.
  • Alumno / Estudiante (/dashboard?role=alumno): Brújula de cursada "¿Dónde curso hoy?" con ubicación por piso y aula o enlace virtual, junto al cronograma de exámenes y entregas de TPs.

Modo Vista Previa: Los usuarios con perfil administrador o directivo pueden previsualizar cualquier perspectiva utilizando el selector de roles en la barra superior o pasando el parámetro ?role={admin|bedelia|docente|alumno} en la URL.


🏛️ Circuito Operativo de Bedelía (UX & Flujo Simplificado)

Para garantizar una experiencia de usuario rápida y sin fricción para el personal de Bedelía, el circuito de gestión áulica se divide en 3 etapas directas:

[ 1. Creación / Edición de Aula ] ──► [ 2. Asignación de Comisión al Aula ] ──► [ 3. Cartelera y Grilla ]
  - Sede Central o Campus Virtual      - Desde Comisiones (1 clic)                - Detección de colisiones
  - Piso y Aforo real                  - O desde Ficha de Aula                    - Drag & Drop semanal
  - Tipo (Teórica / Laboratorio)       - Autocompletado de cupo y Meet            - Cartelera del día en vivo

1. Creación y Mantenimiento de Aulas (/classrooms/list_classrooms)

  • Acceso directo a "Nueva Aula": se selecciona la sede (Edificio Central o Campus Virtual), piso (PB, 1, 2, 3, 4) y tipo de espacio (Teórica, Laboratorio de Informática, etc.).
  • Las aulas virtuales se configuran con capacidad infinita (\infty) y no distorsionan la capacidad de bancos físicos del edificio central.
  • En el catálogo de aulas, cada tarjeta muestra el aforo, piso, equipamiento y el botón de acción rápida "Asignar Comisión", que abre el formulario de reserva con el aula ya preseleccionada.

2. Asignación de Comisión al Aula (/schedule/add_reservation)

La asignación puede realizarse desde dos puntos de entrada según la necesidad operativa:

  • Desde el Catálogo de Comisiones (/admin/commissions_list):
    • Cada fila cuenta con el botón de acceso rápido "Asignar Aula / Horario" (bi-calendar-plus).
    • Al hacer clic, redirige a /schedule/add_reservation?commission_id={id} precargando de forma automática:
      • Nombre de la asignatura y código de comisión.
      • Cupo esperado de alumnos (expected_attendees = max_students).
      • Enlace de videollamada preexistente (Google Meet / Teams).
  • Desde el Catálogo de Aulas (/classrooms/list_classrooms):
    • Al pulsar "Asignar Comisión", redirige a /schedule/add_reservation?classroom_id={id}.
    • El selector en cascada (1. Edificio ➔ 2. Piso ➔ 3. Aula) se auto-posiciona en la sede, planta y aula elegidas.
  • Validación en Vivo: El sistema alerta inmediatamente si la cantidad de alumnos de la comisión excede la capacidad física del aula seleccionada.

3. Visualización y Control de Ocupación

  • Cartelera del Día (/schedule/today_schedule): Bloques horarios de 07:00 a 21:00 hs con filtros por piso, turno y switch para ocultar aulas virtuales.
  • Grilla Semanal Interactiva (/schedule/calendar): Arrastre de comisiones sin aula asignada desde el panel lateral con detección de colisiones físicas, solapamientos docentes y aforo en tiempo real (HTTP 409).

🧹 Módulo de Purga y Sincronización Académica

  • Purga Segura y Selectiva (/admin/google_sheets_import):
    • Permite restablecer limpiamente reservas, comisiones, asignaturas, carreras y/o aulas para comenzar nuevos ciclos lectivos o pruebas de carga.
    • Confirmación Interactiva: Cuenta con un modal de confirmación (#purgeConfirmModal) que lista las entidades específicas a eliminar y previene clics accidentales.
    • Integridad Referencial Estricta: Ejecuta la eliminación en orden topológico inverso de claves foráneas (Reservation ➔ MilestoneGrade ➔ CommissionTeacher ➔ StudentEnrollment ➔ Commission ➔ Subject ➔ Career ➔ Classroom), garantizando que la base de datos no rechace el borrado por restricciones relacionales.
    • Preservación Total de Identidades: Los usuarios (User), contraseñas y roles (Role) están estrictamente blindados y nunca son afectados por la purga de datos académicos.
  • Importación desde Google Sheets: Carga y sincronización dinámica de todas las materias y franjas horarias directamente desde la hoja institucional publicada.

⚡ Capacidades Avanzadas de Gestión (Fases 2, 3 y 4 del MVP)

1. Grilla Semanal Interactiva (Drag & Drop) y Validación de Colisiones en Tiempo Real

  • FullCalendar Interactivo: Arrastre y edición de horarios directo en el calendario general de Bedelía (/schedule/calendar).
  • Sidebar de Comisiones por Asignar: Panel lateral colapsable con las comisiones sin aula, con arrastre fluido hacia la grilla semanal o diaria.
  • Detección Automática de Choques (HTTP 409): Validación previa ante cada movimiento (POST /api/v1/reservations/drag-update) verificando colisiones físicas de aula, superposición docente y límite de aforo. Si hay conflicto, el evento se revierte automáticamente (info.revert()) y se notifica al usuario con un Toast explicativo.

2. Modo Impersonación del Superadmin ("Login as")

  • Permite al Administrador navegar la plataforma adoptando exactamente la perspectiva y permisos de cualquier docente o estudiante.
  • Activación con un clic (bi-incognito) desde el catálogo de usuarios (/admin/users_list).
  • Banner superior permanente de advertencia visual en color ámbar con identificación del usuario adoptado y botón de salida inmediata.
  • Trazabilidad y auditoría obligatoria inmutable en audit_logs (IMPERSONATE_START e IMPERSONATE_END).

3. Libro de Calificaciones (Gradebook) & Cierre Formal de Actas

  • Matriz bidimensional interactiva de calificaciones por comisión (/schedule/gradebook/:id) con autoguardado asíncrono debounced (500 ms).
  • Cálculo en vivo de promedios ponderados y condiciones académicas (Promocionado, Regular, Libre).
  • Cierre formal de actas con generación de código inmutable (ACTA-YYYY-Sem-ID), auditoría en audit_logs y congelamiento de modificaciones.
  • Soporte para reapertura excepcional justificada por Bedelía.
  • Portal del Estudiante (/schedule/my_grades / /mis-materias/mis-notas) para consulta de calificaciones y comprobantes.

4. Co-docencia, Matriz de Conflictos y Regla Diaria

  • Soporte de cátedras con múltiples docentes por comisión (CommissionTeacher).
  • Excepción por co-docencia: autoriza superposiciones de horario docente si la cátedra cuenta con un co-docente registrado disponible.
  • Regla restrictiva de cursada diaria: un alumno no puede cursar dos asignaturas regulares el mismo día, con excepciones automáticas para talleres/cursos cortos (is_short_course) o autorizaciones especiales emitidas por Bedelía.

📅 Ficha de Reserva & Gestión de Comisiones

  • Ficha de Reserva Detallada (/schedule/view_reservation?id={id}): Información completa del espacio físico o virtual asignado, capacidad y asistencia prevista, comisión académica vinculada, docente a cargo, botones de acción inmediata (Modificar Reserva, Confirmar Reserva, Cancelar Reserva) y acceso con un clic a la sala de videollamada.
  • Gestión de Comisiones y Vinculación con Asignaturas (/admin/commissions_list):
    • Botón y modal interactivo Nueva Comisión (#modalAddCommission) para registrar comisiones y vincularlas directamente a su Asignatura / Materia, indicando cuatrimestre, año, turno, cupo y docente responsable.
    • Generación automática de enlace institucional de Google Meet cuando no se especifica un enlace propio.
    • Tabla operativa con visualización explícita del código de comisión, nombre de materia, código de asignatura y carrera.

🚀 Instalación y Despliegue Local

Requisitos previos

  • Node.js (v18 o superior)
  • Python 3.10+
  • SQLite / PostgreSQL

1. Iniciar el Backend (Flask)

cd backend
python -m venv venv
# Activar venv (Windows: venv\Scripts\activate, Linux/Mac: source venv/bin/activate)
pip install -r requirements.txt
flask run --port=5000

(El backend quedará escuchando en http://localhost:5000)

2. Iniciar el Frontend (Node/Express)

cd frontend
npm install
npm run dev
# o en su defecto:
node src/app.js

(El frontend quedará escuchando en http://localhost:3000)


📦 Despliegue Automatizado en Producción (Linux / Proxmox LXC)

Para servidores Debian 12 / Ubuntu en Proxmox LXC o VPS, el repositorio incluye el instalador unificado install.sh en la raíz:

# Despliegue interactivo (pregunta si mantener o restaurar la BD si ya existe):
sudo bash install.sh

# Despliegue desatendido manteniendo la base de datos existente:
sudo bash install.sh --keep-db

# Despliegue desatendido preservando la base de datos y los usuarios/credenciales configurados:
sudo bash install.sh --keep-db --keep-users

# Despliegue desatendido recreando la base de datos desde cero (DROP y restore snapshot):
sudo bash install.sh --fresh-db

El script configura automáticamente:

  1. Entorno Python 3.10+ y virtualenv en backend/venv con Gunicorn y servicio admin-edu-space-backend.service (puerto 5000).
  2. Entorno Node.js 20 LTS en frontend/ con servicio admin-edu-space-frontend.service (puerto 3000).
  3. Motor PostgreSQL local con configuración de usuario y opciones seguras para preservar o restaurar la base classrooms_db.
  4. Servicio maestro unificado admin-edu-space.service gestionable vía systemctl {status|restart|stop} admin-edu-space.

🧪 Pruebas Automatizadas

Para ejecutar la suite completa de pruebas unitarias de regresión (Fases 2, 3 y 4):

cd backend
.\venv\Scripts\python.exe -m unittest tests/test_phase2_rules.py tests/test_phase3_gradebook.py tests/test_phase4_interactive_impersonation.py

📚 Documentación Técnica & Changelogs