Documento histórico
Este documento se conserva solo para trazabilidad. Consulte el índice maestro para la fuente vigente.
Documento histórico — no usar como fuente de decisiones actuales
Reemplazado por la versión canónica del 2026-07-11. Conservar solo como trazabilidad histórica.
CU-016: Gestionar notificaciones (push, email, SMS, in-app)¶
Caso de uso detallado para la gestión integral de notificaciones al usuario: lista, marcar leídas, configurar preferencias y disparo automático desde eventos del sistema.
Metadatos¶
| Campo | Valor |
|---|---|
| ID | CU-016 |
| Nombre | Gestionar notificaciones |
| Actor primario | Usuario Final |
| Actores secundarios | Sistema (eventos de dominio) |
| Módulo | Notificaciones |
| Prioridad | Alta (MVP) |
| Frecuencia esperada | Muy alta (decenas por usuario activo por día) |
| Trazabilidad SRS | RF-035, RF-036, RF-037, RN-041, RN-104 |
Descripción¶
Las notificaciones son mensajes enviados al usuario para informarle sobre eventos relevantes del sistema. Soportan 4 canales:
- Push (FCM en Android)
- Email (SendGrid)
- SMS (Twilio) — solo para eventos críticos
- In-app (bandeja dentro de la app)
Este CU cubre tanto el disparo automático desde eventos del sistema como la gestión por parte del usuario (ver, marcar leídas, configurar preferencias).
Precondiciones¶
- El usuario está autenticado.
- El usuario tiene un
device_tokenregistrado (FCM). - El usuario tiene email y teléfono verificados.
Postcondiciones¶
Éxito (gestión): - Estado de la notificación actualizado. - Preferencia guardada.
Éxito (disparo automático):
- Notificación entregada por el canal configurado.
- Registro en notification_delivery_log.
Fallo: - Mensaje de error al usuario (en gestión). - Reintento automático (en disparo) con backoff exponencial.
Flujo principal — ver historial (usuario)¶
- El usuario abre la app y toca el ícono de campana o accede a
/notifications. - El sistema carga las últimas 50 notificaciones vía
GET /api/v1/notifications?page=1&page_size=50. - Las muestra agrupadas por fecha (hoy, ayer, esta semana, antes).
- Cada item muestra: ícono del tipo, título, descripción corta, hora, indicador de no leída.
- El usuario toca una notificación.
- El sistema la marca como leída vía
PATCH /api/v1/notifications/{id}/read. - El sistema navega al recurso relacionado (paquete, envío, pago, etc.).
Flujo principal — configurar preferencias (usuario)¶
- El usuario accede a
Configuración > Notificaciones. - El sistema muestra la lista de tipos de notificación (ver tabla abajo).
- Para cada tipo, el usuario puede activar/desactivar cada canal.
- El usuario guarda →
PATCH /api/v1/users/me/notification-preferences. - El sistema valida que al menos un canal quede activo para los tipos críticos.
Tipos de notificación configurables¶
| Tipo | Canales permitidos | Default |
|---|---|---|
package_received |
push, email | push+email |
package_status_changed |
push, email | push+email |
consolidation_ready |
push, email | push+email |
payment_confirmed |
push, email | push+email |
shipment_dispatched |
push, email, sms | push+email |
shipment_in_customs |
push, email | push+email |
shipment_delivered |
push, email, sms | push+email+sms |
kyc_status_changed |
push, email | push+email |
incident_update |
push, email | push+email |
storage_charges |
push, email | push+email |
marketing |
push, email | (desactivado por default) |
Flujo principal — disparo automático (sistema)¶
- Un servicio del backend genera un evento de dominio (ej.
PACKAGE_RECEIVED). - El
Notification Servicese suscribe al evento. - Consulta las preferencias del usuario.
- Crea un
notificationcon estadopending. - Para cada canal activo:
- Push: envía a FCM con payload JSON. Log de respuesta.
- Email: envía vía SendGrid con plantilla renderizada. Log.
- SMS: envía vía Twilio (solo para eventos críticos). Log.
- In-app: marca como visible en la bandeja.
- Actualiza el estado a
deliveredofailed. - Si falla, reintenta hasta 3 veces con backoff (1min, 5min, 30min).
- Si tras 3 reintentos sigue fallando, marca como
permanently_failedy alerta al equipo técnico.
Estructura del payload push¶
{
"notification": {
"title": "Paquete recibido",
"body": "Hemos recibido tu paquete de Amazon. Ya está en almacén.",
"icon": "ic_package"
},
"data": {
"type": "package_received",
"resource_type": "physical_package",
"resource_id": "1234",
"deep_link": "islabox://packages/1234"
}
}
Plantillas de email¶
Las plantillas están en core/templates/emails/<tipo>.html y se renderizan con Jinja2.
Cada plantilla recibe contexto con:
user(nombre, email, casillero)resource(paquete, envío, etc.)action_url(deep link a la app)unsubscribe_url(solo marketing)
Flujos alternativos¶
FA-1: Sin device_token¶
- Si el usuario no tiene token de FCM (no ha abierto la app recientemente):
- Solo enviar email.
- Cuando abra la app, mostrar como in-app badge.
FA-2: Push rechazado por FCM¶
- Si FCM devuelve error de token inválido:
- Marcar el
device_tokencomoinvalid. - Limpiarlo del usuario.
- Reintentar con email.
FA-3: Usuario desinstala la app¶
- FCM marcará el token como inválido.
- El sistema limpia tokens inválidos mensualmente.
- Email sigue siendo el canal de respaldo.
FA-4: Rate limit¶
- Si el usuario recibe > 20 push en 1 hora:
- Agrupar las restantes en un digest ("Tienes 5 actualizaciones más").
- Enviar el digest al final del período.
FA-5: Notificación crítica forzada¶
- Para eventos críticos (pago confirmado, incidencia de seguridad), el sistema ignora las preferencias del usuario y envía por todos los canales disponibles.
- Se marca como
forced = trueennotification_delivery_log.
Reglas de negocio¶
- RN-041: El push debe llegar en < 30 segundos desde el evento.
- RN-042: El email debe llegar en < 2 minutos desde el evento.
- RN-043: El SMS solo se usa para 3 tipos:
shipment_dispatched,shipment_delivered,kyc_status_rejected. - RN-044: El usuario puede desactivar canales individuales pero no desactivar notificaciones críticas por completo.
- RN-045: Toda notificación queda registrada en
notificationsynotification_delivery_logcon inmutabilidad. - RN-RBAC-006: El operador puede enviar push manual al usuario, pero el usuario no puede bloquear los del operador.
Endpoints API¶
GET /api/v1/notifications— lista paginadaGET /api/v1/notifications/{id}— detallePATCH /api/v1/notifications/{id}/read— marca leídaPATCH /api/v1/notifications/read-all— marca todasGET /api/v1/users/me/notification-preferences— preferenciasPATCH /api/v1/users/me/notification-preferences— actualiza preferenciasPOST /api/v1/internal/notifications— interno, dispara desde eventoGET /api/v1/admin/notifications/stats— estadísticas (admin)
Pantallas¶
NotificationsScreen(app)NotificationDetailScreen(app)NotificationSettingsScreen(app)- Backoffice:
NotificationLogsScreen(admin)
Eventos consumidos¶
PACKAGE_RECEIVEDPACKAGE_STATUS_CHANGEDCONSOLIDATION_READYPAYMENT_CONFIRMEDSHIPMENT_DISPATCHEDSHIPMENT_IN_CUSTOMSSHIPMENT_DELIVEREDKYC_STATUS_CHANGEDINCIDENT_UPDATESTORAGE_CHARGES_APPLIED
Monitoreo¶
- Dashboard de tasa de entrega por canal.
- Latencia promedio push vs email.
- Tasa de fallo permanente por canal.
- Usuarios con > 10 push sin abrir (para reducir spam).