# OQI-001: Fundamentos y Autenticación

## Resumen Ejecutivo

La épica OQI-001 establece los fundamentos técnicos del proyecto OrbiQuant IA, 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 2025 |
| Biometrics | Requiere mobile | Q2 2025 |
| 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` | ✅ |

---

## Referencias

- [_MAP de la Épica](./_MAP.md)
- [Requerimientos](./requerimientos/)
- [Especificaciones](./especificaciones/)
- [Historias de Usuario](./historias-usuario/)
