trading-platform/docs/02-definicion-modulos/OQI-001-fundamentos-auth/especificaciones/ET-AUTH-004-api.md
rckrdmrd c1b5081208 feat(ml): Complete FASE 11 - BTCUSD update and comprehensive documentation alignment
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>
2026-01-07 09:31:29 -06:00

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)