# Arquitectura de Actualización en Tiempo Real — SGETECBA

Fecha: 30-05-2026

## 1. Diagnóstico inicial

Estado base validado antes de esta fase:

- `git status`: repositorio con cambios previos mezclados
- `pytest`: operativo
- `npm run build`: operativo

Stack identificado:

- Backend: FastAPI + SQLAlchemy + PostgreSQL
- Frontend: React + TypeScript + Vite
- Autenticación: JWT bearer
- Render web: SPA

Patrón actual:

- backend expone CRUDs REST
- frontend hace fetch explícito y refresca manualmente cada vista
- no existía infraestructura central de eventos ni conexión realtime

## 2. Decisión técnica

Se implementó una primera arquitectura profesional basada en **Server-Sent Events (SSE)**.

Justificación:

- el sistema actual necesita principalmente difusión **servidor -> cliente**
- no requiere colaboración bidireccional tipo chat
- se integra bien con FastAPI sin añadir infraestructura pesada
- permite reconexión simple, bajo overhead y menor complejidad que WebSocket para este caso

## 3. Arquitectura aplicada

### Backend

Se agregó una capa central de eventos:

- [backend/app/realtime/schemas.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/realtime/schemas.py:1)
- [backend/app/realtime/broker.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/realtime/broker.py:1)
- [backend/app/realtime/service.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/realtime/service.py:1)
- [backend/app/api/v1/routes/realtime.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/realtime.py:1)

Capacidades:

- broker central en memoria
- suscripción por usuario, rol y módulos activos
- endpoint SSE autenticado
- filtrado de eventos por `role_code`
- envío solo después de persistencia confirmada
- heartbeat para mantener viva la conexión

### Frontend

Se agregó una capa central de consumo realtime:

- [frontend/src/realtime/RealtimeProvider.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/realtime/RealtimeProvider.tsx:1)
- [frontend/src/realtime/useRealtimeSubscription.ts](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/realtime/useRealtimeSubscription.ts:1)
- [frontend/src/realtime/useRealtimeRefresh.ts](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/realtime/useRealtimeRefresh.ts:1)
- [frontend/src/realtime/types.ts](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/realtime/types.ts:1)

Capacidades:

- conexión SSE centralizada
- reconexión automática
- suscripción por módulos activos
- banner de estado de conexión
- notificaciones discretas de actualización automática
- refresco granular con debounce

## 4. Estructura del evento

Formato implementado:

```json
{
  "event": "estudiante.updated",
  "entity": "estudiante",
  "action": "updated",
  "record_id": "7",
  "payload": {},
  "user_id": "3",
  "timestamp": "2026-05-30T00:00:00+00:00",
  "module": "estudiantes",
  "related_modules": ["dashboard"]
}
```

Campos internos no expuestos al cliente:

- `allowed_role_codes`

## 5. Módulos cubiertos en esta fase

Emisión backend conectada a:

- carreras
- asignaturas
- estudiantes
- matriculaciones
- importación

Consumo frontend conectado a:

- dashboard institucional
- dashboard secretaría
- dashboard docente
- carreras
- asignaturas
- estudiantes
- matriculaciones

## 6. Archivos modificados principales

Backend:

- [backend/app/api/v1/api.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/api.py:1)
- [backend/app/core/deps.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/core/deps.py:1)
- [backend/app/api/v1/routes/carreras.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/carreras.py:1)
- [backend/app/api/v1/routes/asignaturas.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/asignaturas.py:1)
- [backend/app/api/v1/routes/estudiantes.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/estudiantes.py:1)
- [backend/app/api/v1/routes/matriculaciones.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/matriculaciones.py:1)
- [backend/app/api/v1/routes/importacion.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/app/api/v1/routes/importacion.py:1)
- [backend/tests/test_realtime.py](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/backend/tests/test_realtime.py:1)

Frontend:

- [frontend/src/api/client.ts](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/api/client.ts:1)
- [frontend/src/main.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/main.tsx:1)
- [frontend/src/pages/Dashboard.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/Dashboard.tsx:1)
- [frontend/src/pages/secretaria/DashboardSecretaria.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/secretaria/DashboardSecretaria.tsx:1)
- [frontend/src/pages/docente/DashboardDocente.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/docente/DashboardDocente.tsx:1)
- [frontend/src/pages/Carreras.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/Carreras.tsx:1)
- [frontend/src/pages/Asignaturas.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/Asignaturas.tsx:1)
- [frontend/src/pages/Estudiantes.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/Estudiantes.tsx:1)
- [frontend/src/pages/Matriculaciones.tsx](/abs/path/C:/Users/Usuario/Documents/ZIS%20TECBA/PROYECTOS/sgetecba/frontend/src/pages/Matriculaciones.tsx:1)

## 7. Pruebas ejecutadas

Backend:

```bash
cd backend
.\.venv\Scripts\python.exe -m pytest
```

Resultado:

- `15 passed`

Frontend:

```bash
cd frontend
npm run build
```

Resultado:

- `PASS`

Cobertura nueva de esta fase:

- validación de serialización de eventos
- validación de filtrado por módulo y rol en el broker

## 8. Riesgos y límites actuales

1. El broker es en memoria y sirve bien para una sola instancia del backend.
2. Para despliegue horizontal debe migrarse a Redis Pub/Sub, NATS, RabbitMQ o Kafka.
3. La autenticación SSE usa token en query string por compatibilidad con `EventSource`.
4. Para endurecimiento productivo adicional se recomienda emitir un token realtime efímero de corta vida.
5. Esta fase cubre los módulos operativos principales, pero aún no todas las vistas del sistema completo.

## 9. Siguiente fase recomendada

1. Conectar eventos de asistencias, sesiones y módulos docentes avanzados.
2. Agregar tests de integración API + stream SSE.
3. Ejecutar QA multiusuario real con dos sesiones en navegador.
4. Diseñar fallback controlado y estrategia de escalado con pub/sub externo.
5. Implementar manejo de conflictos de edición concurrente en formularios.
