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>
14 KiB
| id | title | type | status | rf_parent | epic | version | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|
| ET-AUTH-004 | API Endpoints for Auth | Specification | Done | RF-AUTH-002 | OQI-001 | 1.0 | 2025-12-05 | 2026-01-04 |
ET-AUTH-004: Especificación Técnica - API Endpoints
Version: 1.0.0 Fecha: 2025-12-05 Estado: ✅ Implementado Épica: OQI-001
Resumen
Esta especificación detalla todos los endpoints de la API de autenticación de Trading Platform.
Base URL
Production: https://api.trading.com/api/v1
Development: http://localhost:3000/api/v1
Endpoints Overview
| Método | Endpoint | Descripción | Auth |
|---|---|---|---|
| POST | /auth/register |
Registro con email | ❌ |
| POST | /auth/login |
Login con email/password | ❌ |
| POST | /auth/logout |
Cerrar sesión | ✅ |
| POST | /auth/refresh |
Renovar tokens | ❌ |
| GET | /auth/me |
Usuario actual | ✅ |
| GET | /auth/oauth/:provider/url |
URL de OAuth | ❌ |
| POST | /auth/oauth/:provider |
Callback OAuth | ❌ |
| DELETE | /auth/oauth/:provider |
Desvincular OAuth | ✅ |
| POST | /auth/phone/send |
Enviar OTP | ❌ |
| POST | /auth/phone/verify |
Verificar OTP | ❌ |
| POST | /auth/2fa/setup |
Configurar 2FA | ✅ |
| POST | /auth/2fa/enable |
Activar 2FA | ✅ |
| POST | /auth/2fa/verify |
Verificar 2FA | ❌ |
| POST | /auth/2fa/disable |
Desactivar 2FA | ✅ |
| POST | /auth/forgot-password |
Solicitar reset | ❌ |
| POST | /auth/reset-password |
Cambiar password | ❌ |
| POST | /auth/verify-email |
Verificar email | ❌ |
| GET | /auth/sessions |
Listar sesiones | ✅ |
| DELETE | /auth/sessions/:id |
Revocar sesión | ✅ |
| DELETE | /auth/sessions |
Revocar todas | ✅ |
Detalle de Endpoints
POST /auth/register
Registro de nuevo usuario con email y contraseña.
Request:
POST /api/v1/auth/register
Content-Type: application/json
{
"email": "usuario@example.com",
"password": "SecurePass123!",
"firstName": "Juan",
"lastName": "Pérez",
"acceptTerms": true
}
Response 201:
{
"success": true,
"message": "Registro exitoso. Revisa tu email para verificar tu cuenta.",
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "usuario@example.com",
"firstName": "Juan",
"lastName": "Pérez",
"role": "investor",
"status": "pending_verification",
"emailVerified": false
}
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 400 | VALIDATION_ERROR | Datos inválidos |
| 409 | EMAIL_EXISTS | Email ya registrado |
| 429 | RATE_LIMIT | Demasiadas solicitudes |
POST /auth/login
Inicio de sesión con email y contraseña.
Request:
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "usuario@example.com",
"password": "SecurePass123!"
}
Response 200 (sin 2FA):
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "usuario@example.com",
"firstName": "Juan",
"lastName": "Pérez",
"role": "investor",
"status": "active"
},
"tokens": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 900,
"tokenType": "Bearer"
}
}
}
Response 200 (con 2FA):
{
"success": true,
"data": {
"requires2FA": true,
"tempToken": "temp_token_for_2fa_verification",
"methods": ["totp", "backup_code"]
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 401 | INVALID_CREDENTIALS | Email o contraseña incorrectos |
| 403 | EMAIL_NOT_VERIFIED | Email no verificado |
| 403 | ACCOUNT_LOCKED | Cuenta bloqueada temporalmente |
| 403 | ACCOUNT_SUSPENDED | Cuenta suspendida |
POST /auth/logout
Cerrar sesión actual.
Request:
POST /api/v1/auth/logout
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"message": "Sesión cerrada exitosamente"
}
POST /auth/refresh
Renovar access token usando refresh token.
Request:
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGciOiJSUzI1NiIs..."
}
Response 200:
{
"success": true,
"data": {
"tokens": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 900,
"tokenType": "Bearer"
}
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 401 | INVALID_TOKEN | Token inválido o expirado |
| 401 | TOKEN_REVOKED | Token revocado |
GET /auth/me
Obtener información del usuario actual.
Request:
GET /api/v1/auth/me
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "usuario@example.com",
"phone": "+525512345678",
"firstName": "Juan",
"lastName": "Pérez",
"role": "investor",
"status": "active",
"emailVerified": true,
"phoneVerified": true,
"twoFactorEnabled": false,
"createdAt": "2025-01-15T10:00:00Z",
"profile": {
"displayName": "JuanPerez",
"avatarUrl": "https://...",
"preferredLanguage": "es",
"timezone": "America/Mexico_City"
},
"oauthProviders": ["google", "github"]
}
}
}
GET /auth/oauth/:provider/url
Obtener URL de autorización OAuth.
Request:
GET /api/v1/auth/oauth/google/url?redirectTo=/dashboard
Response 200:
{
"success": true,
"data": {
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?...",
"state": "random_state_token"
}
}
POST /auth/oauth/:provider
Procesar callback de OAuth.
Request:
POST /api/v1/auth/oauth/google
Content-Type: application/json
{
"code": "authorization_code_from_provider",
"state": "state_token_from_url"
}
Response 200:
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "usuario@gmail.com",
"firstName": "Juan",
"lastName": "Pérez",
"isNewUser": false
},
"tokens": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 900,
"tokenType": "Bearer"
},
"redirectTo": "/dashboard"
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 400 | INVALID_STATE | State token inválido |
| 400 | CODE_EXPIRED | Código de autorización expirado |
| 502 | PROVIDER_ERROR | Error con el proveedor OAuth |
DELETE /auth/oauth/:provider
Desvincular proveedor OAuth.
Request:
DELETE /api/v1/auth/oauth/github
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"message": "GitHub desvinculado exitosamente"
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 400 | LAST_AUTH_METHOD | No puedes eliminar tu único método de auth |
| 404 | PROVIDER_NOT_LINKED | Proveedor no vinculado |
POST /auth/phone/send
Enviar OTP por SMS o WhatsApp.
Request:
POST /api/v1/auth/phone/send
Content-Type: application/json
{
"phone": "+525512345678",
"channel": "whatsapp"
}
Response 200:
{
"success": true,
"message": "Código enviado a tu WhatsApp",
"data": {
"expiresAt": "2025-12-05T10:05:00Z",
"retryAfter": 60
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 400 | INVALID_PHONE | Número de teléfono inválido |
| 429 | RATE_LIMIT | Demasiadas solicitudes |
| 502 | SMS_ERROR | Error al enviar mensaje |
POST /auth/phone/verify
Verificar OTP y autenticar.
Request:
POST /api/v1/auth/phone/verify
Content-Type: application/json
{
"phone": "+525512345678",
"code": "123456"
}
Response 200:
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"phone": "+525512345678",
"firstName": "Usuario",
"lastName": "Nuevo",
"isNewUser": true
},
"tokens": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 900,
"tokenType": "Bearer"
}
}
}
Errors:
| Code | Error | Descripción |
|---|---|---|
| 401 | INVALID_CODE | Código incorrecto |
| 401 | CODE_EXPIRED | Código expirado |
| 429 | TOO_MANY_ATTEMPTS | Demasiados intentos |
POST /auth/2fa/setup
Generar secreto TOTP para configuración.
Request:
POST /api/v1/auth/2fa/setup
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qrCode": "data:image/png;base64,iVBORw0KGgo...",
"otpauthUrl": "otpauth://totp/Trading Platform:usuario@example.com?..."
}
}
POST /auth/2fa/enable
Activar 2FA después de verificar código.
Request:
POST /api/v1/auth/2fa/enable
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"code": "123456"
}
Response 200:
{
"success": true,
"message": "2FA activado exitosamente",
"data": {
"backupCodes": [
"A1B2C3D4",
"E5F6G7H8",
"I9J0K1L2",
"M3N4O5P6",
"Q7R8S9T0",
"U1V2W3X4",
"Y5Z6A7B8",
"C9D0E1F2",
"G3H4I5J6",
"K7L8M9N0"
]
}
}
POST /auth/2fa/verify
Verificar código 2FA durante login.
Request:
POST /api/v1/auth/2fa/verify
Content-Type: application/json
{
"tempToken": "temp_token_from_login",
"code": "123456"
}
Response 200:
{
"success": true,
"data": {
"user": { ... },
"tokens": {
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"expiresIn": 900,
"tokenType": "Bearer"
}
}
}
POST /auth/2fa/disable
Desactivar 2FA.
Request:
POST /api/v1/auth/2fa/disable
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"code": "123456"
}
Response 200:
{
"success": true,
"message": "2FA desactivado exitosamente"
}
POST /auth/forgot-password
Solicitar recuperación de contraseña.
Request:
POST /api/v1/auth/forgot-password
Content-Type: application/json
{
"email": "usuario@example.com"
}
Response 200:
{
"success": true,
"message": "Si el email existe, recibirás instrucciones para recuperar tu contraseña"
}
POST /auth/reset-password
Cambiar contraseña con token de recuperación.
Request:
POST /api/v1/auth/reset-password
Content-Type: application/json
{
"token": "reset_token_from_email",
"password": "NewSecurePass123!"
}
Response 200:
{
"success": true,
"message": "Contraseña actualizada exitosamente"
}
POST /auth/verify-email
Verificar email con token.
Request:
POST /api/v1/auth/verify-email
Content-Type: application/json
{
"token": "verification_token_from_email"
}
Response 200:
{
"success": true,
"message": "Email verificado exitosamente"
}
GET /auth/sessions
Listar sesiones activas.
Request:
GET /api/v1/auth/sessions
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"data": {
"sessions": [
{
"id": "session-uuid-1",
"device": {
"type": "desktop",
"browser": "Chrome",
"browserVersion": "120.0.0",
"os": "Windows",
"osVersion": "11"
},
"location": {
"city": "Ciudad de México",
"country": "México",
"countryCode": "MX"
},
"ipAddress": "189.xxx.xxx.xxx",
"lastActivity": "2025-12-05T10:00:00Z",
"createdAt": "2025-12-01T08:00:00Z",
"isCurrent": true
},
{
"id": "session-uuid-2",
"device": {
"type": "mobile",
"browser": "Safari",
"os": "iOS",
"osVersion": "17.1"
},
"location": {
"city": "Guadalajara",
"country": "México"
},
"ipAddress": "187.xxx.xxx.xxx",
"lastActivity": "2025-12-04T15:30:00Z",
"createdAt": "2025-11-28T10:00:00Z",
"isCurrent": false
}
],
"totalCount": 2
}
}
DELETE /auth/sessions/:id
Revocar sesión específica.
Request:
DELETE /api/v1/auth/sessions/session-uuid-2
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"message": "Sesión cerrada exitosamente"
}
DELETE /auth/sessions
Revocar todas las demás sesiones.
Request:
DELETE /api/v1/auth/sessions
Authorization: Bearer {accessToken}
Response 200:
{
"success": true,
"message": "Todas las demás sesiones han sido cerradas",
"data": {
"revokedCount": 3
}
}
Formato de Errores
Todos los errores siguen el formato estándar:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Descripción legible del error",
"details": {
"field": "Detalle específico del campo si aplica"
}
}
}
Rate Limiting Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1701792060
Referencias
- OpenAPI Spec
- [Postman Collection](../../../96-quick-reference/postman/Trading Platform-Auth.json)