Skip to main content

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

ComponenteRepoRol
Dashboardui-angularEl operador abre la sesión desde aquí
Backendnode-apiGestiona sesiones, sirve /gtm.js, SSE
Copilot UICrimooCopilot-frontApp 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 connected o error. Las sesiones pending nunca hacen timeout — quedan como zombies si el copilot nunca cargó.

Endpoints de sesión

MétodoPathAuthDescripción
POST/api/sessionsJWTCrear sesión, retorna initToken
POST/api/sessions/claimNoCanjear initToken → activationToken
POST/api/sessions/:id/heartbeatactivationTokenMantener sesión activa
POST/api/sessions/:id/disconnectactivationTokenDesconexión explícita
GET/api/sessions/:id/streamNoSSE — stream de estado en tiempo real
GET/gtm.jsNoScript 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:

  1. GTM no disparó — verificar que el tag esté activo en el container del cliente
  2. initToken expirado — el token dura 120s; si la claim llega tarde, la UI del copilot muestra "sesión expirada"
  3. COPILOT_URL mal configurada — el iframe apunta a una URL inaccesible; verificar variable de entorno COPILOT_URL en node-api
  4. Sesión zombie en pending — el timeout no limpia sesiones pending; solo connected y error