# RF-NOTIF-004: Preferencias de Notificacion ## Identificacion | Campo | Valor | |-------|-------| | **ID** | RF-NOTIF-004 | | **Modulo** | MGN-008 Notifications | | **Titulo** | Preferencias de Notificacion | | **Prioridad** | P1 - Alta | | **Estado** | Draft | | **Fecha** | 2025-12-05 | --- ## Descripcion El sistema debe permitir a cada usuario configurar sus preferencias de notificacion, incluyendo canales habilitados, tipos de notificaciones, horarios de silencio, y frecuencia de resumenes. --- ## Requisitos Funcionales ### RF-NOTIF-004.1: Estructura de Preferencias ```typescript interface NotificationPreferences { userId: UUID; // Canales globales channels: { inApp: boolean; email: boolean; push: boolean; sms?: boolean; // Futuro }; // Por tipo de notificacion byType: { [notificationType: string]: { enabled: boolean; channels: ('inApp' | 'email' | 'push')[]; }; }; // Horarios quietHours: { enabled: boolean; timezone: string; start: string; // "22:00" end: string; // "08:00" days: number[]; // [0,1,2,3,4,5,6] (dom-sab) }; // Resumenes digest: { enabled: boolean; frequency: 'none' | 'daily' | 'weekly'; time: string; // "09:00" dayOfWeek?: number; // Para weekly (1=Lunes) }; // Miscelaneo soundEnabled: boolean; desktopEnabled: boolean; language: string; } ``` ### RF-NOTIF-004.2: Canales por Tipo de Notificacion Matriz de configuracion: | Tipo | In-App | Email | Push | Default | |------|--------|-------|------|---------| | task_assigned | Si | Si | Si | In-App, Push | | task_due | Si | Si | Si | In-App, Email, Push | | approval_requested | Si | Si | Si | Todos | | order_created | Si | Si | No | In-App, Email | | payment_received | Si | Si | No | In-App, Email | | system_alert | Si | Si | Si | Todos (no configurable) | | marketing | No | Si | No | Email (opt-in) | ### RF-NOTIF-004.3: Valores por Defecto Cada tenant puede definir defaults: ```typescript interface TenantNotificationDefaults { tenantId: UUID; defaults: NotificationPreferences; overridableByUser: boolean; // Puede el usuario cambiarlos? mandatoryTypes: string[]; // Tipos no deshabilitables } ``` ### RF-NOTIF-004.4: Digest (Resumen) Emails de resumen agrupados: ```typescript interface DigestEmail { frequency: 'daily' | 'weekly'; sections: { title: string; notifications: { type: string; count: number; summary: string; link: string; }[]; }[]; unreadTotal: number; period: { from: Date; to: Date }; } // Ejemplo de digest diario { "sections": [ { "title": "Tareas", "notifications": [ { "type": "task_assigned", "count": 3, "summary": "3 nuevas tareas" }, { "type": "task_due", "count": 2, "summary": "2 tareas vencen hoy" } ] }, { "title": "Pedidos", "notifications": [ { "type": "order_created", "count": 5, "summary": "5 nuevos pedidos" } ] } ], "unreadTotal": 10 } ``` ### RF-NOTIF-004.5: Unsubscribe Link Cada email incluye: ``` Para dejar de recibir estos emails, haz click aqui: https://app.example.com/unsubscribe?token=xxx&type=order_created ``` - Token firmado con expiracion - Permite desuscribir tipo especifico o todos los emails - No requiere login --- ## Operaciones ### Obtener Preferencias ```typescript GET /api/v1/notifications/preferences Response: { "channels": { "inApp": true, "email": true, "push": true }, "byType": { "task_assigned": { "enabled": true, "channels": ["inApp", "push"] }, "marketing": { "enabled": false, "channels": [] } }, "quietHours": { "enabled": true, "start": "22:00", "end": "08:00" }, "digest": { "enabled": true, "frequency": "daily", "time": "09:00" } } ``` ### Actualizar Preferencias ```typescript PATCH /api/v1/notifications/preferences { "channels": { "push": false }, "byType": { "task_assigned": { "channels": ["inApp", "email"] } } } ``` ### Deshabilitar Tipo (Unsubscribe) ```typescript POST /api/v1/notifications/unsubscribe { "token": "signed-token", "type": "order_created" // o "all" para todos los emails } // Sin autenticacion, validado por token ``` ### Obtener Tipos Disponibles ```typescript GET /api/v1/notifications/types Response: { "types": [ { "type": "task_assigned", "name": "Tarea asignada", "description": "Cuando te asignan una nueva tarea", "category": "tasks", "availableChannels": ["inApp", "email", "push"], "defaultChannels": ["inApp", "push"], "canDisable": true }, { "type": "system_alert", "name": "Alertas del sistema", "description": "Alertas criticas del sistema", "category": "system", "availableChannels": ["inApp", "email", "push"], "defaultChannels": ["inApp", "email", "push"], "canDisable": false } ] } ``` --- ## Reglas de Negocio | ID | Regla | Severidad | |----|-------|-----------| | BR-001 | Alertas de sistema no deshabilitables | Security | | BR-002 | Quiet hours no afectan alertas criticas | Security | | BR-003 | Unsubscribe token expira en 7 dias | Security | | BR-004 | Nuevos usuarios usan defaults del tenant | UX | | BR-005 | Digest solo si hay notificaciones | UX | --- ## Criterios de Aceptacion - [ ] Configuracion por canal (in-app, email, push) - [ ] Configuracion por tipo de notificacion - [ ] Quiet hours con timezone - [ ] Digest diario/semanal - [ ] Unsubscribe sin login - [ ] Defaults por tenant - [ ] UI de preferencias intuitiva --- ## Historial | Version | Fecha | Autor | Cambios | |---------|-------|-------|---------| | 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |