--- id: EPIC-MCH-017 type: Epic title: "MCH-017: Notificaciones" code: MCH-017 status: Completado status_real: "Completado" status_nota: "Módulo notifications creado con templates, preferencias, device tokens" phase: 4 priority: P1 story_points: 34 created_at: 2026-01-07 updated_at: 2026-01-18 simco_version: "4.0.1" dependencies: blocks: [] depends_on: [] --- # MCH-017: Notificaciones ## Metadata - **Codigo:** MCH-017 - **Fase:** 4 - Pedidos y Clientes - **Prioridad:** P1 - **Estado:** Completado - **Story Points:** 34 - **Fecha completado:** 2026-01-18 ## Descripcion Sistema centralizado de notificaciones multi-canal: push notifications, WhatsApp, y SMS. Soporta notificaciones transaccionales, recordatorios, y alertas de negocio. ## Objetivos 1. Push notifications (Firebase) 2. Notificaciones WhatsApp 3. SMS como fallback 4. Configuracion por usuario 5. Historial de notificaciones ## Alcance ### Incluido - Push via Firebase Cloud Messaging - WhatsApp via MCH-011 - SMS via Twilio (fallback) - Preferencias por usuario - Templates de notificacion - Programacion de envios ### Excluido - Email (no prioritario para micro-negocios) - Notificaciones in-app complejas - Marketing automation ## Tipos de Notificacion ### Transaccionales (Inmediatas) | Evento | Canal Default | Mensaje | |--------|---------------|---------| | Nuevo pedido | Push + WhatsApp | "Nuevo pedido #123" | | Pedido listo | WhatsApp | "Tu pedido esta listo" | | Pago recibido | Push | "Pago de $500 recibido" | | Stock bajo | Push | "Coca-Cola: quedan 5" | ### Recordatorios (Programados) | Tipo | Canal | Frecuencia | |------|-------|------------| | Fiado pendiente | WhatsApp | Segun config | | Reporte semanal | WhatsApp | Lunes 8am | | Cierre de caja | Push | Diario 9pm | ### Alertas de Negocio | Alerta | Canal | Trigger | |--------|-------|---------| | Stock bajo | Push | stock < min_stock | | Venta grande | Push | sale.total > threshold | | Nuevo cliente | Push | customer.created | ## Modelo de Datos ### Tablas (schema: notifications) **notification_templates** - id, tenant_id, code, channel - title, body, variables - active **notifications** - id, tenant_id, user_id, type - channel, title, body - status (pending/sent/delivered/failed) - scheduled_at, sent_at, read_at **notification_preferences** - id, user_id, channel - enabled, quiet_hours_start, quiet_hours_end **device_tokens** - id, user_id, platform (ios/android/web) - token, active, created_at ## Endpoints API | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | POST | /notifications/send | Enviar notificacion | | GET | /notifications | Historial | | PUT | /notifications/:id/read | Marcar como leida | | GET | /notifications/preferences | Preferencias | | PUT | /notifications/preferences | Actualizar prefs | | POST | /notifications/register-device | Registrar token | ## Arquitectura ``` ┌─────────────┐ ┌─────────────────┐ │ Trigger │────▶│ Notification │ │ (Event) │ │ Service │ └─────────────┘ └────────┬────────┘ │ ┌───────────────────┼───────────────────┐ │ │ │ ┌──────▼──────┐ ┌───────▼───────┐ ┌──────▼──────┐ │ Firebase │ │ WhatsApp │ │ Twilio │ │ FCM │ │ Service │ │ SMS │ └─────────────┘ └───────────────┘ └─────────────┘ ``` ## Templates de Notificacion ### Push - Nuevo Pedido ```json { "code": "new_order", "channel": "push", "title": "🛒 Nuevo Pedido", "body": "Pedido #{{order_id}} de {{customer_name}} por ${{total}}" } ``` ### WhatsApp - Pedido Listo ``` ¡Tu pedido #{{order_id}} esta listo! 📦 {{items_summary}} Total: ${{total}} Puedes pasar a recogerlo a: {{business_address}} ``` ### WhatsApp - Recordatorio Fiado ``` Hola {{customer_name}}, te recordamos que tienes un saldo pendiente de ${{balance}} en {{business_name}}. ¿Cuando podrias pasar a liquidar? ``` ## Historias de Usuario ### MCH-US-160: Push Notifications con Firebase FCM **Story Points:** 8 **Como** dueno de changarrito **Quiero** recibir notificaciones push en mi dispositivo movil **Para** enterarme inmediatamente de eventos importantes del negocio sin tener que revisar la app constantemente #### Criterios de Aceptacion - [CA-160-1] El sistema soporta push notifications en iOS y Android via Firebase Cloud Messaging - [CA-160-2] Los tokens de dispositivo se registran automaticamente al iniciar sesion - [CA-160-3] Las notificaciones muestran titulo, cuerpo e icono del negocio - [CA-160-4] Al tocar la notificacion, la app abre la pantalla relevante (pedido, venta, etc.) - [CA-160-5] Las notificaciones se envian correctamente cuando la app esta en background o cerrada - [CA-160-6] Los tokens invalidos se desactivan automaticamente #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-160-01 | Configurar proyecto Firebase y obtener credenciales | 2h | | MCH-TT-160-02 | Implementar FirebaseProvider en backend | 4h | | MCH-TT-160-03 | Crear endpoint POST /notifications/register-device | 2h | | MCH-TT-160-04 | Implementar device_tokens repository y service | 3h | | MCH-TT-160-05 | Integrar Firebase SDK en app movil (iOS/Android) | 4h | | MCH-TT-160-06 | Implementar deep linking desde notificaciones | 3h | | MCH-TT-160-07 | Crear tests unitarios y de integracion | 2h | --- ### MCH-US-161: Notificaciones WhatsApp **Story Points:** 5 **Como** dueno de changarrito **Quiero** enviar notificaciones a mis clientes via WhatsApp **Para** comunicarme con ellos en el canal que mas usan y asegurar que reciban mis mensajes #### Criterios de Aceptacion - [CA-161-1] El sistema envia notificaciones WhatsApp usando la integracion de MCH-011 - [CA-161-2] Las notificaciones usan templates aprobados por WhatsApp Business API - [CA-161-3] El sistema registra el estado de entrega (sent/delivered/read/failed) - [CA-161-4] Los errores de envio se manejan con reintentos automaticos (max 3) - [CA-161-5] El sistema respeta el rate limit de la API de WhatsApp #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-161-01 | Integrar con WhatsApp Service de MCH-011 | 3h | | MCH-TT-161-02 | Implementar mapeo de templates a mensajes WhatsApp | 2h | | MCH-TT-161-03 | Crear sistema de reintentos con backoff exponencial | 2h | | MCH-TT-161-04 | Implementar webhook para callbacks de estado | 2h | | MCH-TT-161-05 | Crear tests de integracion con WhatsApp Service | 2h | --- ### MCH-US-162: SMS Fallback con Twilio **Story Points:** 5 **Como** sistema de notificaciones **Quiero** enviar SMS como canal de respaldo cuando falla WhatsApp **Para** garantizar que los mensajes criticos lleguen al destinatario #### Criterios de Aceptacion - [CA-162-1] El sistema detecta cuando WhatsApp falla despues de reintentos - [CA-162-2] Los SMS se envian automaticamente como fallback para mensajes criticos - [CA-162-3] Twilio se integra correctamente con credenciales seguras - [CA-162-4] El costo de SMS se registra para facturacion - [CA-162-5] Los mensajes SMS respetan el limite de 160 caracteres o se dividen correctamente #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-162-01 | Configurar cuenta Twilio y obtener credenciales | 1h | | MCH-TT-162-02 | Implementar TwilioProvider en backend | 3h | | MCH-TT-162-03 | Crear logica de fallback WhatsApp -> SMS | 2h | | MCH-TT-162-04 | Implementar registro de costos por SMS enviado | 2h | | MCH-TT-162-05 | Crear tests unitarios y de integracion | 2h | --- ### MCH-US-163: Preferencias de Notificacion por Usuario **Story Points:** 5 **Como** usuario de la aplicacion **Quiero** configurar mis preferencias de notificacion por canal **Para** recibir solo las notificaciones que me interesan en los horarios que prefiero #### Criterios de Aceptacion - [CA-163-1] El usuario puede habilitar/deshabilitar cada canal (push, WhatsApp, SMS) - [CA-163-2] El usuario puede configurar "horas tranquilas" donde no recibe notificaciones - [CA-163-3] El sistema respeta las preferencias antes de enviar cualquier notificacion - [CA-163-4] Las notificaciones programadas durante horas tranquilas se posponen automaticamente - [CA-163-5] Existe una pantalla de configuracion accesible desde el perfil #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-163-01 | Crear tabla notification_preferences y migracion | 1h | | MCH-TT-163-02 | Implementar NotificationPreferencesService | 2h | | MCH-TT-163-03 | Crear endpoints GET/PUT /notifications/preferences | 2h | | MCH-TT-163-04 | Implementar logica de quiet hours en NotificationService | 2h | | MCH-TT-163-05 | Crear UI de preferencias en frontend | 4h | | MCH-TT-163-06 | Crear tests unitarios | 2h | --- ### MCH-US-164: Templates de Notificacion Personalizables **Story Points:** 5 **Como** administrador del sistema **Quiero** gestionar templates de notificacion por tipo y canal **Para** mantener consistencia en los mensajes y permitir personalizacion por tenant #### Criterios de Aceptacion - [CA-164-1] Existen templates predefinidos para todos los eventos del sistema - [CA-164-2] Los templates soportan variables dinamicas ({{order_id}}, {{customer_name}}, etc.) - [CA-164-3] Cada tenant puede personalizar los templates manteniendo las variables requeridas - [CA-164-4] El sistema valida que las variables requeridas esten presentes al guardar - [CA-164-5] Los templates se cachean para mejor rendimiento #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-164-01 | Crear tabla notification_templates y migracion | 1h | | MCH-TT-164-02 | Implementar NotificationTemplateService con interpolacion | 3h | | MCH-TT-164-03 | Crear seed de templates predefinidos | 2h | | MCH-TT-164-04 | Implementar validacion de variables requeridas | 2h | | MCH-TT-164-05 | Agregar cache Redis para templates | 2h | | MCH-TT-164-06 | Crear tests unitarios | 2h | --- ### MCH-US-165: Historial de Notificaciones **Story Points:** 6 **Como** usuario de la aplicacion **Quiero** ver el historial de notificaciones recibidas **Para** revisar mensajes anteriores y no perder informacion importante #### Criterios de Aceptacion - [CA-165-1] El usuario puede ver lista paginada de sus notificaciones - [CA-165-2] Las notificaciones muestran estado (leida/no leida) - [CA-165-3] El usuario puede marcar notificaciones como leidas individual o masivamente - [CA-165-4] El historial se filtra por tipo, canal y rango de fechas - [CA-165-5] Las notificaciones antiguas (>30 dias) se archivan automaticamente - [CA-165-6] Existe badge con contador de no leidas en la UI #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-165-01 | Crear tabla notifications y migracion | 1h | | MCH-TT-165-02 | Implementar NotificationsRepository con paginacion | 2h | | MCH-TT-165-03 | Crear endpoint GET /notifications con filtros | 2h | | MCH-TT-165-04 | Crear endpoint PUT /notifications/:id/read | 1h | | MCH-TT-165-05 | Implementar job de archivado automatico | 2h | | MCH-TT-165-06 | Crear pantalla de historial en frontend | 4h | | MCH-TT-165-07 | Implementar badge de notificaciones no leidas | 2h | | MCH-TT-165-08 | Crear tests unitarios y de integracion | 2h | --- ### Resumen de Historias de Usuario | ID | Titulo | Story Points | Estado | |----|--------|--------------|--------| | MCH-US-160 | Push Notifications con Firebase FCM | 8 | Pendiente | | MCH-US-161 | Notificaciones WhatsApp | 5 | Pendiente | | MCH-US-162 | SMS Fallback con Twilio | 5 | Pendiente | | MCH-US-163 | Preferencias de Notificacion por Usuario | 5 | Pendiente | | MCH-US-164 | Templates de Notificacion Personalizables | 5 | Pendiente | | MCH-US-165 | Historial de Notificaciones | 6 | Pendiente | | **Total** | | **34** | | ## Entregables | Entregable | Estado | Archivo | |------------|--------|---------| | notifications.module | Pendiente | `modules/notifications/` | | Firebase integration | Pendiente | `providers/firebase.provider.ts` | | Twilio integration | Pendiente | `providers/twilio.provider.ts` | | Notification preferences UI | Pendiente | `components/settings/` | ## Dependencias ### Depende de - MCH-011 (WhatsApp Service) - MCH-002 (Auth - usuarios) ### Bloquea a - MCH-008 (Recordatorios fiado) - MCH-015 (Notificaciones pedido) ## Criterios de Aceptacion - [ ] Push notifications funcionan (iOS/Android) - [ ] WhatsApp notifications funcionan - [ ] SMS fallback funciona - [ ] Preferencias se respetan - [ ] Historial se guarda correctamente ## Configuracion ### Firebase ```typescript { firebase: { projectId: process.env.FIREBASE_PROJECT_ID, privateKey: process.env.FIREBASE_PRIVATE_KEY, clientEmail: process.env.FIREBASE_CLIENT_EMAIL } } ``` ### Quiet Hours ```typescript // Por usuario { quiet_hours: { enabled: true, start: '22:00', end: '08:00' } } ``` --- **Ultima actualizacion:** 2026-01-17