# DIRECTIVA: Politica de Carga Limpia (DDL-First)

**ID:** DIR-DB-001
**Version:** 1.0.0
**Fecha:** 2025-12-06
**Estado:** ACTIVA
**Aplica a:** Todos los agentes que trabajen con base de datos

---

## OBJETIVO

Establecer una politica clara y obligatoria para la gestion del esquema de base de datos del proyecto Trading Platform (OrbiQuant IA), garantizando que la base de datos pueda ser creada o recreada completamente desde archivos DDL sin dependencia de migraciones incrementales.

---

## PRINCIPIO FUNDAMENTAL

> **La base de datos SIEMPRE debe poder ser creada desde cero ejecutando unicamente los archivos DDL.**

Esto significa:
- NO migraciones incrementales
- NO archivos de "fix" o "patch"
- NO scripts de correccion
- NO ALTER TABLE en archivos separados

---

## REGLAS OBLIGATORIAS

### 1. Estructura de Archivos

```
apps/database/
├── ddl/
│   └── schemas/
│       ├── {schema}/
│       │   ├── 00-enums.sql          # Tipos enumerados
│       │   ├── tables/
│       │   │   ├── 01-{tabla}.sql    # Una tabla por archivo
│       │   │   ├── 02-{tabla}.sql
│       │   │   └── ...
│       │   ├── functions/
│       │   │   ├── 01-{funcion}.sql
│       │   │   └── ...
│       │   ├── triggers/
│       │   │   └── ...
│       │   └── views/
│       │       └── ...
├── seeds/
│   ├── prod/                         # Datos de produccion
│   └── dev/                          # Datos de desarrollo
└── scripts/
    ├── create-database.sh            # Crear BD
    └── drop-and-recreate-database.sh # Recrear BD
```

### 2. Nomenclatura de Archivos

| Tipo | Patron | Ejemplo |
|------|--------|---------|
| Enums | `00-enums.sql` | `00-enums.sql` |
| Tablas | `NN-{nombre}.sql` | `01-users.sql`, `02-profiles.sql` |
| Funciones | `NN-{nombre}.sql` | `01-update_updated_at.sql` |
| Triggers | `NN-{nombre}.sql` | `01-audit_trigger.sql` |
| Views | `NN-{nombre}.sql` | `01-user_summary.sql` |

El numero `NN` indica el orden de ejecucion dentro de cada carpeta.

### 3. Modificaciones al Schema

**CORRECTO:**
```sql
-- Editar directamente el archivo DDL original
-- apps/database/ddl/schemas/auth/tables/01-users.sql

CREATE TABLE IF NOT EXISTS auth.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    -- Agregar nuevas columnas aqui
    phone VARCHAR(20),  -- <-- Nueva columna
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```

**INCORRECTO:**
```sql
-- NO crear archivos de migracion
-- migrations/20251206_add_phone_to_users.sql  <-- PROHIBIDO

ALTER TABLE auth.users ADD COLUMN phone VARCHAR(20);
```

### 4. Cuando Necesitas Cambiar el Schema

1. **Edita el archivo DDL original** de la tabla/funcion/trigger
2. **Ejecuta recreacion** en tu ambiente de desarrollo:
   ```bash
   ./scripts/drop-and-recreate-database.sh
   ```
3. **Verifica** que todo funcione correctamente
4. **Commit** los cambios al DDL

### 5. Prohibiciones Explicitas

| Accion | Permitido | Razon |
|--------|-----------|-------|
| Crear archivo `migrations/*.sql` | NO | Rompe carga limpia |
| Crear archivo `fix-*.sql` | NO | Rompe carga limpia |
| Crear archivo `patch-*.sql` | NO | Rompe carga limpia |
| Crear archivo `alter-*.sql` | NO | Rompe carga limpia |
| Usar `ALTER TABLE` en archivo separado | NO | Debe estar en DDL original |
| Modificar DDL original directamente | SI | Es la forma correcta |

---

## ESTANDARES TECNICOS

### Tipos de Datos

| Uso | Tipo Correcto | Tipo Incorrecto |
|-----|---------------|-----------------|
| Timestamps | `TIMESTAMPTZ` | `TIMESTAMP` |
| UUIDs | `gen_random_uuid()` | `uuid_generate_v4()` |
| Moneda | `DECIMAL(20,8)` | `FLOAT`, `DOUBLE` |
| Texto variable | `VARCHAR(n)` | `CHAR(n)` para texto variable |

### Convenciones SQL

```sql
-- Nombres en snake_case
CREATE TABLE auth.user_profiles (  -- Correcto
CREATE TABLE auth.UserProfiles (   -- Incorrecto

-- Siempre incluir schema
CREATE TABLE auth.users (          -- Correcto
CREATE TABLE users (               -- Incorrecto (usa public)

-- IF NOT EXISTS en CREATE
CREATE TABLE IF NOT EXISTS auth.users (
CREATE TYPE IF NOT EXISTS auth.user_status AS ENUM (

-- Indices con prefijo descriptivo
CREATE INDEX idx_users_email ON auth.users(email);
CREATE INDEX idx_users_created ON auth.users(created_at DESC);
```

### Foreign Keys

```sql
-- Siempre referenciar con schema completo
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

-- Nunca asumir schema
user_id UUID NOT NULL REFERENCES users(id),  -- INCORRECTO
```

---

## ORDEN DE CARGA

El script `create-database.sh` ejecuta en este orden:

1. **Extensiones**
   - uuid-ossp
   - pgcrypto
   - pg_trgm
   - btree_gin
   - vector (si disponible)

2. **Schemas** (en orden)
   - auth
   - education
   - financial
   - trading
   - investment
   - ml
   - llm
   - audit

3. **Por cada schema:**
   - 00-enums.sql (si existe)
   - tables/*.sql (orden numerico)
   - functions/*.sql (orden numerico)
   - triggers/*.sql (orden numerico)
   - views/*.sql (orden numerico)

4. **Seeds**
   - prod/ o dev/ segun ambiente

---

## VALIDACION

### Pre-commit Checklist

Antes de hacer commit de cambios a DDL:

- [ ] No existen archivos `migrations/`, `fix-*`, `patch-*`, `alter-*`
- [ ] Todos los cambios estan en archivos DDL originales
- [ ] Se puede ejecutar `drop-and-recreate-database.sh` sin errores
- [ ] Todas las FKs usan schema completo (`auth.users`, no `users`)
- [ ] Todos los timestamps son `TIMESTAMPTZ`
- [ ] Todos los UUIDs usan `gen_random_uuid()`

### Script de Validacion

```bash
# Verificar que no hay archivos prohibidos
find apps/database -name "fix-*.sql" -o -name "patch-*.sql" -o -name "alter-*.sql"
# Debe retornar vacio

# Verificar que no hay carpeta migrations con contenido nuevo
ls apps/database/migrations/
# Solo debe existir si hay migraciones legacy (a eliminar)
```

---

## EXCEPCIONES

### Unica Excepcion: Datos de Produccion

Si hay datos de produccion que NO pueden perderse:

1. **Exportar datos** antes de recrear
2. **Recrear schema** con DDL limpio
3. **Importar datos** desde backup

Esto NO es una migracion, es un proceso de backup/restore.

---

## CONSECUENCIAS DE VIOLAR ESTA DIRECTIVA

1. **Build fallara** - CI/CD rechazara archivos prohibidos
2. **PR sera rechazado** - Code review detectara violaciones
3. **Deuda tecnica** - Se acumularan inconsistencias

---

## REFERENCIAS

- [_MAP.md - Database Schemas](../apps/database/schemas/_MAP.md)
- [DECISIONES-ARQUITECTONICAS.md](../docs/99-analisis/DECISIONES-ARQUITECTONICAS.md)
- [create-database.sh](../apps/database/scripts/create-database.sh)

---

## HISTORIAL DE CAMBIOS

| Version | Fecha | Cambio |
|---------|-------|--------|
| 1.0.0 | 2025-12-06 | Version inicial |

---

*Directiva establecida por Requirements-Analyst Agent*
*OrbiQuant IA Trading Platform*
