---
id: "US-INV-013"
title: "Completar KYC Básico"
type: "User Story"
status: "Done"
priority: "Media"
epic: "OQI-004"
project: "trading-platform"
story_points: 3
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# US-INV-013: Completar KYC Básico

## Metadata

| Campo | Valor |
|-------|-------|
| **ID** | US-INV-013 |
| **Épica** | OQI-004 - Cuentas de Inversión |
| **Módulo** | investment |
| **Prioridad** | P1 |
| **Story Points** | 2 |
| **Sprint** | Sprint 5 |
| **Estado** | Pendiente |
| **Asignado a** | Por asignar |

---

## Historia de Usuario

**Como** inversor nuevo,
**quiero** completar un proceso de KYC básico,
**para** cumplir con regulaciones y poder invertir cantidades mayores.

## Descripción Detallada

El usuario debe completar un proceso de Know Your Customer (KYC) básico antes de poder abrir cuenta de inversión o después de alcanzar cierto límite de depósito. El proceso incluye: verificar identidad (nombre, fecha nacimiento, país), confirmar dirección, y declarar fuente de fondos. El sistema debe validar la información y aprobar/rechazar el KYC.

## Mockups/Wireframes

```
┌─────────────────────────────────────────────────────────────────┐
│                    VERIFICACIÓN DE IDENTIDAD                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Para cumplir con regulaciones, necesitamos verificar           │
│  tu identidad.                                                   │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Paso 1: Información Personal                           │   │
│  │                                                           │   │
│  │  Nombre completo *                                        │   │
│  │  ┌──────────────────────────────────────────────┐        │   │
│  │  │  Juan                                         │        │   │
│  │  └──────────────────────────────────────────────┘        │   │
│  │                                                           │   │
│  │  Apellidos *                                              │   │
│  │  ┌──────────────────────────────────────────────┐        │   │
│  │  │  Pérez González                               │        │   │
│  │  └──────────────────────────────────────────────┘        │   │
│  │                                                           │   │
│  │  Fecha de nacimiento *                                    │   │
│  │  ┌──────┐  ┌──────┐  ┌──────────┐                        │   │
│  │  │  15  │  │  06  │  │  1990    │                        │   │
│  │  └──────┘  └──────┘  └──────────┘                        │   │
│  │  DD        MM        AAAA                                 │   │
│  │                                                           │   │
│  │  País de residencia *                                     │   │
│  │  ┌──────────────────────────────────────────────┐        │   │
│  │  │  México                               ▼      │        │   │
│  │  └──────────────────────────────────────────────┘        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Paso 2: Dirección                                       │   │
│  │                                                           │   │
│  │  Dirección completa *                                     │   │
│  │  ┌──────────────────────────────────────────────┐        │   │
│  │  │  Av. Reforma 123, Col. Centro                │        │   │
│  │  └──────────────────────────────────────────────┘        │   │
│  │                                                           │   │
│  │  Ciudad *              Código Postal *                    │   │
│  │  ┌───────────────┐     ┌────────────┐                    │   │
│  │  │ Ciudad México │     │ 06000      │                    │   │
│  │  └───────────────┘     └────────────┘                    │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Paso 3: Fuente de Fondos *                              │   │
│  │                                                           │   │
│  │  ( ) Salario/Empleo                                      │   │
│  │  ( ) Negocio propio                                      │   │
│  │  (*) Ahorros/Inversiones                                 │   │
│  │  ( ) Herencia/Donación                                   │   │
│  │  ( ) Otro: _____________                                 │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
│  [✓] Certifico que la información proporcionada es verídica    │
│  [✓] Acepto los términos de verificación de identidad         │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              ENVIAR VERIFICACIÓN                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

---

## Criterios de Aceptación

**Escenario 1: Completar KYC básico exitosamente**
```gherkin
DADO que el usuario está autenticado
Y no ha completado KYC
CUANDO llena todos los campos requeridos
Y marca los checkboxes de certificación
Y hace click en "Enviar verificación"
ENTONCES se crea registro de KYC con status "pending"
Y se muestra mensaje "Verificación enviada"
Y se envía email de confirmación
Y el usuario puede proceder a abrir cuenta (con límite)
```

**Escenario 2: Campos requeridos incompletos**
```gherkin
DADO que el usuario está llenando el formulario KYC
CUANDO deja campos obligatorios vacíos
Y intenta enviar
ENTONCES se muestran mensajes de error en campos faltantes
Y el botón de enviar permanece deshabilitado
```

**Escenario 3: Usuario menor de 18 años**
```gherkin
DADO que el usuario ingresa fecha de nacimiento
CUANDO la edad calculada es menor a 18 años
ENTONCES se muestra error "Debes ser mayor de 18 años"
Y NO se permite enviar el formulario
```

**Escenario 4: País no soportado**
```gherkin
DADO que el usuario selecciona país de residencia
CUANDO selecciona un país no soportado (ej: USA, Irán)
ENTONCES se muestra advertencia "No operamos en este país actualmente"
Y se bloquea el envío del formulario
```

**Escenario 5: KYC aprobado automáticamente**
```gherkin
DADO que el usuario envió KYC
Y todos los datos son válidos
CUANDO el sistema procesa la verificación
ENTONCES el status cambia a "approved" automáticamente
Y se envía email "Verificación aprobada"
Y se incrementan los límites de depósito/retiro
```

**Escenario 6: Ver status de KYC**
```gherkin
DADO que el usuario tiene KYC en proceso
CUANDO navega a /account/kyc
ENTONCES se muestra status actual (pending, approved, rejected)
Y se muestra información enviada
Y si está approved, se muestra badge "✅ Verificado"
```

**Escenario 7: KYC ya completado**
```gherkin
DADO que el usuario ya tiene KYC aprobado
CUANDO intenta acceder al formulario KYC
ENTONCES se redirige a página de status
Y se muestra "Ya estás verificado"
Y puede ver opción "Actualizar información"
```

## Criterios Adicionales

- [ ] Validar formato de fecha de nacimiento
- [ ] Validar código postal según país
- [ ] Encriptar datos sensibles en DB
- [ ] Log de auditoría de cambios
- [ ] Permitir actualizar información (requiere re-aprobación)
- [ ] Integración con servicio de verificación (futuro: Onfido, Jumio)

---

## Tareas Técnicas

**Database:**
- [ ] DB-INV-001: Tabla kyc.verifications
- [ ] DB-INV-002: Enum kyc_status (pending, approved, rejected, expired)
- [ ] DB-INV-003: Encriptar campos sensibles (dirección, DOB)

**Backend:**
- [ ] BE-INV-001: Endpoint POST /kyc/submit
- [ ] BE-INV-002: Implementar KYCService.submitVerification()
- [ ] BE-INV-003: Validar edad mínima (18 años)
- [ ] BE-INV-004: Validar país soportado
- [ ] BE-INV-005: Endpoint GET /kyc/status
- [ ] BE-INV-006: Auto-aprobar KYC básico (sin documentos)
- [ ] BE-INV-007: Endpoint PUT /kyc/update
- [ ] BE-INV-008: Enviar emails de status

**Frontend:**
- [ ] FE-INV-001: Crear página KYCFormPage.tsx
- [ ] FE-INV-002: Crear componente PersonalInfoForm.tsx
- [ ] FE-INV-003: Crear componente AddressForm.tsx
- [ ] FE-INV-004: Crear componente FundingSourceSelector.tsx
- [ ] FE-INV-005: Crear página KYCStatusPage.tsx
- [ ] FE-INV-006: Validaciones de formulario (Formik/React Hook Form)
- [ ] FE-INV-007: Implementar kycStore

**Tests:**
- [ ] TEST-INV-001: Test validación de edad
- [ ] TEST-INV-002: Test país soportado
- [ ] TEST-INV-003: Test auto-aprobación
- [ ] TEST-INV-004: Test E2E flujo completo

---

## Dependencias

**Depende de:**
- [ ] US-AUTH-001: Autenticación - Estado: ✅ Completado

**Bloquea:**
- [ ] US-INV-002: Abrir cuenta (sin KYC, límite de $1,000)
- [ ] US-INV-003: Realizar depósito (sin KYC, límite de $1,000)

---

## Notas Técnicas

**Endpoints involucrados:**
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| POST | /kyc/submit | Enviar verificación |
| GET | /kyc/status | Ver status |
| PUT | /kyc/update | Actualizar info |

**Entidades/Tablas:**

**kyc.verifications:**
```sql
CREATE TABLE kyc.verifications (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL UNIQUE REFERENCES auth.users(id),
  first_name VARCHAR(100) NOT NULL,
  last_name VARCHAR(100) NOT NULL,
  date_of_birth DATE NOT NULL,
  country_code VARCHAR(2) NOT NULL,
  address_line1 TEXT NOT NULL,
  city VARCHAR(100) NOT NULL,
  postal_code VARCHAR(20) NOT NULL,
  funding_source VARCHAR(50) NOT NULL,
  status VARCHAR(20) DEFAULT 'pending',
  submitted_at TIMESTAMP DEFAULT NOW(),
  approved_at TIMESTAMP,
  rejected_at TIMESTAMP,
  rejection_reason TEXT,
  updated_at TIMESTAMP DEFAULT NOW()
);
```

**Request Body POST /kyc/submit:**
```typescript
{
  firstName: "Juan",
  lastName: "Pérez González",
  dateOfBirth: "1990-06-15",
  country: "MX",
  addressLine1: "Av. Reforma 123, Col. Centro",
  city: "Ciudad de México",
  postalCode: "06000",
  fundingSource: "savings" | "salary" | "business" | "inheritance" | "other",
  certifyTruthful: true,
  acceptTerms: true
}
```

**Response:**
```typescript
{
  verification: {
    id: "uuid",
    userId: "uuid",
    status: "pending",
    submittedAt: "2025-12-05T10:00:00Z"
  },
  message: "Verificación enviada. Procesaremos tu información pronto."
}
```

**Response GET /kyc/status:**
```typescript
{
  verification: {
    id: "uuid",
    status: "approved",
    firstName: "Juan",
    lastName: "Pérez González",
    country: "MX",
    submittedAt: "2025-12-05T10:00:00Z",
    approvedAt: "2025-12-05T10:05:00Z"
  },
  limits: {
    depositLimit: 50000, // USD
    withdrawalLimit: 50000,
    accountLimit: 100000
  }
}
```

**Países Soportados (inicial):**
- México (MX)
- Colombia (CO)
- Argentina (AR)
- Chile (CL)
- Perú (PE)

**Países NO Soportados:**
- USA (regulación compleja)
- Países sancionados (Irán, Corea del Norte, etc.)

**Estados de KYC:**
- `pending`: Enviado, esperando procesamiento
- `approved`: Aprobado, usuario verificado
- `rejected`: Rechazado, información incorrecta
- `expired`: Expiró (requiere renovación anual)

**Límites sin KYC:**
- Depósito máximo: $1,000 USD
- Retiro máximo: $1,000 USD
- Balance máximo: $2,000 USD

**Límites con KYC aprobado:**
- Depósito máximo: $50,000 USD por transacción
- Retiro máximo: $50,000 USD por transacción
- Balance máximo: $100,000 USD

**Auto-Aprobación:**
- Para MVP, KYC básico se auto-aprueba si:
  - Todos los campos están completos
  - Edad >= 18 años
  - País soportado
- En producción, integrar con Onfido/Jumio para verificación con documentos

**Email Templates:**
- **KYC Submitted:** "Hemos recibido tu verificación"
- **KYC Approved:** "Tu identidad ha sido verificada ✅"
- **KYC Rejected:** "Necesitamos más información"

---

## Definition of Ready (DoR)

- [x] Historia claramente escrita
- [x] Criterios de aceptación definidos
- [x] Story points estimados
- [x] Dependencias identificadas
- [x] Límites definidos
- [ ] Diseño/mockup disponible
- [x] API spec disponible

## Definition of Done (DoD)

- [ ] Código implementado según criterios
- [ ] Tests unitarios escritos y pasando
- [ ] Tests de integración pasando
- [ ] Validaciones funcionando correctamente
- [ ] Encriptación de datos sensibles
- [ ] Límites aplicados correctamente
- [ ] Code review aprobado
- [ ] Documentación actualizada
- [ ] QA aprobado
- [ ] Desplegado en ambiente de pruebas

---

## Historial de Cambios

| Fecha | Cambio | Autor |
|-------|--------|-------|
| 2025-12-05 | Creación | Requirements-Analyst |

---

**Creada por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Última actualización:** 2025-12-05
