Mantiene una conexión con Reverb mientras hay sesión y avisa a las pantallas que algo cambió. Los avisos no traen datos: cada pantalla vuelve a consultar la API, que aplica los permisos (Módulo Realtime).
Conexión
- Cuándo. La abre
useRealtimeConnection, que vive en el shell. El shell solo existe con sesión, así que la conexión se abre al entrar y se cierra al salir. Arranca 1,5 s después de abrir la app, para no competir con lo que la pantalla necesita mostrar. - Cómo se conecta.
- Pide
GET /realtimepara conocer la clave pública y la ruta (/ws). Lo guarda ensessionStorage, así que se pide una vez por pestaña. - Se conecta con Laravel Echo al mismo dominio de la app, por el gateway, con
wsssi la página va porhttps. - Pusher pide una firma por canal, todas en el mismo momento: el autorizador las junta y las pide en una sola petición, con el cliente HTTP de la app, que lleva el token de la sesión.
- Pide
- Canales (
channelsFor): el personal siempre;incidents.allconincidents.view.any;incidents.unassignedconincidents.view.unassigned. Si los permisos cambian, entra a los nuevos y sale de los que ya no aplican. - Sin el aviso propio. El cliente HTTP manda el
X-Socket-IDde la pestaña (shared/http/socketId.ts) y la API no le avisa de sus propios cambios. - Reconexión. Al volver la conexión publica
reconnected, por si se perdió algún aviso. - Si el tiempo real falla, la app sigue igual, sin avisos.
Avisos y qué hace cada pantalla
Las pantallas escuchan el bus con useRealtime(evento, función), que deja de escuchar sola al desmontar. No conocen Echo ni los canales.
| Pantalla | incident | reconnected |
|---|---|---|
| Detalle (conversación) | Con comment: si la conversación ya se cargó, vuelve a pedir lo más reciente y lo une; si no, ajusta el número del botón | Vuelve a pedir la conversación si se había cargado |
| Listado de incidentes | Aviso “Hay N incidentes con cambios de otras personas · Actualizar” (cuenta incidentes, no avisos); no mueve las filas | Vuelve a consultar |
| Detalle y vista previa | Si es el mismo incidente y no hay una acción en curso, se vuelven a leer los datos y el historial | Vuelve a consultar (detalle) |
| Formulario de edición | Si es el mismo incidente: aviso “Otra persona cambió este incidente…” con “Recargar”; no toca lo que se escribió | — |
| Dashboard | Refresca las cifras, como máximo una vez cada 10 s y nunca en modo Personalizar | Igual |
Por el canal personal (useRealtimeNotices):
assigned: pide el incidente a la API y muestra “Te asignaron TZ-26-0142: título” con “Abrir”. Es la opciónactiondenotifyenuseFeedback, que deja el aviso 8 s en lugar de 4.notifications: lo escucha el centro de notificaciones, que vuelve a pedir las sin leer y, si el panel está abierto, la pestaña que se ve.session: vuelve a pedir la sesión (session.refresh()).- Si la sesión ya no vale, la API responde
UNAUTHENTICATEDy el cliente HTTP lleva al login con “Tu sesión terminó”. - Si cambiaron los permisos, el menú y los botones se ajustan y los canales se actualizan.
- Si la sesión ya no vale, la API responde
Capas
| Capa | Pieza | Qué hace |
|---|---|---|
| domain | realtime.ts | Tipos de aviso y a qué canales se suscribe cada persona |
| infrastructure | echoClient.ts | Configuración de conexión y creación de Echo con su autorizador |
| application | useRealtimeConnection, realtimeBus (onRealtime, emitRealtime, useRealtime) | Conexión, canales y bus de avisos |
| presentation | useRealtimeNotices | Aviso de asignación y cambios de sesión |
Dónde está en el código
frontend/src/modules/realtime/shared/http/socketId.tsyshared/http/client.ts- Pantallas:
IncidentListPage,IncidentDetailPage,IncidentFormPageyuseDashboard - Pruebas:
realtime.spec.tsye2e/realtime.spec.ts - Decisión: ADR-0057