Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
11 KiB
11 KiB
| id | title | type | status | priority | module | epic | version | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|---|
| RF-AUTH-003 | Autenticacion por Telefono | Requirement | Done | Alta | auth | OQI-001 | 1.0 | 2025-12-05 | 2026-01-04 |
RF-AUTH-003: Autenticación por Teléfono
Version: 1.0.0 Fecha: 2025-12-05 Estado: ✅ Implementado Prioridad: P1 (Alta) Épica: OQI-001
Descripción
El sistema debe permitir a los usuarios autenticarse mediante número de teléfono usando OTP (One-Time Password) enviado por SMS o WhatsApp, facilitando el acceso a usuarios que prefieren no usar email o redes sociales.
Objetivo de Negocio
- Ampliar opciones de autenticación para mercado LATAM
- Reducir fricción para usuarios móviles
- WhatsApp tiene alta penetración en México y LATAM
- Proporcionar alternativa sin necesidad de recordar contraseña
Requisitos Funcionales
RF-AUTH-003.1: Envío de OTP
DEBE:
- Aceptar número de teléfono con código de país
- Validar formato E.164 (+52XXXXXXXXXX)
- Permitir selección de canal (SMS o WhatsApp)
- Generar OTP de 6 dígitos
- Almacenar OTP con TTL de 5 minutos
- Enviar OTP via Twilio
- Limitar envíos por número (3 cada 15 min)
RF-AUTH-003.2: Verificación de OTP
DEBE:
- Aceptar número de teléfono y OTP
- Validar OTP contra almacenado
- Invalidar OTP después de uso
- Máximo 3 intentos por OTP
- Crear o actualizar usuario
- Generar tokens JWT
RF-AUTH-003.3: Vinculación de Teléfono
DEBE:
- Permitir agregar teléfono a cuenta existente
- Verificar teléfono con OTP
- Marcar teléfono como verificado
- Un teléfono solo puede estar en una cuenta
Canales Soportados
| Canal | Proveedor | Costo* | Velocidad |
|---|---|---|---|
| SMS | Twilio | $0.05 USD | 5-30 seg |
| Twilio | $0.005 USD | 1-5 seg |
*Costos aproximados por mensaje en México
Formato de Número
Validación
// Formato E.164
const phoneRegex = /^\+[1-9]\d{1,14}$/;
// Ejemplos válidos:
// +525512345678 (México)
// +5491123456789 (Argentina)
// +573001234567 (Colombia)
Normalización
function normalizePhone(phone: string): string {
// Remover espacios, guiones, paréntesis
return phone.replace(/[\s\-\(\)]/g, '');
}
Flujo de Autenticación
Usuario Frontend Backend Twilio
│ │ │ │
│─── Ingresa teléfono ────▶│ │ │
│ +525512345678 │ │ │
│ Selecciona: WhatsApp │ │ │
│ │ │ │
│ │─── POST /auth/phone/send─▶ │
│ │ { phone, channel } │ │
│ │ │ │
│ │ │─── Check rate limit ───│
│ │ │ │
│ │ │─── Generate OTP ───────│
│ │ │ (6 digits) │
│ │ │ │
│ │ │─── Store in Redis ─────│
│ │ │ TTL: 5 min │
│ │ │ │
│ │ │─── Send via Twilio ───▶│
│ │ │ │
│ │ │◀── Message sent ───────│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ { message, expires } │ │
│ │ │ │
│◀── "Código enviado" ─────│ │ │
│ │ │ │
│═══ Recibe WhatsApp ══════════════════════════════════════════════════════════│
│ "Tu código: 123456" │ │ │
│ │ │ │
│─── Ingresa 123456 ──────▶│ │ │
│ │ │ │
│ │─── POST /auth/phone/verify │
│ │ { phone, code } │ │
│ │ │ │
│ │ │─── Validate OTP ───────│
│ │ │ │
│ │ │─── Find/Create user ───│
│ │ │ │
│ │ │─── Generate JWT ───────│
│ │ │ │
│ │◀── 200 OK ───────────────│ │
│ │ { tokens, user } │ │
│ │ │ │
│◀── Dashboard ────────────│ │ │
Generación de OTP
function generateOTP(): string {
// 6 dígitos numéricos
return Math.floor(100000 + Math.random() * 900000).toString();
}
Almacenamiento en Redis
// Key pattern
const key = `otp:${phone}`;
// Value structure
{
"code": "123456",
"attempts": 0,
"channel": "whatsapp",
"createdAt": "2025-12-05T10:00:00Z"
}
// TTL: 5 minutos
await redis.setEx(key, 300, JSON.stringify(otpData));
Mensajes de OTP
SMS
OrbiQuant: Tu código de verificación es 123456. Expira en 5 minutos.
🔐 *OrbiQuant IA*
Tu código de verificación es: *123456*
Este código expira en 5 minutos.
No compartas este código con nadie.
Rate Limiting
Por Número de Teléfono
| Período | Límite | Acción |
|---|---|---|
| 15 min | 3 envíos | Bloqueo temporal |
| 1 hora | 5 envíos | Bloqueo 1 hora |
| 24 horas | 10 envíos | Bloqueo 24 horas |
Por IP
| Período | Límite | Acción |
|---|---|---|
| 15 min | 10 envíos | Bloqueo temporal |
| 1 hora | 20 envíos | Bloqueo 1 hora |
Manejo de Errores
| Error | Código | Mensaje Usuario |
|---|---|---|
| Teléfono inválido | 400 | Formato de teléfono inválido |
| Rate limit | 429 | Demasiados intentos, espera X minutos |
| OTP inválido | 401 | Código incorrecto |
| OTP expirado | 401 | Código expirado, solicita uno nuevo |
| Twilio error | 502 | Error al enviar mensaje, intenta de nuevo |
| Canal no soportado | 400 | Canal de envío no soportado |
Integración Twilio
Configuración
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_PHONE_NUMBER=+15555555555
TWILIO_WHATSAPP_NUMBER=+14155238886
Envío SMS
await twilioClient.messages.create({
body: `OrbiQuant: Tu código es ${otp}. Expira en 5 min.`,
from: process.env.TWILIO_PHONE_NUMBER,
to: phone,
});
Envío WhatsApp
await twilioClient.messages.create({
body: `🔐 *OrbiQuant IA*\n\nTu código es: *${otp}*\n\nExpira en 5 minutos.`,
from: `whatsapp:${process.env.TWILIO_WHATSAPP_NUMBER}`,
to: `whatsapp:${phone}`,
});
Reglas de Negocio
RN-001: Teléfono Existente
Si el teléfono ya está registrado:
- Enviar OTP al número
- Al verificar, crear sesión con cuenta existente
- No crear cuenta nueva
RN-002: Teléfono Nuevo
Si el teléfono no está registrado:
- Crear cuenta nueva con teléfono como identificador
- Solicitar email posteriormente (opcional)
- Asignar rol
investorpor defecto
RN-003: Sin Email
Cuentas creadas solo con teléfono:
- Pueden operar normalmente
- Se les solicita email para ciertas funciones (inversión real)
- Pueden agregar email después
Consideraciones de Seguridad
Prevención de Abuso
- Rate limiting agresivo por número e IP
- CAPTCHA después de 2 intentos fallidos
- Bloqueo progresivo de números sospechosos
- Monitoreo de patrones de abuso
Protección de Datos
- No almacenar OTPs en logs
- Encriptar números de teléfono en BD
- Audit log de todos los envíos
- Eliminar OTPs después de verificación
Criterios de Aceptación
- Usuario puede solicitar OTP por SMS
- Usuario puede solicitar OTP por WhatsApp
- OTP se recibe en menos de 30 segundos
- OTP expira después de 5 minutos
- Usuario puede verificar OTP correctamente
- Usuario bloqueado después de 3 intentos fallidos
- Rate limiting funciona correctamente
- Usuario existente puede hacer login con teléfono
- Usuario nuevo puede registrarse con teléfono
- Teléfono se puede vincular a cuenta existente