# Sistema de Notificaciones **Versión:** 1.0.0 **Origen:** projects/gamilit **Estado:** Producción **Última actualización:** 2025-12-08 --- ## Descripción Sistema completo de notificaciones multi-canal: - Notificaciones in-app (popups, bell icon) - Notificaciones por email (SMTP, SendGrid) - Push notifications (Web Push API nativo) - Templates con interpolación de variables - Preferencias por usuario y tipo - Cola asíncrona para procesamiento --- ## Características | Característica | Descripción | |----------------|-------------| | Multi-canal | in_app, email, push | | Templates | Sistema de templates con variables | | Preferencias | Por usuario y tipo de notificación | | Cola Asíncrona | Procesamiento en background | | Prioridades | low, normal, high, urgent | | Expiración | Notificaciones con fecha de vencimiento | | Logs | Registro de entregas y fallos | --- ## Stack Tecnológico ```yaml backend: framework: NestJS orm: TypeORM email: Nodemailer + SendGrid push: web-push (Web Push API nativo VAPID) database: engine: PostgreSQL schema: notifications ``` --- ## Dependencias NPM ```json { "nodemailer": "^6.x", "@nestjs-modules/mailer": "^1.x", "web-push": "^3.x", "typeorm": "^0.3.x" } ``` --- ## Tablas Requeridas | Tabla | Propósito | |-------|-----------| | notifications.notifications | Notificaciones principales | | notifications.notification_preferences | Preferencias por usuario/tipo | | notifications.notification_templates | Templates con variables | | notifications.notification_queue | Cola de procesamiento | | notifications.notification_logs | Historial de entregas | | notifications.user_devices | Dispositivos para push | --- ## Estructura del Módulo ``` notifications/ ├── notifications.module.ts ├── controllers/ │ ├── notifications.controller.ts # CRUD notificaciones │ ├── notification-preferences.controller.ts │ ├── notification-templates.controller.ts │ └── notification-devices.controller.ts ├── services/ │ ├── notification.service.ts # Servicio principal │ ├── notification-preference.service.ts │ ├── notification-template.service.ts │ ├── notification-queue.service.ts # Cola asíncrona │ ├── push-notification.service.ts # Web Push │ └── user-device.service.ts ├── entities/ │ ├── notification.entity.ts │ ├── notification-preference.entity.ts │ ├── notification-template.entity.ts │ ├── notification-queue.entity.ts │ ├── notification-log.entity.ts │ └── user-device.entity.ts └── dto/ ├── create-notification.dto.ts ├── notification-response.dto.ts └── ... mail/ ├── mail.module.ts ├── mail.service.ts # Envío de emails └── templates/ └── notification.templates.ts # Templates HTML ``` --- ## Canales de Notificación ### 1. In-App ```typescript // Se muestra en bell icon y como popup { channels: ['in_app'], // El frontend consulta notificaciones no leídas // WebSocket puede notificar en tiempo real } ``` ### 2. Email ```typescript // Envío vía SMTP o SendGrid { channels: ['email'], // Se usa template HTML // Retry con backoff exponencial } ``` ### 3. Push ```typescript // Web Push API nativo (VAPID) { channels: ['push'], // No requiere Firebase/OneSignal // Compatible con Chrome, Firefox, Safari 16.4+ } ``` --- ## Uso Rápido ### 1. Crear notificación ad-hoc ```typescript import { NotificationService } from '@/modules/notifications/services'; await notificationService.create({ userId: 'user-uuid', title: 'Nuevo logro desbloqueado!', message: 'Has completado 10 ejercicios', type: 'achievement', channels: ['in_app', 'email'], priority: 'normal', data: { achievement_id: 'ach-001', xp_reward: 100, }, }); ``` ### 2. Usar template ```typescript await notificationService.sendFromTemplate({ templateKey: 'achievement_unlocked', userId: 'user-uuid', variables: { achievement_name: 'Primer Ejercicio', xp_earned: '100', }, channels: ['in_app', 'push'], }); ``` ### 3. Obtener notificaciones del usuario ```typescript const { data, total } = await notificationService.findAllByUser(userId, { status: 'sent', // pending, sent, read, failed type: 'achievement', // filtrar por tipo limit: 20, offset: 0, }); ``` ### 4. Marcar como leída ```typescript await notificationService.markAsRead(notificationId, userId); // o todas await notificationService.markAllAsRead(userId); ``` ### 5. Contador de no leídas ```typescript const unreadCount = await notificationService.getUnreadCount(userId); ``` --- ## Sistema de Preferencias Los usuarios pueden configurar qué canales usar para cada tipo de notificación: ```typescript // Estructura de preferencia { userId: 'user-uuid', notificationType: 'achievement', // tipo de notificación inAppEnabled: true, // mostrar en app emailEnabled: false, // no enviar email pushEnabled: true, // enviar push } ``` ### Tipos de notificación comunes | Tipo | Descripción | Canales por defecto | |------|-------------|---------------------| | achievement | Logros desbloqueados | in_app, push | | rank_up | Subida de rango | in_app, email, push | | assignment_due | Recordatorio de tarea | in_app, email | | friend_request | Solicitud de amistad | in_app, push | | system | Anuncios del sistema | in_app, email | | password_reset | Reset de contraseña | email | --- ## Servicio de Email ### Configuración SMTP ```env SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=user@example.com SMTP_PASS=password SMTP_SECURE=false SMTP_FROM="App Name " ``` ### Configuración SendGrid ```env SENDGRID_API_KEY=SG.xxxxxx ``` ### Métodos disponibles ```typescript class MailService { // Email genérico async sendEmail(to, subject, html, text?): Promise; // Email de notificación con template async sendNotificationEmail(to, title, message, actionUrl?, actionText?): Promise; // Emails específicos async sendPasswordResetEmail(email, token, userName?): Promise; async sendVerificationEmail(email, token, userName?): Promise; async sendWelcomeEmail(email, userName, role): Promise; } ``` --- ## Push Notifications (Web Push) ### Configuración VAPID ```env VAPID_PUBLIC_KEY=BN... VAPID_PRIVATE_KEY=... VAPID_SUBJECT=mailto:admin@example.com ``` Generar claves: ```bash npx web-push generate-vapid-keys ``` ### Flujo de registro ```typescript // 1. Frontend obtiene subscription del navegador const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: VAPID_PUBLIC_KEY, }); // 2. Enviar subscription al backend await fetch('/api/notifications/devices', { method: 'POST', body: JSON.stringify({ subscription, deviceType: 'web', browser: 'Chrome', }), }); ``` --- ## Variables de Entorno ```env # Email - SMTP SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=user SMTP_PASS=pass SMTP_SECURE=false SMTP_FROM="App " # Email - SendGrid (alternativo) SENDGRID_API_KEY=SG.xxx # Push Notifications VAPID_PUBLIC_KEY=BN... VAPID_PRIVATE_KEY=... VAPID_SUBJECT=mailto:admin@app.com # Frontend URL (para links en emails) FRONTEND_URL=https://app.example.com ``` --- ## Endpoints Principales | Método | Ruta | Descripción | |--------|------|-------------| | GET | /notifications | Listar notificaciones del usuario | | GET | /notifications/unread-count | Contador de no leídas | | POST | /notifications/:id/read | Marcar como leída | | POST | /notifications/read-all | Marcar todas como leídas | | DELETE | /notifications/:id | Eliminar notificación | | GET | /notifications/preferences | Obtener preferencias | | PUT | /notifications/preferences | Actualizar preferencias | | POST | /notifications/devices | Registrar dispositivo push | | DELETE | /notifications/devices/:id | Eliminar dispositivo | --- ## Flujo de Envío ``` 1. Crear notificación (service o trigger SQL) │ ▼ 2. Verificar preferencias del usuario │ ├─► in_app habilitado? → Guardar en BD │ ├─► email habilitado? → Encolar en notification_queue │ └─► push habilitado? → Encolar en notification_queue │ ▼ 3. Worker procesa cola (cron job) │ ├─► Enviar email via MailService │ └─► Enviar push via PushNotificationService │ ▼ 4. Registrar resultado en notification_logs ``` --- ## Adaptaciones Necesarias 1. **Tipos de notificación**: Definir tipos específicos del proyecto 2. **Templates**: Crear templates HTML para emails 3. **Canales**: Ajustar canales por defecto según necesidades 4. **VAPID keys**: Generar claves únicas para push 5. **Proveedor email**: Configurar SMTP o SendGrid --- ## Referencias - [Web Push Protocol](https://developers.google.com/web/fundamentals/push-notifications) - [Nodemailer](https://nodemailer.com/) - [SendGrid Docs](https://docs.sendgrid.com/) --- **Mantenido por:** Sistema NEXUS **Proyecto origen:** Gamilit Platform