trading-platform/docs/02-definicion-modulos/OQI-004-investment-accounts/historias-usuario/US-INV-012-notificaciones.md

412 lines
18 KiB
Markdown

# US-INV-012: Recibir Notificaciones
## Metadata
| Campo | Valor |
|-------|-------|
| **ID** | US-INV-012 |
| **Épica** | OQI-004 - Cuentas de Inversión |
| **Módulo** | investment |
| **Prioridad** | P2 |
| **Story Points** | 3 |
| **Sprint** | Sprint 7 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |
---
## Historia de Usuario
**Como** inversor,
**quiero** recibir notificaciones sobre eventos importantes de mi cuenta,
**para** estar informado en tiempo real sobre depósitos, retiros, distribuciones y actividad del agente.
## Descripción Detallada
El usuario debe poder configurar y recibir notificaciones por diferentes canales (email, push, in-app) sobre eventos clave: depósito completado, retiro procesado, distribución mensual, grandes ganancias/pérdidas, alertas de rendimiento, y más. Debe poder personalizar qué notificaciones recibir y por qué canal.
## Mockups/Wireframes
```
┌─────────────────────────────────────────────────────────────────┐
│ CONFIGURACIÓN DE NOTIFICACIONES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Elige cómo quieres recibir notificaciones: │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Tipo de Notificación │ Email │ Push │ In-App │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 💰 Depósito completado │ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 💸 Retiro procesado │ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 📊 Distribución mensual │ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🎉 Ganancia grande (>5%) │ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ ⚠️ Pérdida importante (>3%)│ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 📈 Nuevo récord de balance │ [x] │ [ ] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🤖 Agente abrió posición │ [ ] │ [ ] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🤖 Agente cerró posición │ [ ] │ [ ] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 📉 Drawdown alcanzó límite │ [x] │ [x] │ [x] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 📬 Resumen semanal │ [x] │ [ ] │ [ ] │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🔔 Actualizaciones sistema │ [x] │ [ ] │ [x] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Horario de notificaciones push │ │
│ │ [x] Respetar horario (solo 9am - 9pm) │ │
│ │ [ ] Recibir en cualquier horario │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ [Guardar Preferencias] │
│ │
│ ───────────────────────────────────────────────────────────── │
│ │
│ NOTIFICACIONES RECIENTES │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🎉 Ganancia importante Hace 2h │ │
│ │ Tu agente Atlas generó +$125 en un trade (+5.2%) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 💰 Depósito completado Ayer │ │
│ │ Tu depósito de $1,000 fue procesado exitosamente │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 📊 Distribución mensual Hace 5 días │ │
│ │ Ganaste $48 este mes (+4.8%) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ [Ver todas las notificaciones →] │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## Criterios de Aceptación
**Escenario 1: Configurar preferencias de notificaciones**
```gherkin
DADO que el usuario está en configuración de notificaciones
CUANDO marca "Email" para "Depósito completado"
Y desmarca "Push" para "Agente abrió posición"
Y hace click en "Guardar Preferencias"
ENTONCES se guardan las preferencias
Y se muestra confirmación "Preferencias guardadas"
Y las notificaciones futuras respetan la configuración
```
**Escenario 2: Recibir notificación de depósito**
```gherkin
DADO que el usuario tiene notificaciones de depósito activadas (email + push)
CUANDO se completa un depósito de $1,000
ENTONCES se envía email con asunto "Depósito completado - $1,000"
Y se envía notificación push
Y se crea notificación in-app
Y el contador de notificaciones se incrementa
```
**Escenario 3: Notificación de ganancia grande**
```gherkin
DADO que el agente cierra trade con ganancia de $125 (+5.2%)
Y supera el umbral de 5%
CUANDO se procesa el trade
ENTONCES se envía notificación "Ganancia importante"
Y incluye monto y porcentaje
Y link para ver detalle del trade
```
**Escenario 4: Ver notificaciones in-app**
```gherkin
DADO que el usuario tiene 5 notificaciones sin leer
CUANDO hace click en el icono de notificaciones
ENTONCES se abre panel lateral con lista
Y muestra las 5 notificaciones ordenadas por fecha
Y las más recientes están resaltadas
Y al hacer click en una, se marca como leída
```
**Escenario 5: Respetar horario de push**
```gherkin
DADO que el usuario tiene "Respetar horario" activado
Y son las 11pm (fuera de horario)
CUANDO ocurre un evento que genera notificación push
ENTONCES NO se envía push en ese momento
Y se envía al día siguiente a las 9am
Y las notificaciones in-app siguen funcionando normalmente
```
**Escenario 6: Resumen semanal por email**
```gherkin
DADO que es lunes a las 9am
Y el usuario tiene "Resumen semanal" activado
CUANDO se ejecuta el cron job de resúmenes
ENTONCES se envía email con resumen de la semana pasada
Y incluye: balance inicial/final, trades, rendimiento, top ganancias
```
**Escenario 7: Desactivar todas las notificaciones**
```gherkin
DADO que el usuario quiere pausar todas las notificaciones
CUANDO desmarca todos los checkboxes
Y guarda
ENTONCES NO se envían notificaciones de ningún tipo
Y se muestra advertencia "No recibirás notificaciones"
```
## Criterios Adicionales
- [ ] Badge de contador en icono de notificaciones
- [ ] Marcar todas como leídas con un click
- [ ] Eliminar notificaciones antiguas (>30 días)
- [ ] Notificaciones agrupadas ("3 trades cerrados hoy")
- [ ] Deep links desde notificaciones a secciones específicas
---
## Tareas Técnicas
**Database:**
- [ ] DB-INV-001: Tabla notifications.preferences (por usuario)
- [ ] DB-INV-002: Tabla notifications.notifications
- [ ] DB-INV-003: Índices en (user_id, read, created_at)
**Backend:**
- [ ] BE-INV-001: Endpoint GET /notifications/preferences
- [ ] BE-INV-002: Endpoint PUT /notifications/preferences
- [ ] BE-INV-003: Implementar NotificationService.send()
- [ ] BE-INV-004: Email notifications (Nodemailer/SendGrid)
- [ ] BE-INV-005: Push notifications (Firebase Cloud Messaging)
- [ ] BE-INV-006: Endpoint GET /notifications (lista)
- [ ] BE-INV-007: Endpoint PATCH /notifications/:id/read
- [ ] BE-INV-008: Endpoint PATCH /notifications/mark-all-read
- [ ] BE-INV-009: Cron job para resumen semanal
- [ ] BE-INV-010: Event emitter para disparar notificaciones
- [ ] BE-INV-011: Cleanup job para notificaciones antiguas
**Frontend:**
- [ ] FE-INV-001: Crear página NotificationsSettingsPage.tsx
- [ ] FE-INV-002: Crear componente NotificationPreferences.tsx
- [ ] FE-INV-003: Crear componente NotificationBell.tsx (header)
- [ ] FE-INV-004: Crear componente NotificationsList.tsx
- [ ] FE-INV-005: Crear componente NotificationItem.tsx
- [ ] FE-INV-006: Integrar Firebase SDK para push
- [ ] FE-INV-007: Solicitar permisos de notificaciones
- [ ] FE-INV-008: Implementar notificationsStore
- [ ] FE-INV-009: WebSocket para notificaciones en tiempo real
**Tests:**
- [ ] TEST-INV-001: Test guardado de preferencias
- [ ] TEST-INV-002: Test envío de emails
- [ ] TEST-INV-003: Test envío de push
- [ ] TEST-INV-004: Test horario de notificaciones
- [ ] TEST-INV-005: Test resumen semanal
- [ ] TEST-INV-006: Test E2E flujo completo
---
## Dependencias
**Depende de:**
- [ ] Firebase Cloud Messaging configurado
- [ ] Email service configurado (SendGrid/SES)
**Bloquea:**
- Ninguna
---
## Notas Técnicas
**Endpoints involucrados:**
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | /notifications/preferences | Obtener preferencias |
| PUT | /notifications/preferences | Guardar preferencias |
| GET | /notifications | Lista de notificaciones |
| PATCH | /notifications/:id/read | Marcar como leída |
| PATCH | /notifications/mark-all-read | Marcar todas |
**Entidades/Tablas:**
**notifications.preferences:**
```sql
CREATE TABLE notifications.preferences (
user_id UUID PRIMARY KEY REFERENCES auth.users(id),
deposit_completed_email BOOLEAN DEFAULT true,
deposit_completed_push BOOLEAN DEFAULT true,
deposit_completed_inapp BOOLEAN DEFAULT true,
withdrawal_processed_email BOOLEAN DEFAULT true,
withdrawal_processed_push BOOLEAN DEFAULT true,
withdrawal_processed_inapp BOOLEAN DEFAULT true,
monthly_distribution_email BOOLEAN DEFAULT true,
monthly_distribution_push BOOLEAN DEFAULT true,
monthly_distribution_inapp BOOLEAN DEFAULT true,
large_profit_email BOOLEAN DEFAULT true,
large_profit_push BOOLEAN DEFAULT true,
large_profit_inapp BOOLEAN DEFAULT true,
-- ... más tipos
respect_quiet_hours BOOLEAN DEFAULT true,
quiet_hours_start TIME DEFAULT '21:00',
quiet_hours_end TIME DEFAULT '09:00',
weekly_summary_email BOOLEAN DEFAULT true,
updated_at TIMESTAMP DEFAULT NOW()
);
```
**notifications.notifications:**
```sql
CREATE TABLE notifications.notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id),
account_id UUID REFERENCES investment.accounts(id),
type VARCHAR(50) NOT NULL,
title VARCHAR(200) NOT NULL,
message TEXT NOT NULL,
data JSONB,
read BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
```
**Tipos de Notificación:**
```typescript
enum NotificationType {
DEPOSIT_COMPLETED = 'deposit_completed',
WITHDRAWAL_PROCESSED = 'withdrawal_processed',
MONTHLY_DISTRIBUTION = 'monthly_distribution',
LARGE_PROFIT = 'large_profit',
SIGNIFICANT_LOSS = 'significant_loss',
NEW_BALANCE_RECORD = 'new_balance_record',
POSITION_OPENED = 'position_opened',
POSITION_CLOSED = 'position_closed',
DRAWDOWN_LIMIT = 'drawdown_limit',
WEEKLY_SUMMARY = 'weekly_summary',
SYSTEM_UPDATE = 'system_update'
}
```
**Response GET /notifications:**
```typescript
{
notifications: [
{
id: "uuid",
type: "large_profit",
title: "Ganancia importante",
message: "Tu agente Atlas generó +$125 en un trade (+5.2%)",
data: {
accountId: "uuid",
tradeId: "uuid",
amount: 125,
percentage: 5.2
},
read: false,
createdAt: "2025-12-05T08:30:00Z"
}
],
unreadCount: 3,
pagination: {
page: 1,
total: 45
}
}
```
**Lógica de Envío:**
```typescript
class NotificationService {
async send(userId: string, type: NotificationType, data: any) {
const prefs = await this.getPreferences(userId);
// In-app (siempre)
if (prefs[`${type}_inapp`]) {
await this.createInAppNotification(userId, type, data);
}
// Email
if (prefs[`${type}_email`]) {
await this.sendEmail(userId, type, data);
}
// Push
if (prefs[`${type}_push`]) {
if (this.isWithinQuietHours(prefs) && prefs.respect_quiet_hours) {
await this.schedulePushForLater(userId, type, data);
} else {
await this.sendPush(userId, type, data);
}
}
}
}
```
**Email Templates:**
- Usar HTML templates con branding
- Incluir botones de acción (CTA)
- Link de unsubscribe al final
**Push Notifications:**
- Firebase Cloud Messaging (FCM)
- Solicitar permisos en frontend
- Guardar FCM token en DB
- Deeplinks a secciones específicas
**Umbrales para Alertas:**
- Ganancia grande: >5% en un trade
- Pérdida importante: >3% en un trade
- Drawdown límite: Alcanza 80% del max drawdown del producto
---
## Definition of Ready (DoR)
- [x] Historia claramente escrita
- [x] Criterios de aceptación definidos
- [x] Story points estimados
- [x] Dependencias identificadas
- [ ] Firebase configurado
- [ ] Email service configurado
- [ ] Diseño/mockup disponible
- [x] API spec disponible
## Definition of Done (DoD)
- [ ] Código implementado según criterios
- [ ] Tests unitarios escritos y pasando
- [ ] Tests de integración pasando
- [ ] Email templates creados
- [ ] Push notifications funcionando
- [ ] In-app notifications funcionando
- [ ] Preferencias guardándose correctamente
- [ ] Horario de quiet hours respetado
- [ ] Code review aprobado
- [ ] Documentación actualizada
- [ ] QA aprobado
- [ ] Desplegado en ambiente de pruebas
---
## Historial de Cambios
| Fecha | Cambio | Autor |
|-------|--------|-------|
| 2025-12-05 | Creación | Requirements-Analyst |
---
**Creada por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05