# US-MGN008-004: Gestionar Preferencias de Notificacion

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | US-MGN008-004 |
| **Modulo** | MGN-008 Notifications |
| **Sprint** | Sprint 5 |
| **Prioridad** | P1 - Alta |
| **Story Points** | 4 |
| **Estado** | Ready |
| **RF Relacionado** | RF-NOTIF-004 |
| **Fecha** | 2025-12-05 |

---

## Historia de Usuario

**Como** usuario del sistema
**Quiero** configurar mis preferencias de notificaciones
**Para** recibir solo las notificaciones que me interesan por los canales que prefiero

---

## Descripcion

Cada usuario configura canales habilitados, tipos de notificaciones, horarios de silencio y frecuencia de resumenes. Los emails incluyen link de unsubscribe sin necesidad de login.

### Contexto

- Configuracion por canal (in-app, email, push)
- Configuracion por tipo de notificacion
- Quiet hours con timezone
- Digest diario/semanal

---

## Criterios de Aceptacion

### Escenario 1: Ver mis preferencias

```gherkin
Given un usuario autenticado
When accede a GET /api/v1/notifications/preferences
Then retorna su configuracion actual:
  | channels | { inApp: true, email: true, push: true } |
  | byType | { task_assigned: { enabled: true, channels: [...] } } |
  | quietHours | { enabled: false } |
  | digest | { enabled: true, frequency: "daily" } |
```

### Escenario 2: Actualizar preferencias

```gherkin
Given un usuario autenticado
When envia PATCH /api/v1/notifications/preferences
  | channels.push | false |
Then las preferencias se actualizan
  And ya no recibe push notifications
```

### Escenario 3: Configurar canales por tipo

```gherkin
Given tipos de notificacion disponibles
When configura:
  | task_assigned | channels: ["inApp", "email"] |
  | order_created | channels: ["inApp"] |
Then las tareas llegan por in-app y email
  And los pedidos solo por in-app
```

### Escenario 4: Configurar quiet hours

```gherkin
Given usuario que no quiere interrupciones de noche
When configura:
  | quietHours.enabled | true |
  | quietHours.start | "22:00" |
  | quietHours.end | "08:00" |
  | quietHours.timezone | "America/Mexico_City" |
Then no recibe push ni sonidos en ese horario
  And las notificaciones in-app si se crean silenciosamente
```

### Escenario 5: Configurar digest

```gherkin
Given usuario que prefiere resumen
When configura:
  | digest.enabled | true |
  | digest.frequency | "daily" |
  | digest.time | "09:00" |
Then recibe email resumen cada dia a las 9am
  And solo si hubo notificaciones nuevas
```

### Escenario 6: Tipos no deshabilitables

```gherkin
Given tipo "system_alert" marcado como mandatory
When usuario intenta deshabilitar ese tipo
Then el sistema responde con error 400
  And indica que el tipo no puede deshabilitarse
```

### Escenario 7: Unsubscribe sin login

```gherkin
Given email con link de unsubscribe
When usuario hace click en el link
  | token | signed-token |
  | type | "order_created" |
Then la pagina muestra formulario de confirmacion
  And al confirmar, se deshabilita ese tipo de email
  And no requiere login
```

### Escenario 8: Ver tipos disponibles

```gherkin
Given un usuario autenticado
When consulta GET /api/v1/notifications/types
Then retorna lista de tipos con:
  | type, name, description, availableChannels, canDisable |
```

### Escenario 9: Nuevos usuarios usan defaults

```gherkin
Given tenant con defaults configurados
When se crea un nuevo usuario
Then sus preferencias se inicializan con los defaults del tenant
```

### Escenario 10: Digest semanal

```gherkin
Given usuario con digest semanal los lunes
When es lunes a la hora configurada
  And hubo notificaciones en la semana
Then recibe email de resumen semanal
  And agrupa por categoria/tipo
```

---

## Mockup / Wireframe

```
+------------------------------------------------------------------+
|  PREFERENCIAS DE NOTIFICACIONES                                   |
+------------------------------------------------------------------+

CANALES
+------------------------------------------------------------------+
| [✓] Notificaciones in-app                                        |
| [✓] Notificaciones por email                                      |
| [✓] Notificaciones push                                           |
+------------------------------------------------------------------+

POR TIPO DE NOTIFICACION
+------------------------------------------------------------------+
| TIPO              | HABILITADO | IN-APP | EMAIL | PUSH            |
+------------------------------------------------------------------+
| Tareas                                                            |
|   Tarea asignada      [✓]       [✓]     [✓]    [✓]               |
|   Tarea vencida       [✓]       [✓]     [✓]    [✓]               |
| Aprobaciones                                                      |
|   Solicitud           [✓]       [✓]     [✓]    [✓]               |
| Pedidos                                                           |
|   Nuevo pedido        [✓]       [✓]     [✓]    [ ]               |
|   Pago recibido       [✓]       [✓]     [✓]    [ ]               |
| Sistema                                                           |
|   Alertas [🔒]        [✓]       [✓]     [✓]    [✓]    (no editable)|
+------------------------------------------------------------------+

HORAS DE SILENCIO
+------------------------------------------------------------------+
| [✓] Activar horas de silencio                                    |
|                                                                   |
| Desde: [22:00 v]   Hasta: [08:00 v]                              |
| Zona horaria: [America/Mexico_City v]                             |
|                                                                   |
| Dias: [✓ L] [✓ M] [✓ M] [✓ J] [✓ V] [✓ S] [✓ D]                 |
|                                                                   |
| Nota: Las alertas criticas ignoran este horario                  |
+------------------------------------------------------------------+

RESUMEN (DIGEST)
+------------------------------------------------------------------+
| [✓] Recibir email de resumen                                     |
|                                                                   |
| Frecuencia: (•) Diario  ( ) Semanal                              |
| Hora de envio: [09:00 v]                                         |
| Dia de semana: [Lunes v]  (solo para semanal)                    |
+------------------------------------------------------------------+

                              [Restaurar defaults]  [=== Guardar ===]

Pagina de Unsubscribe (sin login):
+------------------------------------------------------------------+
|                                                                   |
|   [LOGO]                                                          |
|                                                                   |
|   Confirmar desuscripcion                                        |
|                                                                   |
|   Estas a punto de dejar de recibir emails de:                   |
|   "Nuevos pedidos"                                                |
|                                                                   |
|   Email: usuario@ejemplo.com                                      |
|                                                                   |
|   ( ) Solo este tipo de emails                                   |
|   ( ) Todos los emails (excepto sistema)                         |
|                                                                   |
|                [Cancelar]  [=== Confirmar ===]                   |
|                                                                   |
|   Puedes cambiar tus preferencias en cualquier momento           |
|   desde tu perfil en la aplicacion.                              |
|                                                                   |
+------------------------------------------------------------------+
```

---

## Notas Tecnicas

### API Endpoints

| Metodo | Path | Descripcion |
|--------|------|-------------|
| GET | /notifications/preferences | Obtener preferencias |
| PATCH | /notifications/preferences | Actualizar |
| GET | /notifications/types | Tipos disponibles |
| POST | /notifications/unsubscribe | Desuscribir (sin auth) |

### Estructura de Preferencias

```typescript
interface NotificationPreferences {
  channels: { inApp: boolean; email: boolean; push: boolean };
  byType: Record<string, { enabled: boolean; channels: string[] }>;
  quietHours: { enabled: boolean; start: string; end: string; timezone: string };
  digest: { enabled: boolean; frequency: 'daily' | 'weekly'; time: string };
}
```

### Token de Unsubscribe

```typescript
// Token firmado con JWT o similar
interface UnsubscribeToken {
  userId: UUID;
  type: string | 'all';
  exp: number; // 7 dias
}
```

---

## Definicion de Done

- [ ] CRUD preferencias de usuario
- [ ] Configuracion por canal y tipo
- [ ] Quiet hours con timezone
- [ ] Digest diario/semanal
- [ ] Job de envio de digest
- [ ] Unsubscribe sin login
- [ ] Defaults por tenant
- [ ] UI de preferencias
- [ ] Tests unitarios
- [ ] Documentacion Swagger

---

## Dependencias

### Requiere

| Item | Descripcion |
|------|-------------|
| Tabla notification_preferences | Storage |
| US-MGN008-001 | In-app para filtrar |
| US-MGN008-002 | Email para digest |
| US-MGN008-003 | Push para filtrar |

### Bloquea

| Item | Descripcion |
|------|-------------|
| Todos los envios | Respetan preferencias |

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |
