- FASE-0: Diagnostic audit of 500+ files, 33 findings cataloged (7P0/8P1/12P2/6P3) - FASE-1: Resolved 7 P0 critical conflicts (ports, paths, dedup OQI-010/ADR-002, orphan schemas) - FASE-2: Resolved 8 P1 issues (traces, README/CLAUDE.md, DEPENDENCY-GRAPH v2.0, DDL drift, stack versions, DoR/DoD) - FASE-3: Resolved 12 P2 issues (archived tasks indexed, RNFs created, OQI-010 US/RF/ET, AGENTS v2.0) - FASE-4: Purged 3 obsolete docs to _archive/, fixed MODELO-NEGOCIO.md broken ref - FASE-5: Cross-layer validation (DDL→OQI 66%, OQI→BE 72%, BE→FE 78%, Inventories 95%) - FASE-6: INFORME-FINAL, SA-INDEX (18 subagents), METADATA COMPLETED 27/33 findings resolved (82%), 6 P3 deferred to backlog. 18 new files created, 40+ modified, 4 archived. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
333 lines
15 KiB
Markdown
333 lines
15 KiB
Markdown
---
|
|
id: "README"
|
|
title: "Fundamentos y Autenticación"
|
|
type: "Documentation"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
updated_date: "2026-02-06"
|
|
---
|
|
|
|
# OQI-001: Fundamentos y Autenticación
|
|
|
|
## Resumen Ejecutivo
|
|
|
|
La épica OQI-001 establece los fundamentos técnicos del proyecto Trading Platform, incluyendo un sistema de autenticación robusto y flexible que soporta múltiples métodos de acceso para maximizar la conversión de usuarios.
|
|
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
Implementar un sistema de autenticación multi-proveedor que permita a los usuarios:
|
|
1. Registrarse e iniciar sesión de la forma más conveniente
|
|
2. Mantener sus cuentas seguras con 2FA
|
|
3. Vincular múltiples métodos de autenticación a una sola cuenta
|
|
|
|
---
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
|
|
| Feature | Descripción |
|
|
|---------|-------------|
|
|
| OAuth 2.0 | Google, Facebook, X, Apple, GitHub |
|
|
| Email/Password | Registro tradicional con verificación |
|
|
| Phone Auth | SMS y WhatsApp OTP via Twilio |
|
|
| 2FA | TOTP (Google Authenticator) + backup codes |
|
|
| JWT | Access tokens (15min) + refresh tokens (7d) |
|
|
| Sessions | Gestión de dispositivos y sesiones |
|
|
| RBAC | Roles: investor, trader, student, admin |
|
|
|
|
### Excluido
|
|
|
|
| Feature | Razón | Fase |
|
|
|---------|-------|------|
|
|
| SSO Enterprise | Complejidad | Q3 2026 |
|
|
| Biometrics | Requiere mobile | Q2 2026 |
|
|
| Hardware Keys | Nicho pequeño | Backlog |
|
|
|
|
---
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ FRONTEND │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Login │ │ Register │ │ Callback │ │
|
|
│ │ Page │ │ Page │ │ Page │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
└─────────┼────────────────┼────────────────┼─────────────────────┘
|
|
│ │ │
|
|
└────────────────┼────────────────┘
|
|
│ HTTPS
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ BACKEND API │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ AUTH CONTROLLER │ │
|
|
│ │ POST /auth/register POST /auth/login │ │
|
|
│ │ POST /auth/oauth/:provider POST /auth/phone/send │ │
|
|
│ │ POST /auth/2fa/setup POST /auth/refresh │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
|
│ │ OAuth │ │ Token │ │ Phone │ │ 2FA │ │
|
|
│ │ Service │ │ Service │ │ Service │ │ Service │ │
|
|
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
|
|
└────────┼──────────────┼──────────────┼──────────────┼───────────┘
|
|
│ │ │ │
|
|
▼ ▼ ▼ ▼
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
│ OAuth │ │ PostgreSQL │ │ Twilio │ │ Redis │
|
|
│ Providers │ │ (users) │ │ SMS/WA │ │ (sessions) │
|
|
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Flujos Principales
|
|
|
|
### 1. Registro con Email
|
|
|
|
```
|
|
Usuario Frontend Backend DB
|
|
│ │ │ │
|
|
│─── Completa form ───────▶│ │ │
|
|
│ │─── POST /auth/register ─▶│ │
|
|
│ │ │─── INSERT user ───────▶│
|
|
│ │ │◀── user_id ────────────│
|
|
│ │ │─── Send email ─────────│
|
|
│ │◀── 201 + message ────────│ │
|
|
│◀── "Verifica email" ─────│ │ │
|
|
│ │ │ │
|
|
│─── Click link email ────────────────────────────────▶ │
|
|
│ │ │─── UPDATE verified ───▶│
|
|
│◀── Redirect to login ───────────────────────────────│ │
|
|
```
|
|
|
|
### 2. Login OAuth (Google)
|
|
|
|
```
|
|
Usuario Frontend Backend Google
|
|
│ │ │ │
|
|
│─── Click "Google" ──────▶│ │ │
|
|
│ │─── GET /auth/oauth/google/url ─▶│ │
|
|
│ │◀── auth_url ─────────────│ │
|
|
│◀── Redirect to Google ───│ │ │
|
|
│ │ │ │
|
|
│─── Autoriza en Google ──────────────────────────────────────────────────────▶│
|
|
│◀── Redirect con code ───────────────────────────────────────────────────────│
|
|
│ │ │ │
|
|
│─── /callback?code=xxx ──▶│ │ │
|
|
│ │─── POST /auth/oauth/google ─▶│ │
|
|
│ │ │─── Exchange code ─────▶│
|
|
│ │ │◀── user_info ─────────│
|
|
│ │ │─── Find/Create user ──│
|
|
│ │◀── JWT tokens ───────────│ │
|
|
│◀── Logged in ────────────│ │ │
|
|
```
|
|
|
|
### 3. Login con 2FA
|
|
|
|
```
|
|
Usuario Frontend Backend Redis
|
|
│ │ │ │
|
|
│─── Login email/pass ────▶│ │ │
|
|
│ │─── POST /auth/login ────▶│ │
|
|
│ │◀── 200 + requires_2fa ───│ │
|
|
│◀── Show 2FA input ───────│ │ │
|
|
│ │ │ │
|
|
│─── Ingresa código ──────▶│ │ │
|
|
│ │─── POST /auth/2fa/verify ▶│ │
|
|
│ │ │─── Validate TOTP ─────▶│
|
|
│ │◀── JWT tokens ───────────│ │
|
|
│◀── Logged in ────────────│ │ │
|
|
```
|
|
|
|
---
|
|
|
|
## Modelo de Datos
|
|
|
|
### Tablas Principales
|
|
|
|
```sql
|
|
-- Usuarios
|
|
CREATE TABLE users (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
email VARCHAR(255) UNIQUE,
|
|
password_hash VARCHAR(255),
|
|
phone VARCHAR(20) UNIQUE,
|
|
first_name VARCHAR(100),
|
|
last_name VARCHAR(100),
|
|
role user_role_enum DEFAULT 'investor',
|
|
status user_status_enum DEFAULT 'pending_verification',
|
|
email_verified BOOLEAN DEFAULT FALSE,
|
|
phone_verified BOOLEAN DEFAULT FALSE,
|
|
two_factor_enabled BOOLEAN DEFAULT FALSE,
|
|
two_factor_secret VARCHAR(255),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Cuentas OAuth vinculadas
|
|
CREATE TABLE oauth_accounts (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID REFERENCES users(id),
|
|
provider auth_provider_enum NOT NULL,
|
|
provider_user_id VARCHAR(255) NOT NULL,
|
|
email VARCHAR(255),
|
|
access_token TEXT,
|
|
refresh_token TEXT,
|
|
expires_at TIMESTAMPTZ,
|
|
UNIQUE(provider, provider_user_id)
|
|
);
|
|
|
|
-- Sesiones activas
|
|
CREATE TABLE sessions (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
user_id UUID REFERENCES users(id),
|
|
token_hash VARCHAR(255) NOT NULL,
|
|
device_info JSONB,
|
|
ip_address INET,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
last_activity TIMESTAMPTZ DEFAULT NOW(),
|
|
is_active BOOLEAN DEFAULT TRUE
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
### Autenticación Base
|
|
|
|
| Method | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/register` | Registro con email |
|
|
| POST | `/auth/login` | Login con email/password |
|
|
| POST | `/auth/logout` | Cerrar sesión |
|
|
| POST | `/auth/refresh` | Renovar access token |
|
|
| GET | `/auth/me` | Usuario actual |
|
|
|
|
### OAuth
|
|
|
|
| Method | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| GET | `/auth/oauth/:provider/url` | Obtener URL de autorización |
|
|
| POST | `/auth/oauth/:provider` | Intercambiar código por tokens |
|
|
| DELETE | `/auth/oauth/:provider` | Desvincular proveedor |
|
|
|
|
### Teléfono
|
|
|
|
| Method | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/phone/send` | Enviar OTP (SMS/WhatsApp) |
|
|
| POST | `/auth/phone/verify` | Verificar OTP |
|
|
|
|
### 2FA
|
|
|
|
| Method | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/2fa/setup` | Generar secreto TOTP |
|
|
| POST | `/auth/2fa/enable` | Activar 2FA |
|
|
| POST | `/auth/2fa/verify` | Verificar código 2FA |
|
|
| POST | `/auth/2fa/disable` | Desactivar 2FA |
|
|
| GET | `/auth/2fa/backup-codes` | Obtener backup codes |
|
|
|
|
### Recuperación
|
|
|
|
| Method | Endpoint | Descripción |
|
|
|--------|----------|-------------|
|
|
| POST | `/auth/forgot-password` | Solicitar reset |
|
|
| POST | `/auth/reset-password` | Cambiar contraseña |
|
|
| POST | `/auth/verify-email` | Verificar email |
|
|
| POST | `/auth/resend-verification` | Reenviar verificación |
|
|
|
|
---
|
|
|
|
## Seguridad
|
|
|
|
### Rate Limiting
|
|
|
|
| Endpoint | Límite | Ventana |
|
|
|----------|--------|---------|
|
|
| `/auth/login` | 5 | 15 min |
|
|
| `/auth/register` | 3 | 1 hora |
|
|
| `/auth/phone/send` | 3 | 15 min |
|
|
| `/auth/forgot-password` | 3 | 1 hora |
|
|
| General API | 100 | 1 min |
|
|
|
|
### Tokens JWT
|
|
|
|
```typescript
|
|
// Access Token (15 min)
|
|
{
|
|
"sub": "user_uuid",
|
|
"email": "user@example.com",
|
|
"role": "investor",
|
|
"iat": 1701792000,
|
|
"exp": 1701792900
|
|
}
|
|
|
|
// Refresh Token (7 días)
|
|
{
|
|
"sub": "user_uuid",
|
|
"type": "refresh",
|
|
"jti": "unique_token_id",
|
|
"iat": 1701792000,
|
|
"exp": 1702396800
|
|
}
|
|
```
|
|
|
|
### Password Policy
|
|
|
|
- Mínimo 8 caracteres
|
|
- Al menos 1 mayúscula
|
|
- Al menos 1 número
|
|
- Al menos 1 carácter especial
|
|
- No puede ser igual al email
|
|
|
|
---
|
|
|
|
## Entregables
|
|
|
|
| Entregable | Ruta | Estado |
|
|
|------------|------|--------|
|
|
| Schema DB | `apps/database/schemas/01_public_schema.sql` | ✅ |
|
|
| Schema OAuth | `apps/database/schemas/01b_oauth_providers.sql` | ✅ |
|
|
| Token Service | `apps/backend/src/modules/auth/services/token.service.ts` | ✅ |
|
|
| OAuth Service | `apps/backend/src/modules/auth/services/oauth.service.ts` | ✅ |
|
|
| Phone Service | `apps/backend/src/modules/auth/services/phone.service.ts` | ✅ |
|
|
| 2FA Service | `apps/backend/src/modules/auth/services/twofa.service.ts` | ✅ |
|
|
| Auth Controller | `apps/backend/src/modules/auth/controllers/auth.controller.ts` | ✅ |
|
|
| Auth Routes | `apps/backend/src/modules/auth/auth.routes.ts` | ✅ |
|
|
| Login Page | `apps/frontend/src/modules/auth/pages/Login.tsx` | ✅ |
|
|
| Register Page | `apps/frontend/src/modules/auth/pages/Register.tsx` | ✅ |
|
|
| OAuth Callback | `apps/frontend/src/modules/auth/pages/AuthCallback.tsx` | ✅ |
|
|
|
|
---
|
|
|
|
## Schemas DDL Asignados
|
|
|
|
Este modulo es owner de los siguientes schemas DDL:
|
|
|
|
| Schema | Tablas | Descripcion |
|
|
|--------|--------|-------------|
|
|
| **auth** | 12 | users, user_profiles, oauth_accounts, sessions, email_verifications, phone_verifications, password_reset_tokens, auth_logs, login_attempts, rate_limiting_config, notifications, user_push_tokens |
|
|
| **audit** | 7 | audit_logs, security_events, system_events, trading_audit, api_request_logs, data_access_logs, compliance_logs (cross-cutting concern) |
|
|
| **feature_flags** | 3 | features, user_overrides, audit_trail (infraestructura transversal) |
|
|
|
|
**Total tablas:** 22 (12 auth + 7 audit + 3 feature_flags)
|
|
**Nota:** audit y feature_flags asignados a OQI-001 por TASK-2026-02-06 F1.7 (schemas huerfanos).
|
|
audit es un concern transversal de seguridad/compliance; feature_flags es infraestructura de configuracion.
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [_MAP de la Épica](./_MAP.md)
|
|
- [Requerimientos](./requerimientos/)
|
|
- [Especificaciones](./especificaciones/)
|
|
- [Historias de Usuario](./historias-usuario/)
|