- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
US-NOT-001a: Infraestructura WebSocket y Sistema de Entrega en Tiempo Real
Épica: EXT-003 - Sistema de Notificaciones Sprint: Mes 3, Semana 1-2 Story Points: 10 SP Presupuesto: $13,160 MXN Prioridad: Alta (Extensión Fase 3) Estado: 📋 Planificada Relación: Parte de US-NOT-001 (dividida en a/b/c por PF-001)
Descripción
Como desarrollador del sistema Quiero implementar la infraestructura completa de WebSocket con Socket.IO, Redis adapter, autenticación JWT y sistema de entrega de notificaciones Para permitir comunicación en tiempo real confiable, escalable y segura entre el servidor y los clientes
Contexto: Esta user story es parte del sistema completo de notificaciones (EXT-003), dividida para cumplir con PF-001. Esta parte implementa la infraestructura técnica base para comunicación en tiempo real.
Alcance:
- WebSocket server con Socket.IO en puerto dedicado (3001)
- Autenticación JWT para conexiones WebSocket
- Redis adapter para horizontal scaling (multi-instance)
- Sistema de rooms por usuario (
user:${userId}) - Heartbeat y reconnection automática
- Sistema de prioridades de notificaciones (P0-P3)
- Rate limiting y anti-spam
- Persistencia y sincronización de notificaciones offline
- Analytics y monitoring de métricas críticas
- Seguridad y encriptación de comunicación
Valor de Negocio
- WebSocket Latency: <500ms entrega de notificaciones (SLA)
- Delivery Rate: >99% notificaciones entregadas exitosamente
- WebSocket Uptime: >99.9% disponibilidad de servicio
- Scalability: Soporte para 10,000+ conexiones concurrentes
- Infraestructura reutilizable para features futuras (chat, live updates)
Criterios de Aceptación
CA-01: Infraestructura WebSocket con Socket.IO
Dado que se requiere comunicación en tiempo real Cuando un usuario se conecta a la plataforma Entonces debe establecerse conexión WebSocket:
Configuración del Servidor:
- Socket.IO server en puerto 3001 (separado de API REST en 3000)
- Autenticación vía JWT token en handshake
- Rooms por usuario:
user:${userId}para envío directo - Reconnection automática con backoff exponencial (1s → 5s)
- Heartbeat cada 25 segundos para mantener conexión activa
- Redis adapter para horizontal scaling (múltiples servidores)
- Compression habilitada para reducir bandwidth (gzip)
- CORS configurado correctamente para dominio frontend
- Soporte de fallback a long polling si WebSocket no disponible
- Graceful shutdown en deploy (desconectar clientes con warning)
Validación:
- Usuario autenticado se conecta y se une a room
user:123 - Notificación enviada a
user:123llega solo a ese usuario - Redis distribuye mensajes a todas las instancias del servidor
- Reconexión automática funciona tras pérdida de conexión
CA-02: Sistema de Prioridades
Dado que existen múltiples notificaciones con diferentes urgencias Cuando el sistema decide orden de entrega Entonces debe priorizar según:
Niveles de Prioridad:
- Crítico (P0): Sistema en mantenimiento, errores de seguridad
- Alto (P1): Solicitudes de amistad, invitaciones de gremio
- Medio (P2): Logros raros/épicos, desafíos de gremio
- Bajo (P3): Logros comunes, actividades de amigos
Comportamiento:
- P0/P1: Envío inmediato, bypass de rate limiting
- P2: Envío inmediato, toast normal
- P3: Batch cada 5 minutos (agrupar para reducir ruido)
- Agrupación: Si >10 del mismo tipo en 1 minuto → consolidar
Validación:
- Notificación P0 entregada antes que P3 aunque P3 llegó primero
- Notificaciones P3 agrupadas en batches de 5 minutos
CA-03: Rate Limiting y Anti-Spam
Dado que se previene spam de notificaciones Cuando el sistema genera notificaciones Entonces debe aplicar límites:
Límites Globales por Usuario:
- Máximo 50 notificaciones/usuario/hora
- Máximo 200 notificaciones/usuario/día
- Deduplicación: No enviar 2x la misma notificación en 5 minutos
- Agrupación automática: Consolidar notificaciones similares
Límites por Tipo:
friend:request: Max 10 solicitudes/horaguild:*: Max 20 notificaciones/gremio/horasystem:*: Sin límite (alta prioridad)achievement:unlocked: Max 30/hora
Comportamiento al Exceder Límites:
- Notificaciones adicionales puestas en cola
- Log de notificaciones suprimidas
- Alert a admins si usuario excede límites consistentemente
Implementación:
- Redis para rate limiting (counter con TTL)
- Sliding window algorithm
- Cache de deduplicación (hash de contenido)
Validación:
- Usuario que excede 50 notif/hora → siguientes en cola
- Duplicado en 5 minutos → bloqueado
CA-04: Persistencia y Sincronización
Dado que un usuario puede estar offline Cuando se reconecta a la plataforma Entonces debe sincronizar notificaciones:
Sincronización al Reconectar:
- Cargar notificaciones no leídas desde última conexión (max 50)
- Actualizar contador de badge inmediatamente
- Mostrar notificaciones importantes (P0/P1) como toasts
- Marcar notificaciones >7 días como vistas automáticamente
Persistencia:
- Notificaciones guardadas en PostgreSQL (tabla
notifications) - Retención de 30 días (auto-eliminadas vía cron job)
- Índices en
user_id + readpara queries rápidas
Validación:
- Usuario offline recibe 10 notificaciones → al reconectar, las ve todas
- Badge muestra número correcto tras reconexión
CA-05: Analytics y Monitoring
Dado que se monitorea el sistema Cuando se recolectan métricas en tiempo real Entonces debe trackear:
Métricas de Performance:
- Latencia de entrega: P50, P95, P99 (objetivo: P95 <500ms)
- Tasa de entrega exitosa: % (objetivo: >99%)
- Conexiones WebSocket activas
- Tasa de desconexión/reconexión (objetivo: <2%)
- Throughput: Notificaciones procesadas por segundo
- Queue depth: Tamaño de cola pendientes
- Redis latency
Alertas Críticas:
- Latencia >1s por más de 5 minutos
- Tasa de error >1%
- WebSocket server caído
- Redis adapter desconectado
- Queue depth >1000
Herramientas: Sentry (errors), DataDog/Prometheus (métricas)
CA-06: Seguridad y Privacidad
Dado que se manejan notificaciones sensibles Cuando el sistema procesa y entrega notificaciones Entonces debe garantizar seguridad:
Seguridad:
- Autenticación JWT obligatoria en handshake
- Encriptación TLS/SSL en tránsito (wss://)
- Validación de permisos antes de enviar notificación
- Usuario solo puede conectarse a su propia room
- Sanitización de contenido (prevenir XSS)
Privacidad (GDPR/CCPA):
- Usuarios solo reciben sus propias notificaciones
- Respeto de preferencias de privacidad
- Right to delete: Usuario puede borrar todas sus notificaciones
- Logs anonimizados para analytics
Validación:
- Token JWT inválido → conexión rechazada
- Contenido con script XSS → sanitizado
Especificaciones Técnicas
Backend - WebSocket Server
Tecnologías: Socket.IO 4.x, Redis 7.x, ioredis, PostgreSQL 15
Setup Principal (server/websocket/notificationServer.ts):
import { Server } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import Redis from 'ioredis';
const io = new Server(3001, {
cors: { origin: process.env.FRONTEND_URL },
transports: ['websocket', 'polling'],
pingTimeout: 60000,
pingInterval: 25000
});
// Redis adapter for horizontal scaling
const pubClient = new Redis(process.env.REDIS_URL);
const subClient = pubClient.duplicate();
io.adapter(createAdapter(pubClient, subClient));
// Authentication middleware
io.use(async (socket, next) => {
const token = socket.handshake.auth.token;
try {
const user = await verifyJWT(token);
socket.userId = user.id;
socket.join(`user:${user.id}`);
next();
} catch (error) {
next(new Error('Authentication failed'));
}
});
// Connection handler
io.on('connection', async (socket) => {
const unreadNotifications = await NotificationService.getUnread(socket.userId);
socket.emit('notifications:sync', unreadNotifications);
socket.on('disconnect', (reason) => {
console.log(`User ${socket.userId} disconnected: ${reason}`);
});
});
// Emit notification to user
export function emitNotification(userId: string, notification: Notification) {
io.to(`user:${userId}`).emit(notification.type, notification);
}
NotificationService (resumen):
export class NotificationService {
static async send(userId: string, notification: NotificationPayload) {
// Check rate limit
if (!await rateLimiter.check(userId, notification.type)) return null;
// Check duplicates
if (await this.checkDuplicate(userId, notification)) return null;
// Persist to database
const saved = await db.notifications.create({ userId, ...notification });
// Add to priority queue
priorityQueue.add(notification.priority, () => {
emitNotification(userId, saved);
});
return saved;
}
static async getUnread(userId: string, limit = 50) {
return db.notifications.findMany({
where: { userId, read: false },
orderBy: { createdAt: 'desc' },
take: limit
});
}
}
Database Schema
CREATE TABLE notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
type VARCHAR(50) NOT NULL,
priority VARCHAR(10) CHECK (priority IN ('critical', 'high', 'medium', 'low')) DEFAULT 'medium',
title VARCHAR(100) NOT NULL,
message TEXT,
data JSONB,
action_url VARCHAR(255),
read BOOLEAN DEFAULT false,
read_at TIMESTAMP,
expires_at TIMESTAMP DEFAULT (NOW() + INTERVAL '30 days'),
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_notifications_user_unread ON notifications(user_id, read) WHERE read = false;
CREATE INDEX idx_notifications_created ON notifications(created_at DESC);
CREATE INDEX idx_notifications_type ON notifications(type);
API Endpoints
GET /api/notifications // Get user's notifications (paginated)
GET /api/notifications/unread/count // Get unread count
PUT /api/notifications/:id/read // Mark as read
PUT /api/notifications/read-all // Mark all as read
DELETE /api/notifications/:id // Delete notification
Dependencias
Requiere:
- Infraestructura de autenticación JWT (AUTH-001)
- Base de datos PostgreSQL configurada
- Redis configurado para producción
Relacionada:
- US-NOT-001b: Centro de Notificaciones - consume esta infraestructura
- US-NOT-001c: Preferencias - usa rate limiting
Bloquea:
- Cualquier feature que necesite notificaciones en tiempo real
Definición de Hecho (DoD)
Desarrollo
- WebSocket server (Socket.IO) implementado en puerto 3001
- Redis adapter configurado con 2+ instancias
- Autenticación JWT en handshake
- Sistema de prioridades (P0-P3) implementado
- Rate limiting con Redis funcional
- Persistencia en PostgreSQL con índices
- Cron job de limpieza de notificaciones expiradas
- API REST endpoints implementados
Testing
- Tests unitarios: WebSocket server, Rate limiter, Priority queue
- Tests de integración: Redis adapter (multi-instance)
- Load testing: 1000+ conexiones WebSocket concurrentes
- Tests de latency (verificar <500ms P95)
- Tests de seguridad: JWT inválido rechazado, XSS sanitización
Monitoreo
- Sentry configurado para error tracking
- DataDog/Prometheus métricas expuestas
- Alertas configuradas (latencia, errors, uptime)
- Dashboard con métricas en tiempo real
Documentación
- API docs (REST endpoints)
- WebSocket events documentation
- Guía de deployment (Redis, multi-instance)
Estimación
- Backend - WebSocket Server: 24 horas
- Backend - Rate Limiting & Priority: 12 horas
- Backend - Persistencia & Sync: 8 horas
- Backend - Security & Auth: 8 horas
- Testing (Unit + Integration + Load): 16 horas
- Monitoring & Alertas: 8 horas
- Documentación: 4 horas
Total: 80 horas (10 SP @ 8h/SP)
Riesgos y Mitigaciones
| Riesgo | Probabilidad | Impacto | Mitigación |
|---|---|---|---|
| WebSocket no escala con miles de usuarios | Media | Alto | Redis adapter, horizontal scaling, load testing |
| Alta latencia en notificaciones (>500ms) | Baja | Alto | Monitoring estricto, Redis en mismo datacenter |
| Desconexiones frecuentes | Media | Medio | Reconnection automática con backoff exponencial |
| Redis adapter failure | Baja | Alto | Fallback a single-server mode, auto-restart |
Notas
- ✅ Archivo modularizado desde US-NOT-001-FULL.md (2025-11-02)
- ✅ Cumple PF-001 (<400L)
- ✅ Esta es la parte más compleja (10 SP de 19 SP total)
- ✅ Implementar primero esta infraestructura antes que US-NOT-001b/c
- ⚠️ Requiere Redis en producción (costo adicional de infraestructura)
- 🔒 Priorizar seguridad: JWT obligatorio, TLS/SSL, sanitización
Stack Tecnológico
Backend: Socket.IO 4.x, Redis 7.x, ioredis, PostgreSQL 15, pg-cron Monitoring: Sentry, DataDog/Prometheus, PagerDuty Testing: Jest, Socket.IO Client, Artillery (load testing)
Tags: #websocket #socket-io #redis #real-time #infrastructure #backend #ext-003 #fase3