Skip to main content

Inbox

El modulo de Inbox gestiona la bandeja de entrada de cada usuario: mensajes internos, notificaciones push (mobile y browser), y preferencias de notificacion. Es el punto central donde convergen alertas de todos los modulos.

Arquitectura

Tipos de mensaje

Prioridades

Estados

unreadreadresolvedarchived Soft delete con campo deleted_at.

API Endpoints

Filtros

Los endpoints de listado aceptan:
  • sourceTool — filtrar por herramienta origen (chat, community, notifications, system, ai)
  • messageTypes — array de tipos de mensaje
  • priority — filtrar por prioridad
  • status — filtrar por estado

Preferencias de usuario

Cada usuario puede configurar:

Push Notifications

El inbox soporta dos canales de push:
  • Expo Push — para vivla-mobile (iOS/Android)
  • Web Push — para el panel web via VAPID/service worker
Las notificaciones respetan las preferencias del usuario y las horas silenciosas (excepto prioridad urgent).

Helpers del servicio

InboxService expone metodos helper para crear mensajes tipados desde otros modulos:
  • createChatBookingCreateMessage() — notificacion de reserva
  • createChatTicketCreatedMessage() — nuevo ticket
  • createChatTicketAssignedMessage() — ticket asignado
  • createChatShiftCreatedMessage() — turno creado
  • createChatPropertyAssignedMessage() — propiedad asignada
  • createGuideIncompleteMessage() — guia incompleta
  • createAIDailySummaryMessage() — resumen IA diario

Tickets via Automation Engine (ticket.*)

Los avisos de ticket no pasan por los helpers createChatTicket*Message() de arriba (ese camino ad-hoc se retiro con VIV-2081) — llegan al buzón vía el motor de notificaciones (apps/backend/src/notifications/engine/), que escribe directamente en inbox_messages cuando el flow tiene una accion con canal tools_inbox. En este camino las filas quedan con message_type: 'automation' y source_tool: 'notifications'; el tipo de evento real vive en metadata.event_type. Eventos emitidos por ticket-events-emitter.service.ts (uno por transicion, nunca dos para el mismo cambio logico): Flows + plantillas: 171_seed_ticket_notification_flows.sql (created, updated, assigned, comment_added) y 178_seed_ticket_resolved_notification_flow.sql (resolved). Todos avisan a creador + asignado por tools_inbox + email, excluyendo al actor del cambio y deduplicando cuando creador == asignado (skipIfTargetEquals).

Metadata enriquecida para la card del buzón

Para que la card del sidebar (TicketMessageCard, en apps/frontend/app/components/inbox/) se pinte sin un fetch adicional a getTicket, el motor añade un bloque metadata.ticket solo para eventos ticket.* (aditivo — no toca el shape de metadata de otros flows):
Todos los campos de metadata.ticket son best-effort (la resolucion de contexto en el emitter puede fallar en un miss puntual) — el frontend degrada campo a campo en vez de todo-o-nada. message.deepLink es siempre null para estos mensajes; el link se construye en el cliente como /app/tickets/list/{ticketId} a partir de metadata.aggregate_id.

Estructura de modulo