Flujo de Sesión — Crimoo Copilot
Cómo se establece la conexión entre el dashboard y el copilot que aparece en el sitio del cliente.
Componentes involucrados
| Componente | Repo | Rol |
|---|---|---|
| Dashboard | ui-angular | El operador abre la sesión desde aquí |
| Backend | node-api | Gestiona sesiones, sirve /gtm.js, SSE |
| Copilot UI | CrimooCopilot-front | App React que corre dentro del iframe en el sitio del cliente |
Requisito previo
El sitio del cliente debe tener instalado un tag en GTM que cargue el script del backend:
GET https://api.crimoo.com/gtm.js
Sin este tag, el copilot no puede aparecer en el sitio.
Flujo completo
Ciclo de vida de tokens
Estado de sesión (SessionStateService)
El estado se mantiene en memoria en node-api. No sobrevive reinicios del servidor.
Importante: El timeout solo aplica a sesiones en estado
connectedoerror. Las sesionespendingnunca hacen timeout — quedan como zombies si el copilot nunca cargó.
Endpoints de sesión
| Método | Path | Auth | Descripción |
|---|---|---|---|
| POST | /api/sessions | JWT | Crear sesión, retorna initToken |
| POST | /api/sessions/claim | No | Canjear initToken → activationToken |
| POST | /api/sessions/:id/heartbeat | activationToken | Mantener sesión activa |
| POST | /api/sessions/:id/disconnect | activationToken | Desconexión explícita |
| GET | /api/sessions/:id/stream | No | SSE — stream de estado en tiempo real |
| GET | /gtm.js | No | Script loader que inyecta el iframe |
SSE — Stream de estado
El dashboard se suscribe vía EventSource a /api/sessions/:id/stream. El backend emite eventos con nombre status:
event: status
data: {"status":"connected"}
Estados posibles: pending · connected · disconnected · error
El SessionStreamService (Angular) reconecta automáticamente con backoff exponencial (máx. 5 intentos).
Depuración — El copilot no aparece
Si los logs muestran ciclos de subscribe/unsubscribe en SSE pero nunca ✅ Session marked as CONNECTED:
- GTM no disparó — verificar que el tag esté activo en el container del cliente
- initToken expirado — el token dura 120s; si la claim llega tarde, la UI del copilot muestra "sesión expirada"
- COPILOT_URL mal configurada — el iframe apunta a una URL inaccesible; verificar variable de entorno
COPILOT_URLen node-api - Sesión zombie en
pending— el timeout no limpia sesionespending; soloconnectedyerror