ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
17 KiB
17 KiB
| id | title | type | status | priority | module | epic | version | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|---|
| RF-AUTH-002 | Autenticacion por Email | Requirement | Done | Alta | auth | OQI-001 | 1.0 | 2025-12-05 | 2026-01-04 |
RF-AUTH-002: Autenticación por Email
Version: 1.0.0 Fecha: 2025-12-05 Estado: ✅ Implementado Prioridad: P0 (Crítica) Épica: OQI-001
Descripción
El sistema debe permitir a los usuarios registrarse e iniciar sesión mediante email y contraseña, con verificación de email obligatoria y recuperación de contraseña segura.
Objetivo de Negocio
- Proporcionar método de auth tradicional para usuarios que prefieren no usar OAuth
- Mantener control total sobre las credenciales
- Cumplir con requisitos regulatorios de identificación
Requisitos Funcionales
RF-AUTH-002.1: Registro
DEBE:
- Aceptar email, contraseña, nombre y apellido
- Validar formato de email (RFC 5322)
- Validar política de contraseña
- Verificar que email no exista en el sistema
- Hashear contraseña con bcrypt (cost 12)
- Enviar email de verificación
- Crear usuario con status
pending_verification
NO DEBE:
- Almacenar contraseña en texto plano
- Permitir emails duplicados
- Revelar si email ya existe (seguridad)
RF-AUTH-002.2: Verificación de Email
DEBE:
- Generar token único de verificación (64 chars)
- Almacenar token con TTL de 24 horas
- Enviar link de verificación por email
- Validar token al hacer click
- Marcar email como verificado
- Invalidar token después de uso
RF-AUTH-002.3: Login
DEBE:
- Aceptar email y contraseña
- Verificar que el usuario existe
- Comparar hash de contraseña
- Verificar que email está verificado
- Verificar que cuenta no está bloqueada
- Generar tokens JWT (access + refresh)
- Registrar sesión en base de datos
RF-AUTH-002.4: Recuperación de Contraseña
DEBE:
- Aceptar email del usuario
- Generar token de reset (64 chars)
- Almacenar token con TTL de 1 hora
- Enviar link de recuperación por email
- Validar token al cambiar contraseña
- Invalidar todas las sesiones activas
- Invalidar token después de uso
Política de Contraseña
| Criterio | Requisito |
|---|---|
| Longitud mínima | 8 caracteres |
| Longitud máxima | 128 caracteres |
| Mayúsculas | Al menos 1 |
| Minúsculas | Al menos 1 |
| Números | Al menos 1 |
| Especiales | Al menos 1 (!@#$%^&*) |
| No igual a email | Obligatorio |
| No en lista negra | Opcional (común passwords) |
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,128}$/;
Flujo de Registro
Usuario Frontend Backend DB
│ │ │ │
│─── Completa form ───────▶│ │ │
│ - email │ │ │
│ - password │ │ │
│ - firstName │ │ │
│ - lastName │ │ │
│ - acceptTerms │ │ │
│ │ │ │
│ │─── POST /auth/register ─▶│ │
│ │ │ │
│ │ │─── Check email ───────▶│
│ │ │◀── Not exists ─────────│
│ │ │ │
│ │ │─── Hash password ──────│
│ │ │ │
│ │ │─── INSERT user ───────▶│
│ │ │◀── user created ───────│
│ │ │ │
│ │ │─── Generate token ─────│
│ │ │─── Store in Redis ─────│
│ │ │─── Send email ─────────│
│ │ │ │
│ │◀── 201 Created ──────────│ │
│ │ { message } │ │
│ │ │ │
│◀── "Verifica email" ─────│ │ │
│ │ │ │
│═══ Recibe email ═════════════════════════════════════ │
│ │ │ │
│─── Click link ──────────▶│ │ │
│ │─── GET /verify-email ───▶│ │
│ │ ?token=xxx │ │
│ │ │ │
│ │ │─── Validate token ─────│
│ │ │─── UPDATE verified ───▶│
│ │ │─── Delete token ───────│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ │ │
│◀── Redirect to login ────│ │ │
Flujo de Login
Usuario Frontend Backend DB
│ │ │ │
│─── Email + Password ────▶│ │ │
│ │ │ │
│ │─── POST /auth/login ────▶│ │
│ │ │ │
│ │ │─── Find user ─────────▶│
│ │ │◀── user data ──────────│
│ │ │ │
│ │ │─── Compare hash ───────│
│ │ │ │
│ │ │─── Check verified ─────│
│ │ │ │
│ │ │─── Check 2FA ──────────│
│ │ │ │
│ │ │ [Si 2FA enabled] │
│ │◀── 200 requires_2fa ─────│ │
│◀── Show 2FA input ───────│ │ │
│ │ │ │
│ │ │ [Si NO 2FA] │
│ │ │─── Generate JWT ───────│
│ │ │─── Create session ────▶│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ { tokens, user } │ │
│ │ │ │
│◀── Dashboard ────────────│ │ │
Flujo de Recuperación
Usuario Frontend Backend DB
│ │ │ │
│─── Email ───────────────▶│ │ │
│ │ │ │
│ │─── POST /forgot-password─▶ │
│ │ │ │
│ │ │─── Find user ─────────▶│
│ │ │◀── user exists ────────│
│ │ │ │
│ │ │─── Generate token ─────│
│ │ │─── Store in Redis ─────│
│ │ │─── Send email ─────────│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ { message } │ │
│ │ │ │
│◀── "Revisa email" ───────│ │ │
│ │ │ │
│═══ Recibe email ═════════════════════════════════════ │
│ │ │ │
│─── Click link ──────────▶│ │ │
│ │─── GET /reset-password ─▶│ │
│ │ ?token=xxx │ │
│ │ │ │
│◀── Form nueva password ──│ │ │
│ │ │ │
│─── Nueva password ──────▶│ │ │
│ │─── POST /reset-password ▶│ │
│ │ { token, password } │ │
│ │ │ │
│ │ │─── Validate token ─────│
│ │ │─── Hash password ──────│
│ │ │─── UPDATE password ───▶│
│ │ │─── Invalidate sessions▶│
│ │ │─── Delete token ───────│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ │ │
│◀── Redirect to login ────│ │ │
Templates de Email
Verificación de Email
Asunto: Verifica tu cuenta de Trading Platform
Hola {{firstName}},
Gracias por registrarte en Trading Platform.
Para completar tu registro, verifica tu email haciendo click aquí:
{{verificationUrl}}
Este link expira en 24 horas.
Si no creaste esta cuenta, ignora este email.
Saludos,
Equipo Trading Platform
Recuperación de Contraseña
Asunto: Recupera tu contraseña de Trading Platform
Hola {{firstName}},
Recibimos una solicitud para restablecer tu contraseña.
Haz click aquí para crear una nueva contraseña:
{{resetUrl}}
Este link expira en 1 hora.
Si no solicitaste este cambio, ignora este email.
Tu contraseña actual seguirá funcionando.
Saludos,
Equipo Trading Platform
Manejo de Errores
| Error | Código | Mensaje Usuario |
|---|---|---|
| Email existe | 409 | Este email ya está registrado |
| Email no encontrado | 401 | Credenciales inválidas |
| Contraseña incorrecta | 401 | Credenciales inválidas |
| Email no verificado | 403 | Por favor verifica tu email |
| Cuenta bloqueada | 403 | Cuenta bloqueada temporalmente |
| Token inválido | 400 | Link inválido o expirado |
| Token expirado | 400 | Link expirado, solicita uno nuevo |
| Password débil | 400 | La contraseña no cumple requisitos |
Nota: No revelar si el email existe en errores de login (seguridad).
Bloqueo por Intentos Fallidos
| Intentos | Acción |
|---|---|
| 3 | Warning en UI |
| 5 | Bloqueo 15 minutos |
| 10 | Bloqueo 1 hora |
| 15 | Bloqueo 24 horas |
| 20+ | Requiere contactar soporte |
Seguridad
Password Hashing
import bcrypt from 'bcryptjs';
const SALT_ROUNDS = 12;
async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
Token Generation
import crypto from 'crypto';
function generateSecureToken(): string {
return crypto.randomBytes(32).toString('hex'); // 64 chars
}
Criterios de Aceptación
- Usuario puede registrarse con email válido
- Contraseña se valida contra política
- Email de verificación se envía correctamente
- Usuario puede verificar email con link
- Usuario puede hacer login después de verificar
- Login falla si email no está verificado
- Usuario puede solicitar recuperación de contraseña
- Link de recuperación funciona una sola vez
- Sesiones se invalidan al cambiar contraseña
- Cuenta se bloquea después de intentos fallidos