# DIRECTIVA: POLITICA DE CARGA LIMPIA (Clean Load Policy)

**Ambito:** GLOBAL - Todos los proyectos del workspace
**Version:** 2.0.0
**Fecha:** 2025-12-05
**Tipo:** Directiva Obligatoria
**Stack:** PostgreSQL 15+

---

## PROPOSITO

Garantizar que la base de datos pueda **recrearse completamente desde archivos DDL** en cualquier momento, sin dependencia de scripts incrementales, migrations o fixes.

Esta politica establece que:
- Los **archivos DDL son la fuente de verdad**
- La **base de datos es el resultado** de ejecutar esos archivos
- Todo cambio se valida mediante **recreacion completa**
- **No se usan migrations** ni scripts incrementales

---

## VARIABLES DE PROYECTO

Esta directiva usa placeholders que cada proyecto debe resolver en su `CONTEXTO-PROYECTO.md`:

```yaml
Paths Requeridos:
  {DB_DDL_PATH}:     Path a archivos DDL (ej: apps/database/ddl)
  {DB_SCRIPTS_PATH}: Path a scripts de BD (ej: apps/database)
  {DB_NAME}:         Nombre de la base de datos
  {PROJECT_ROOT}:    Raiz del proyecto

Comandos:
  RECREATE_CMD:      Comando de recreacion (ej: ./drop-and-recreate-database.sh)
```

---

## REGLAS OBLIGATORIAS

### 1. DDL-First Approach

**Principio:** Los archivos DDL se crean/actualizan ANTES de modificar la base de datos.

#### FLUJO CORRECTO

```
1. Crear/actualizar archivo DDL
   └─> {DB_DDL_PATH}/schemas/{schema}/{tipo}/{archivo}.sql

2. Validar sintaxis del archivo DDL
   └─> Revisar manualmente o con linter SQL

3. Ejecutar recreacion completa
   └─> ./{DB_SCRIPTS_PATH}/{RECREATE_CMD}

4. Si funciona → Commitear archivo DDL
   └─> git add {DB_DDL_PATH}/...
   └─> git commit -m "feat(db): descripcion del cambio"

5. Si falla → Corregir DDL y volver a paso 3
   └─> NO ejecutar fixes manuales en BD
   └─> Corregir archivo DDL
```

#### FLUJO PROHIBIDO

```
1. Ejecutar ALTER TABLE directamente en psql
2. "Documentar" el cambio creando archivo DDL despues
3. Esperar que funcione en produccion
4. Crear migration incremental para aplicar cambio
```

**Razon de prohibicion:**
- La BD y el DDL quedan desincronizados
- No hay garantia de que el cambio funcione en recreacion limpia
- Otros desarrolladores no pueden recrear la BD localmente
- Riesgo alto en produccion (cambio no validado)

---

### 2. Prohibicion de Migrations

**PROHIBIDO crear o usar:**

```yaml
Carpeta migrations/:
  - {DB_DDL_PATH}/migrations/
  - Archivos estilo TypeORM/Prisma migrations
  - Archivos versionados tipo: 001-create-users.sql, 002-add-column.sql

Scripts incrementales:
  - migration-*.sql
  - alter-*.sql
  - update-*.sql
  - change-*.sql

Estrategia ALTER TABLE como cambio principal:
  - ALTER TABLE ... ADD COLUMN (sin actualizar DDL base)
  - ALTER TABLE ... DROP COLUMN (sin actualizar DDL base)
  - ALTER TABLE ... MODIFY COLUMN (sin actualizar DDL base)
```

#### Por que NO migrations?

**Problemas de migrations incrementales:**
1. **Orden de ejecucion:** Dificil de mantener, errores si se ejecuta fuera de orden
2. **Estado de BD desconocido:** No sabes si migration ya se aplico o no
3. **Recreacion imposible:** No puedes crear BD limpia sin ejecutar todas las migrations en orden
4. **Dependencias complejas:** Migrations dependen de migrations anteriores
5. **Debugging dificil:** Dificil saber en que migration esta el problema
6. **Rollback riesgoso:** Dificil revertir migrations sin perder datos

**Ventajas de carga limpia:**
1. **Fuente de verdad clara:** DDL es el estado actual, siempre
2. **Recreacion simple:** Un comando y listo
3. **Sin estado:** No importa el estado anterior de la BD
4. **Debugging facil:** Error en recreacion = DDL tiene problema
5. **Onboarding rapido:** Nuevos devs crean BD en 1 comando
6. **Testing robusto:** Tests siempre empiezan con BD limpia

---

### 3. Prohibicion de Fixes y Patches

**PROHIBIDO crear:**

```yaml
Archivos de correccion unica (one-time scripts):
  - fix-*.sql
  - patch-*.sql
  - hotfix-*.sql
  - repair-*.sql
  - cleanup-*.sql

Scripts "temporales" que se vuelven permanentes:
  - temp-fix-users.sql
  - manual-update-points.sql
  - data-correction-YYYY-MM-DD.sql
```

#### Que hacer en lugar de fix/patch?

**Escenario 1: Error en DDL**

```markdown
INCORRECTO:
1. Crear fix-missing-column.sql con ALTER TABLE
2. Ejecutar fix en BD
3. "Ya funciona, no tocar"

CORRECTO:
1. Identificar archivo DDL original con error
   └─> {DB_DDL_PATH}/schemas/{schema}/tables/{archivo}.sql
2. Corregir DDL (agregar columna faltante en CREATE TABLE)
3. Validar con recreacion completa
4. Commitear DDL corregido
```

**Escenario 2: Datos incorrectos en seeds**

```markdown
INCORRECTO:
1. Crear fix-seed-data.sql con UPDATE/INSERT
2. Ejecutar fix en BD
3. Dejar seed original con datos incorrectos

CORRECTO:
1. Identificar archivo seed con error
2. Corregir seed (arreglar datos)
3. Validar con recreacion completa
4. Commitear seed corregido
```

**Escenario 3: Error en produccion**

```markdown
INCORRECTO:
1. Ejecutar fix directo en BD de produccion
2. "Olvidar" actualizar DDL
3. Siguiente deploy rompe porque DDL esta desactualizado

CORRECTO:
1. Corregir DDL en desarrollo
2. Validar con recreacion completa local
3. Crear ADR documentando el cambio
4. Aplicar cambio en produccion usando DDL corregido
5. Commitear DDL + ADR
```

---

### 4. Cambios en Tablas Existentes

#### PROCESO CORRECTO para Cambios

**Ejemplo: Agregar columna a tabla existente**

```bash
# 1. Actualizar DDL base (NO crear migration)
# Editar: {DB_DDL_PATH}/schemas/{schema}/tables/{table}.sql

# Cambiar de:
CREATE TABLE {schema}.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username VARCHAR(50) NOT NULL,
    email VARCHAR(255) NOT NULL
);

# A:
CREATE TABLE {schema}.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username VARCHAR(50) NOT NULL,
    email VARCHAR(255) NOT NULL,
    phone_number VARCHAR(20),  -- Nueva columna agregada
    phone_verified BOOLEAN DEFAULT false
);

# 2. Validar con recreacion completa
cd {DB_SCRIPTS_PATH}
./{RECREATE_CMD}

# 3. Si funciona, commitear
git add {DB_DDL_PATH}/schemas/{schema}/tables/{table}.sql
git commit -m "feat(db): add phone_number and phone_verified to users table"

# 4. Documentar en TRAZA-TAREAS-DATABASE.md
```

#### PROCESO PROHIBIDO

```bash
# NO hacer esto:
psql -d {DB_NAME} -c "ALTER TABLE {schema}.users ADD COLUMN phone_number VARCHAR(20);"

# NO crear migration:
echo "ALTER TABLE {schema}.users ADD COLUMN phone_number VARCHAR(20);" \
  > {DB_DDL_PATH}/migrations/002-add-phone-to-users.sql

# NO crear fix:
echo "ALTER TABLE {schema}.users ADD COLUMN phone_number VARCHAR(20);" \
  > {DB_DDL_PATH}/fix-add-phone.sql
```

---

### 5. Validacion de Carga Limpia

**Regla:** TODO cambio en DDL DEBE validarse con recreacion completa.

#### Comandos de Validacion

```bash
# Validacion basica (desarrollo)
cd {DB_SCRIPTS_PATH}
./{RECREATE_CMD}

# Validacion completa (pre-commit)
cd {DB_SCRIPTS_PATH}
./{RECREATE_CMD} && \
  psql -d {DB_NAME} -f scripts/validate-integrity.sql && \
  echo "Carga limpia validada"

# Si falla la recreacion
# → El DDL tiene un problema
# → NO ejecutar fixes manuales
# → Corregir el archivo DDL y volver a intentar
```

#### Frecuencia de Validacion

```yaml
Desarrollo local:
  - Despues de cada cambio en DDL
  - Antes de cada commit que toca {DB_DDL_PATH}/

CI/CD:
  - En cada pull request
  - Antes de merge a main/master
  - En cada deploy a staging/produccion

Mantenimiento:
  - Recreacion semanal de BD de desarrollo
  - Validacion mensual de que DDL + seeds = BD completa
```

#### Checklist de Validacion

```markdown
- [ ] Recreacion completa ejecuta sin errores
- [ ] Todas las tablas se crean correctamente
- [ ] Todos los indices se crean
- [ ] Todas las funciones y triggers se crean
- [ ] Todas las RLS policies se aplican
- [ ] Seeds se cargan sin errores
- [ ] Integridad referencial validada (FKs)
- [ ] No hay warnings en el log de create-database.sh
```

---

### 6. Homologacion BD <-> Archivos DDL

**Principio:** Los archivos DDL son la fuente de verdad, la BD es derivada.

```yaml
Fuente de verdad:
  {DB_DDL_PATH}/schemas/**/*.sql
  {DB_SEEDS_PATH}/**/*.sql

Derivado (resultado de ejecutar DDL):
  Base de datos PostgreSQL real

Flujo de sincronizacion:
  DDL actualizado → Recreacion BD → BD actualizada

Flujo PROHIBIDO:
  BD actualizada manualmente → "Documentar" en DDL despues
```

---

## HERRAMIENTAS Y SCRIPTS

### Scripts de Recreacion (estructura estandar)

```bash
{DB_SCRIPTS_PATH}/
├── create-database.sh              # Crear BD completa desde DDL
├── drop-and-recreate-database.sh   # Drop + Create (carga limpia total)
├── reset-database.sh               # Reset a estado inicial
└── recreate-database.sh            # Alias de drop-and-recreate
```

### Script de Validacion de Politica

```bash
#!/bin/bash
# validate-clean-load-policy.sh
# Validar cumplimiento de Politica de Carga Limpia

echo "Validando Politica de Carga Limpia..."

# 1. Verificar que no existe carpeta migrations/
if [ -d "{DB_DDL_PATH}/migrations" ]; then
  echo "ERROR: Carpeta migrations/ detectada (PROHIBIDA)"
  exit 1
fi

# 2. Verificar que no hay archivos fix-*.sql o patch-*.sql
FIXES=$(find {DB_DDL_PATH} -name "fix-*.sql" -o -name "patch-*.sql" -o -name "hotfix-*.sql")
if [ -n "$FIXES" ]; then
  echo "ERROR: Archivos fix/patch detectados (PROHIBIDOS):"
  echo "$FIXES"
  exit 1
fi

# 3. Validar que recreacion completa funciona
echo "Validando recreacion completa..."
./{DB_SCRIPTS_PATH}/{RECREATE_CMD} > /tmp/clean-load-test.log 2>&1
if [ $? -ne 0 ]; then
  echo "ERROR: Recreacion completa fallo"
  echo "Ver log: /tmp/clean-load-test.log"
  exit 1
fi

echo "Politica de Carga Limpia: CUMPLIDA"
exit 0
```

---

## CHECKLIST DE CUMPLIMIENTO

### Para Database-Agent

Antes de completar una tarea, verificar:

```markdown
- [ ] Todos los cambios estan en archivos DDL (no en BD directamente)
- [ ] NO se crearon archivos en migrations/
- [ ] NO se crearon archivos fix-*.sql o patch-*.sql
- [ ] Recreacion completa funciona
- [ ] MASTER_INVENTORY.yml actualizado (si aplica)
- [ ] TRAZA-TAREAS-DATABASE.md actualizado
- [ ] Commits incluyen archivos DDL, no scripts temporales
```

### Para Code Reviewers

Al revisar PRs que tocan base de datos:

```markdown
- [ ] Cambios estan en {DB_DDL_PATH}/, no en migrations/
- [ ] NO hay archivos fix-*.sql, patch-*.sql, hotfix-*.sql
- [ ] DDL sigue estandares (ver DIRECTIVA-DISENO-BASE-DATOS.md)
- [ ] CI/CD ejecuto recreacion completa exitosamente
- [ ] TRAZA-TAREAS-DATABASE.md documenta el cambio
```

---

## CASOS ESPECIALES

### Caso 1: Migracion desde Otro Sistema

**Escenario:** Importar datos desde sistema legacy.

```markdown
CORRECTO:
1. Crear seed en {DB_SEEDS_PATH}/prod/migration/01-import-legacy.sql
2. Documentar que es importacion unica con comentarios
3. Incluir en create-database.sh con flag condicional
4. Mantener seed para recreaciones futuras (testing)
```

### Caso 2: Datos de Produccion

**Escenario:** Necesito actualizar datos en produccion.

```markdown
Si es dato de configuracion:
  └─> Actualizar seed en {DB_SEEDS_PATH}/prod/
  └─> Validar con recreacion local
  └─> Aplicar seed en produccion

Si es dato de usuario (transaccional):
  └─> NO va en seeds (datos dinamicos)
  └─> Crear script de actualizacion documentado
  └─> Ejecutar en produccion
  └─> Archivar script como documentacion (NO en seeds)
```

### Caso 3: Hotfix en Produccion

**Escenario:** Bug critico en produccion que requiere cambio urgente en BD.

```markdown
CORRECTO (incluso en emergencia):
1. Corregir DDL localmente
2. Validar con recreacion local (rapido: 2-3 min)
3. Crear ADR documentando el hotfix
4. Aplicar DDL en produccion
5. Commitear DDL + ADR inmediatamente
6. Post-mortem: Por que no se detecto en testing?
```

---

## BENEFICIOS DE ESTA POLITICA

### Tecnicos

1. **Reproducibilidad:** BD puede recrearse en cualquier momento, en cualquier ambiente
2. **Simplicidad:** Un script, un resultado (BD completa)
3. **Debugging:** Error en recreacion = DDL tiene problema (facil de localizar)
4. **Testing:** Tests siempre empiezan con BD limpia predecible
5. **Onboarding:** Nuevos devs tienen BD funcional en minutos

### Operacionales

1. **Disaster Recovery:** Recrear BD desde DDL es rapido y confiable
2. **Ambientes:** Dev, Staging, Prod tienen misma estructura (desde mismo DDL)
3. **Auditoria:** Git history de DDL = historia completa de cambios en BD
4. **Rollback:** Revertir commit de DDL = revertir cambio en BD
5. **Compliance:** Cambios en BD rastreables y versionados

### De Equipo

1. **Claridad:** Todo el equipo sabe donde estan los cambios (DDL)
2. **Colaboracion:** Conflictos en DDL son faciles de resolver (Git)
3. **Documentacion:** DDL es documentacion ejecutable y siempre actualizada
4. **Confianza:** Cambios validados con recreacion = alta confianza
5. **Velocidad:** No hay "estado misterioso" de BD, siempre es predecible

---

## CONTRASTE: Carga Limpia vs Migrations

| Aspecto | Migrations Incrementales | Carga Limpia (Esta Politica) |
|---------|-------------------------|------------------------------|
| **Fuente de verdad** | Estado de BD + Migrations historicas | Archivos DDL actuales |
| **Recreacion** | Ejecutar todas las migrations en orden | Un script |
| **Debugging** | Dificil (cual migration fallo?) | Facil (DDL tiene el problema) |
| **Onboarding** | Complejo (ejecutar N migrations) | Simple (1 comando, BD lista) |
| **Estado de BD** | Incierto (migrations aplicadas?) | Siempre conocido (DDL) |
| **Rollback** | Requiere migration de rollback | Revertir commit de DDL |
| **Testing** | Dificil (estado previo incierto) | Simple (siempre BD limpia) |
| **Produccion** | Riesgoso (migration puede fallar) | Confiable (validado en recreacion) |

**Cuando usar migrations:** Proyectos con datos de produccion que NO pueden perderse y requieren zero-downtime deployments.

**Cuando usar carga limpia:** Proyectos en desarrollo, startups, MVPs, sistemas donde BD puede recrearse.

---

## REFERENCIAS

### Documentos Relacionados
- **DIRECTIVA-DISENO-BASE-DATOS.md** - Estandares de diseno
- **ESTANDARES-NOMENCLATURA-BASE.md** - Nomenclatura de objetos DB

### Ver implementacion especifica por proyecto
- Cada proyecto define sus paths en `orchestration/00-guidelines/CONTEXTO-PROYECTO.md`
- Directivas especificas en `projects/{proyecto}/orchestration/directivas/`

---

**Version:** 2.0.0
**Fecha:** 2025-12-05
**Tipo:** Directiva Global (aplica a todos los proyectos)
**Proxima revision:** Trimestral o al identificar necesidad
