- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
740 lines
22 KiB
Markdown
740 lines
22 KiB
Markdown
# DIRECTIVA: POLÍTICA DE CARGA LIMPIA (Clean Load Policy)
|
|
|
|
**Proyecto:** GAMILIT - Sistema de Gamificación Educativa
|
|
**Versión:** 1.0.0
|
|
**Fecha:** 2025-11-23
|
|
**Ámbito:** Database-Agent y todos los desarrolladores
|
|
**Tipo:** Directiva Obligatoria
|
|
**Stack:** PostgreSQL 15+ con PostGIS
|
|
|
|
---
|
|
|
|
## 🎯 PROPÓSITO
|
|
|
|
Garantizar que la base de datos pueda **recrearse completamente desde archivos DDL** en cualquier momento, sin dependencia de scripts incrementales, migrations o fixes.
|
|
|
|
Esta política 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 **recreación completa**
|
|
- ❌ **No se usan migrations** ni scripts incrementales
|
|
|
|
---
|
|
|
|
## 📜 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
|
|
└─> apps/database/ddl/schemas/{schema}/{tipo}/{archivo}.sql
|
|
|
|
2. Validar sintaxis del archivo DDL
|
|
└─> Revisar manualmente o con linter SQL
|
|
|
|
3. Ejecutar recreación completa
|
|
└─> ./apps/database/drop-and-recreate-database.sh
|
|
|
|
4. Si funciona → Commitear archivo DDL
|
|
└─> git add apps/database/ddl/...
|
|
└─> git commit -m "feat(db): descripción 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 después
|
|
❌ 3. Esperar que funcione en producción
|
|
❌ 4. Crear migration incremental para aplicar cambio
|
|
```
|
|
|
|
**Razón de prohibición:**
|
|
- La BD y el DDL quedan desincronizados
|
|
- No hay garantía de que el cambio funcione en recreación limpia
|
|
- Otros desarrolladores no pueden recrear la BD localmente
|
|
- Riesgo alto en producción (cambio no validado)
|
|
|
|
---
|
|
|
|
### 2. Prohibición de Migrations
|
|
|
|
**PROHIBIDO crear o usar:**
|
|
|
|
```yaml
|
|
❌ Carpeta migrations/:
|
|
- apps/database/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 qué NO migrations?
|
|
|
|
**Problemas de migrations incrementales:**
|
|
1. ❌ **Orden de ejecución:** Difícil de mantener, errores si se ejecuta fuera de orden
|
|
2. ❌ **Estado de BD desconocido:** No sabes si migration ya se aplicó o no
|
|
3. ❌ **Recreación imposible:** No puedes crear BD limpia sin ejecutar todas las migrations en orden
|
|
4. ❌ **Dependencias complejas:** Migrations dependen de migrations anteriores
|
|
5. ❌ **Debugging difícil:** Difícil saber en qué migration está el problema
|
|
6. ❌ **Rollback riesgoso:** Difícil revertir migrations sin perder datos
|
|
|
|
**Ventajas de carga limpia:**
|
|
1. ✅ **Fuente de verdad clara:** DDL es el estado actual, siempre
|
|
2. ✅ **Recreación simple:** `./drop-and-recreate-database.sh` y listo
|
|
3. ✅ **Sin estado:** No importa el estado anterior de la BD
|
|
4. ✅ **Debugging fácil:** Error en recreación = DDL tiene problema
|
|
5. ✅ **Onboarding rápido:** Nuevos devs crean BD en 1 comando
|
|
6. ✅ **Testing robusto:** Tests siempre empiezan con BD limpia
|
|
|
|
---
|
|
|
|
### 3. Prohibición de Fixes y Patches
|
|
|
|
**PROHIBIDO crear:**
|
|
|
|
```yaml
|
|
❌ Archivos de corrección única (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-2025-11-23.sql
|
|
```
|
|
|
|
#### ¿Qué 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
|
|
└─> apps/database/ddl/schemas/auth_management/tables/01-users.sql
|
|
2. Corregir DDL (agregar columna faltante en CREATE TABLE)
|
|
3. Validar con recreación completa: ./drop-and-recreate-database.sh
|
|
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
|
|
└─> apps/database/seeds/dev/auth_management/01-users.sql
|
|
2. Corregir seed (arreglar datos)
|
|
3. Validar con recreación completa: ./drop-and-recreate-database.sh
|
|
4. Commitear seed corregido
|
|
```
|
|
|
|
**Escenario 3: Error en producción**
|
|
|
|
```markdown
|
|
❌ INCORRECTO:
|
|
1. Ejecutar fix directo en BD de producción
|
|
2. "Olvidar" actualizar DDL
|
|
3. Siguiente deploy rompe porque DDL está desactualizado
|
|
|
|
✅ CORRECTO:
|
|
1. Corregir DDL en desarrollo
|
|
2. Validar con recreación completa local
|
|
3. Crear ADR documentando el cambio
|
|
4. Aplicar cambio en producción 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)
|
|
vim apps/database/ddl/schemas/auth_management/tables/01-users.sql
|
|
|
|
# Cambiar de:
|
|
CREATE TABLE auth_management.users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
username VARCHAR(50) NOT NULL,
|
|
email VARCHAR(255) NOT NULL
|
|
);
|
|
|
|
# A:
|
|
CREATE TABLE auth_management.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 recreación completa
|
|
cd apps/database
|
|
./drop-and-recreate-database.sh
|
|
|
|
# 3. Si funciona, commitear
|
|
git add apps/database/ddl/schemas/auth_management/tables/01-users.sql
|
|
git commit -m "feat(db): add phone_number and phone_verified to users table"
|
|
|
|
# 4. Documentar en TRAZA-TAREAS-DATABASE.md
|
|
echo "## [DB-042] Agregar verificación de teléfono
|
|
**Fecha:** 2025-11-23
|
|
**Estado:** ✅ Completado
|
|
**Cambios:**
|
|
- Agregadas columnas phone_number, phone_verified a auth_management.users
|
|
**Archivos modificados:**
|
|
- apps/database/ddl/schemas/auth_management/tables/01-users.sql
|
|
" >> orchestration/trazas/TRAZA-TAREAS-DATABASE.md
|
|
```
|
|
|
|
#### ❌ PROCESO PROHIBIDO
|
|
|
|
```bash
|
|
# ❌ NO hacer esto:
|
|
psql -d gamilit_db -c "ALTER TABLE auth_management.users ADD COLUMN phone_number VARCHAR(20);"
|
|
|
|
# ❌ NO crear migration:
|
|
echo "ALTER TABLE auth_management.users ADD COLUMN phone_number VARCHAR(20);" \
|
|
> apps/database/migrations/002-add-phone-to-users.sql
|
|
|
|
# ❌ NO crear fix:
|
|
echo "ALTER TABLE auth_management.users ADD COLUMN phone_number VARCHAR(20);" \
|
|
> apps/database/fix-add-phone.sql
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Validación de Carga Limpia
|
|
|
|
**Regla:** TODO cambio en DDL DEBE validarse con recreación completa.
|
|
|
|
#### Comandos de Validación
|
|
|
|
```bash
|
|
# Validación básica (desarrollo)
|
|
cd apps/database
|
|
./drop-and-recreate-database.sh
|
|
|
|
# Validación completa (pre-commit)
|
|
cd apps/database
|
|
./drop-and-recreate-database.sh && \
|
|
psql -d gamilit_platform -f scripts/validate-integrity.sql && \
|
|
echo "✅ Carga limpia validada"
|
|
|
|
# Si falla la recreación
|
|
# → El DDL tiene un problema
|
|
# → NO ejecutar fixes manuales
|
|
# → Corregir el archivo DDL y volver a intentar
|
|
```
|
|
|
|
#### Frecuencia de Validación
|
|
|
|
```yaml
|
|
Desarrollo local:
|
|
- Después de cada cambio en DDL
|
|
- Antes de cada commit que toca apps/database/
|
|
|
|
CI/CD:
|
|
- En cada pull request
|
|
- Antes de merge a main/master
|
|
- En cada deploy a staging/producción
|
|
|
|
Mantenimiento:
|
|
- Recreación semanal de BD de desarrollo
|
|
- Validación mensual de que DDL + seeds = BD completa
|
|
```
|
|
|
|
#### Checklist de Validación
|
|
|
|
```markdown
|
|
- [ ] Recreación completa ejecuta sin errores
|
|
- [ ] Todas las tablas se crean correctamente
|
|
- [ ] Todos los índices 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. Homologación BD ↔ Archivos DDL
|
|
|
|
**Principio:** Los archivos DDL son la fuente de verdad, la BD es derivada.
|
|
|
|
```yaml
|
|
Fuente de verdad:
|
|
✅ apps/database/ddl/schemas/**/*.sql
|
|
✅ apps/database/seeds/**/*.sql
|
|
|
|
Derivado (resultado de ejecutar DDL):
|
|
✅ Base de datos PostgreSQL real
|
|
|
|
Flujo de sincronización:
|
|
DDL actualizado → Recreación BD → BD actualizada
|
|
|
|
Flujo PROHIBIDO:
|
|
❌ BD actualizada manualmente → "Documentar" en DDL después
|
|
```
|
|
|
|
#### Validación de Homologación
|
|
|
|
```bash
|
|
# ¿Cómo saber si DDL y BD están sincronizados?
|
|
# → Recrear BD completa y comparar
|
|
|
|
# 1. Backup de BD actual (por seguridad)
|
|
pg_dump gamilit_platform > /tmp/backup-before-recreation.sql
|
|
|
|
# 2. Recrear desde DDL
|
|
./drop-and-recreate-database.sh
|
|
|
|
# 3. Si recreación falla:
|
|
# → DDL y BD NO están sincronizados
|
|
# → Actualizar DDL con cambios faltantes
|
|
# → Volver a intentar recreación
|
|
|
|
# 4. Si recreación funciona:
|
|
# → DDL y BD están sincronizados ✅
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 HERRAMIENTAS Y SCRIPTS
|
|
|
|
### Scripts de Recreación
|
|
|
|
```bash
|
|
apps/database/
|
|
├── 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
|
|
```
|
|
|
|
**Uso principal:**
|
|
```bash
|
|
# Desarrollo diario
|
|
cd apps/database
|
|
./drop-and-recreate-database.sh
|
|
|
|
# Pre-commit
|
|
git add apps/database/ddl/...
|
|
./drop-and-recreate-database.sh && git commit -m "feat(db): ..."
|
|
|
|
# Validar que DDL está completo
|
|
./drop-and-recreate-database.sh && echo "✅ DDL completo"
|
|
```
|
|
|
|
### Script de Validación (Opcional)
|
|
|
|
```bash
|
|
# apps/database/scripts/validate-clean-load-policy.sh
|
|
# Validar cumplimiento de Política de Carga Limpia
|
|
|
|
#!/bin/bash
|
|
echo "🔍 Validando Política de Carga Limpia..."
|
|
|
|
# 1. Verificar que no existe carpeta migrations/
|
|
if [ -d "apps/database/migrations" ]; then
|
|
echo "❌ ERROR: Carpeta migrations/ detectada (PROHIBIDA)"
|
|
exit 1
|
|
fi
|
|
|
|
# 2. Verificar que no hay archivos fix-*.sql o patch-*.sql
|
|
FIXES=$(find apps/database -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 recreación completa funciona
|
|
echo "🔄 Validando recreación completa..."
|
|
./apps/database/drop-and-recreate-database.sh > /tmp/clean-load-test.log 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "❌ ERROR: Recreación completa falló"
|
|
echo "Ver log: /tmp/clean-load-test.log"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ Política de Carga Limpia: CUMPLIDA"
|
|
exit 0
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 EJEMPLOS PRÁCTICOS
|
|
|
|
### Ejemplo 1: Crear Nueva Tabla
|
|
|
|
```sql
|
|
-- ✅ CORRECTO: Crear archivo DDL primero
|
|
-- File: apps/database/ddl/schemas/gamification_system/tables/05-challenges.sql
|
|
|
|
-- ============================================================================
|
|
-- Tabla: challenges
|
|
-- Schema: gamification_system
|
|
-- Descripción: Desafíos y retos del sistema de gamificación
|
|
-- Autor: Database-Agent
|
|
-- Fecha: 2025-11-23
|
|
-- Dependencias: gamification_system.levels
|
|
-- ============================================================================
|
|
|
|
DROP TABLE IF EXISTS gamification_system.challenges CASCADE;
|
|
|
|
CREATE TABLE gamification_system.challenges (
|
|
-- Identificador
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
|
|
-- Datos del desafío
|
|
code VARCHAR(50) NOT NULL UNIQUE,
|
|
name VARCHAR(200) NOT NULL,
|
|
description TEXT,
|
|
difficulty VARCHAR(20) NOT NULL,
|
|
points_reward INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Requisitos
|
|
required_level_id UUID,
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
|
|
-- Constraints
|
|
CONSTRAINT fk_challenges_to_levels
|
|
FOREIGN KEY (required_level_id)
|
|
REFERENCES gamification_system.levels(id)
|
|
ON DELETE SET NULL,
|
|
|
|
CONSTRAINT chk_challenges_difficulty_valid
|
|
CHECK (difficulty IN ('easy', 'medium', 'hard', 'expert')),
|
|
|
|
CONSTRAINT chk_challenges_points_positive
|
|
CHECK (points_reward >= 0)
|
|
);
|
|
|
|
-- Índices
|
|
CREATE INDEX idx_challenges_difficulty ON gamification_system.challenges(difficulty);
|
|
CREATE INDEX idx_challenges_required_level_id ON gamification_system.challenges(required_level_id);
|
|
|
|
-- Comentarios
|
|
COMMENT ON TABLE gamification_system.challenges IS
|
|
'Desafíos del sistema de gamificación que los estudiantes pueden completar para ganar puntos adicionales';
|
|
|
|
COMMENT ON COLUMN gamification_system.challenges.difficulty IS
|
|
'Dificultad del desafío: easy, medium, hard, expert';
|
|
```
|
|
|
|
**Luego validar:**
|
|
```bash
|
|
cd apps/database
|
|
./drop-and-recreate-database.sh
|
|
# Si funciona → commit
|
|
git add apps/database/ddl/schemas/gamification_system/tables/05-challenges.sql
|
|
git commit -m "feat(db): add challenges table to gamification_system"
|
|
```
|
|
|
|
### Ejemplo 2: Modificar Tabla Existente
|
|
|
|
```sql
|
|
-- ✅ CORRECTO: Actualizar DDL existente (NO crear migration)
|
|
-- File: apps/database/ddl/schemas/auth_management/tables/01-users.sql
|
|
|
|
-- Cambio: Agregar columnas para autenticación de dos factores
|
|
|
|
DROP TABLE IF EXISTS auth_management.users CASCADE;
|
|
|
|
CREATE TABLE auth_management.users (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
|
|
-- ← NUEVAS COLUMNAS AGREGADAS
|
|
two_factor_enabled BOOLEAN DEFAULT false,
|
|
two_factor_secret VARCHAR(100),
|
|
backup_codes TEXT[],
|
|
-- ← FIN NUEVAS COLUMNAS
|
|
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
```
|
|
|
|
**Validar:**
|
|
```bash
|
|
./drop-and-recreate-database.sh
|
|
# ✅ Si funciona → DDL correcto, commitear
|
|
# ❌ Si falla → Corregir DDL, no ejecutar ALTER TABLE manual
|
|
```
|
|
|
|
### Ejemplo 3: Corregir Error en Seed
|
|
|
|
```sql
|
|
-- ❌ INCORRECTO: Crear fix-seed-data.sql
|
|
-- apps/database/fix-seed-users.sql
|
|
UPDATE auth_management.users SET role = 'admin' WHERE username = 'admin';
|
|
|
|
-- ✅ CORRECTO: Corregir archivo seed original
|
|
-- apps/database/seeds/dev/auth_management/01-users.sql
|
|
|
|
INSERT INTO auth_management.users (username, email, password_hash, role)
|
|
VALUES
|
|
('admin', 'admin@gamilit.com', '$2b$10$...', 'admin'), -- ← Corregir role aquí
|
|
('teacher1', 'teacher1@gamilit.com', '$2b$10$...', 'teacher'),
|
|
('student1', 'student1@gamilit.com', '$2b$10$...', 'student')
|
|
ON CONFLICT (username) DO NOTHING;
|
|
```
|
|
|
|
**Validar:**
|
|
```bash
|
|
./drop-and-recreate-database.sh
|
|
# Verificar que admin tiene role correcto desde el inicio
|
|
psql -d gamilit_platform -c "SELECT username, role FROM auth_management.users WHERE username = 'admin';"
|
|
```
|
|
|
|
---
|
|
|
|
## 🚨 CASOS ESPECIALES
|
|
|
|
### Caso 1: Migración desde Otro Sistema
|
|
|
|
**Escenario:** Importar datos desde sistema legacy.
|
|
|
|
```markdown
|
|
❌ INCORRECTO:
|
|
1. Crear migration-import-legacy.sql con INSERT masivo
|
|
2. Ejecutar una vez y "olvidar"
|
|
|
|
✅ CORRECTO:
|
|
1. Crear seed en apps/database/seeds/prod/migration/01-import-legacy.sql
|
|
2. Documentar que es importación única con comentarios
|
|
3. Incluir en create-database.sh con flag condicional
|
|
4. Mantener seed para recreaciones futuras (testing)
|
|
```
|
|
|
|
### Caso 2: Datos de Producción
|
|
|
|
**Escenario:** Necesito actualizar datos en producción.
|
|
|
|
```markdown
|
|
❌ INCORRECTO:
|
|
1. Ejecutar UPDATE directo en producción
|
|
2. No actualizar seeds
|
|
|
|
✅ CORRECTO:
|
|
1. Si es dato de configuración:
|
|
└─> Actualizar seed en apps/database/seeds/prod/
|
|
└─> Validar con recreación local
|
|
└─> Aplicar seed en producción
|
|
|
|
2. Si es dato de usuario (transaccional):
|
|
└─> NO va en seeds (datos dinámicos)
|
|
└─> Crear script de actualización documentado
|
|
└─> Ejecutar en producción
|
|
└─> Archivar script como documentación (NO en seeds)
|
|
```
|
|
|
|
### Caso 3: Hotfix en Producción
|
|
|
|
**Escenario:** Bug crítico en producción que requiere cambio urgente en BD.
|
|
|
|
```markdown
|
|
❌ INCORRECTO:
|
|
1. Ejecutar ALTER TABLE directo en producción
|
|
2. "Ya funcionó, documentar después"
|
|
|
|
✅ CORRECTO (incluso en emergencia):
|
|
1. Corregir DDL localmente
|
|
2. Validar con recreación local (rápido: 2-3 min)
|
|
3. Crear ADR documentando el hotfix
|
|
4. Aplicar DDL en producción
|
|
5. Commitear DDL + ADR inmediatamente
|
|
6. Post-mortem: ¿Por qué no se detectó en testing?
|
|
```
|
|
|
|
---
|
|
|
|
## ✅ CHECKLIST DE CUMPLIMIENTO
|
|
|
|
### Para Database-Agent
|
|
|
|
Antes de completar una tarea, verificar:
|
|
|
|
```markdown
|
|
- [ ] Todos los cambios están en archivos DDL (no en BD directamente)
|
|
- [ ] NO se crearon archivos en migrations/
|
|
- [ ] NO se crearon archivos fix-*.sql o patch-*.sql
|
|
- [ ] Recreación completa funciona: ./drop-and-recreate-database.sh
|
|
- [ ] MASTER_INVENTORY.yml actualizado
|
|
- [ ] 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 están en apps/database/ddl/, no en migrations/
|
|
- [ ] NO hay archivos fix-*.sql, patch-*.sql, hotfix-*.sql
|
|
- [ ] DDL sigue estándares (ver DIRECTIVA-DISENO-BASE-DATOS.md)
|
|
- [ ] CI/CD ejecutó recreación completa exitosamente
|
|
- [ ] TRAZA-TAREAS-DATABASE.md documenta el cambio
|
|
```
|
|
|
|
### Para Desarrolladores
|
|
|
|
Al trabajar con base de datos:
|
|
|
|
```markdown
|
|
- [ ] Leí DIRECTIVA-POLITICA-CARGA-LIMPIA.md (este documento)
|
|
- [ ] Entiendo que DDL es fuente de verdad, BD es derivada
|
|
- [ ] Sé que NO debo crear migrations/
|
|
- [ ] Sé que debo actualizar DDL antes de modificar BD
|
|
- [ ] Sé validar con ./drop-and-recreate-database.sh
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 REFERENCIAS
|
|
|
|
### Documentos Relacionados
|
|
|
|
- **[PROMPT-DATABASE-AGENT.md](../prompts/PROMPT-DATABASE-AGENT.md)** - Workflow de Database-Agent
|
|
- **[DIRECTIVA-DISENO-BASE-DATOS.md](DIRECTIVA-DISENO-BASE-DATOS.md)** - Estándares de diseño
|
|
- **[ESTANDARES-NOMENCLATURA.md](ESTANDARES-NOMENCLATURA.md)** - Nomenclatura de objetos DB
|
|
- **[TRAZA-TAREAS-DATABASE.md](../trazas/TRAZA-TAREAS-DATABASE.md)** - Historial de cambios
|
|
|
|
### Scripts Importantes
|
|
|
|
```bash
|
|
apps/database/
|
|
├── create-database.sh # Crear BD desde DDL
|
|
├── drop-and-recreate-database.sh # Recreación completa (carga limpia)
|
|
└── reset-database.sh # Reset a estado inicial
|
|
```
|
|
|
|
### Estructura de Archivos DDL
|
|
|
|
```bash
|
|
apps/database/ddl/
|
|
├── 00-prerequisites.sql # Extensions, configuración
|
|
└── schemas/
|
|
├── auth_management/
|
|
│ ├── 00-schema.sql
|
|
│ ├── tables/
|
|
│ │ ├── 01-users.sql
|
|
│ │ └── 02-roles.sql
|
|
│ ├── functions/
|
|
│ └── policies/
|
|
├── gamification_system/
|
|
│ └── ...
|
|
└── educational_content/
|
|
└── ...
|
|
```
|
|
|
|
---
|
|
|
|
## 🎓 BENEFICIOS DE ESTA POLÍTICA
|
|
|
|
### Técnicos
|
|
|
|
1. ✅ **Reproducibilidad:** BD puede recrearse en cualquier momento, en cualquier ambiente
|
|
2. ✅ **Simplicidad:** Un script (drop-and-recreate), un resultado (BD completa)
|
|
3. ✅ **Debugging:** Error en recreación = DDL tiene problema (fácil 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 rápido y confiable
|
|
2. ✅ **Ambientes:** Dev, Staging, Prod tienen misma estructura (desde mismo DDL)
|
|
3. ✅ **Auditoría:** 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 dónde están los cambios (DDL)
|
|
2. ✅ **Colaboración:** Conflictos en DDL son fáciles de resolver (Git)
|
|
3. ✅ **Documentación:** DDL es documentación ejecutable y siempre actualizada
|
|
4. ✅ **Confianza:** Cambios validados con recreación = alta confianza
|
|
5. ✅ **Velocidad:** No hay "estado misterioso" de BD, siempre es predecible
|
|
|
|
---
|
|
|
|
## ⚖️ CONTRASTE: Carga Limpia vs Migrations
|
|
|
|
| Aspecto | Migrations Incrementales | Carga Limpia (Este Proyecto) |
|
|
|---------|-------------------------|------------------------------|
|
|
| **Fuente de verdad** | Estado de BD + Migrations históricas | Archivos DDL actuales |
|
|
| **Recreación** | Ejecutar todas las migrations en orden | Un script: drop-and-recreate |
|
|
| **Debugging** | Difícil (¿cuál migration falló?) | Fácil (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** | Difícil (estado previo incierto) | Simple (siempre BD limpia) |
|
|
| **Producción** | Riesgoso (migration puede fallar) | Confiable (validado en recreación) |
|
|
|
|
**Cuándo usar migrations:** Proyectos con datos de producción que NO pueden perderse (ej: e-commerce, banking).
|
|
|
|
**Cuándo usar carga limpia:** Proyectos educativos, startups, MVPs, sistemas donde BD puede recrearse (como GAMILIT).
|
|
|
|
---
|
|
|
|
**Versión:** 1.0.0
|
|
**Fecha:** 2025-11-23
|
|
**Próxima revisión:** Trimestral o al identificar necesidad
|
|
**Responsable:** Database-Agent + Tech Lead
|
|
**Aprobado por:** Tech Lead
|
|
|
|
---
|
|
|
|
**NOTA IMPORTANTE:**
|
|
|
|
Esta política formaliza la práctica que ya se viene aplicando exitosamente en GAMILIT. El objetivo es documentarla para prevenir desviaciones futuras y facilitar el onboarding de nuevos desarrolladores.
|
|
|
|
**Evidencia de cumplimiento histórico:**
|
|
- ✅ 45+ menciones a "Política de Carga Limpia" en `TRAZA-TAREAS-DATABASE.md`
|
|
- ✅ 0 migrations creadas en historial del proyecto
|
|
- ✅ Scripts de recreación completa (`drop-and-recreate-database.sh`) funcionando desde inicio
|
|
- ✅ 100% de cambios en BD documentados en archivos DDL
|