Saltar a contenido

Outbox e integraciones

Los efectos hacia el mundo exterior — avisar a una familia, crear un curso en Moodle, generar boletas — no pueden perderse si el servidor se cae, ni ejecutarse si la operación que los originó falló. El sistema lo garantiza con el patrón outbox sobre PostgreSQL (sin Redis ni brokers).

Cómo funciona

  1. El evento se inserta en la tabla Outbox dentro de la misma transacción del cambio de dominio (la falta y su alerta se confirman o revierten juntas).
  2. Un dispatcher reclama lotes pendientes de forma atómica (FOR UPDATE SKIP LOCKED — varios workers sin duplicar trabajo).
  3. Cada handler procesa con reintentos con backoff (5 intentos); si agota, queda FALLIDO y visible para administración.

Evidencia real de la simulación

Estado de la tabla tras el recorrido completo de este manual:

        topic         |   status   | count
----------------------+------------+-------
 email.send           | COMPLETADO |     1     ← comunicado de reunión de padres
 moodle.provision     | COMPLETADO |     5     ← matrículas y cursos aprovisionados
 push.send            | COMPLETADO |     3     ← falta de Ana, pago, comunicado
 report-card.generate | COMPLETADO |     1     ← boletas del parcial cerrado

Cero pendientes, cero fallidos: todo lo que el dominio prometió, se despachó.

El panel para administración

Configuración → Sistema muestra los contadores por estado, el último error de cada evento fallido, y permite reintentar individualmente o todos los fallidos con un clic (por ejemplo, tras una caída del Moodle del colegio):

Panel de outbox

Los adapters

Destino Activación Sin configurar
Email (SMTP) SMTP_URL + SMTP_FROM Modo stub: registra en el log, el pipeline es idéntico
Push (FCM) FCM_CREDENTIALS_PATH (service account de Firebase) Stub; además limpia tokens inválidos en cada envío real
Moodle URL + token en Configuración → Integraciones (en BD, administrable; el token nunca se re-expone) Stub; con conexión: aprovisionamiento idempotente vía mapeo uuid ↔ moodle_id y lectura de gradebook
Boletas PDF Siempre activo Se generan en cola (pg-boss) para no degradar el sistema en picos de cierre

Qué NO va por outbox

El event emitter en memoria se usa solo para efectos internos no críticos, siempre después del commit. La regla del proyecto: si perder el efecto duele, va por outbox; si no, ni siquiera amerita un evento.