Sistema NEXUS v3.4 migrado con: Estructura principal: - core/orchestration: Sistema SIMCO + CAPVED (27 directivas, 28 perfiles) - core/catalog: Catalogo de funcionalidades reutilizables - shared/knowledge-base: Base de conocimiento compartida - devtools/scripts: Herramientas de desarrollo - control-plane/registries: Control de servicios y CI/CD - orchestration/: Configuracion de orquestacion de agentes Proyectos incluidos (11): - gamilit (submodule -> GitHub) - trading-platform (OrbiquanTIA) - erp-suite con 5 verticales: - erp-core, construccion, vidrio-templado - mecanicas-diesel, retail, clinicas - betting-analytics - inmobiliaria-analytics - platform_marketing_content - pos-micro, erp-basico Configuracion: - .gitignore completo para Node.js/Python/Docker - gamilit como submodule (git@github.com:rckrdmrd/gamilit-workspace.git) - Sistema de puertos estandarizado (3005-3199) Generated with NEXUS v3.4 Migration System EPIC-010: Configuracion Git y Repositorios
406 lines
9.2 KiB
Markdown
406 lines
9.2 KiB
Markdown
# 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 <noreply@example.com>"
|
|
```
|
|
|
|
### 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<boolean>;
|
|
|
|
// Email de notificación con template
|
|
async sendNotificationEmail(to, title, message, actionUrl?, actionText?): Promise<boolean>;
|
|
|
|
// Emails específicos
|
|
async sendPasswordResetEmail(email, token, userName?): Promise<void>;
|
|
async sendVerificationEmail(email, token, userName?): Promise<void>;
|
|
async sendWelcomeEmail(email, userName, role): Promise<void>;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 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 <noreply@app.com>"
|
|
|
|
# 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
|