workspace-v1/control-plane/orchestration/directivas/simco/SIMCO-DDL.md
Adrian Flores Cortes 967ab360bb Initial commit: Workspace v1 with 3-layer architecture
Structure:
- control-plane/: Registries, SIMCO directives, CI/CD templates
- projects/: Gamilit, ERP-Suite, Trading-Platform, Betting-Analytics
- shared/: Libs catalog, knowledge-base

Key features:
- Centralized port, domain, database, and service registries
- 23 SIMCO directives + 6 fundamental principles
- NEXUS agent profiles with delegation rules
- Validation scripts for workspace integrity
- Dockerfiles for all services
- Path aliases for quick reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 00:35:19 -06:00

14 KiB

SIMCO: OPERACIONES DDL (Database)

Versión: 1.0.0 Fecha: 2025-12-08 Aplica a: Todo agente que trabaje con base de datos PostgreSQL Prioridad: OBLIGATORIA para operaciones de BD


RESUMEN EJECUTIVO

DDL-First: Los archivos DDL son la fuente de verdad. La BD es el resultado de ejecutarlos.


PRINCIPIO FUNDAMENTAL

╔══════════════════════════════════════════════════════════════════════╗
║  POLÍTICA DE CARGA LIMPIA                                            ║
║                                                                       ║
║  1. TODO cambio de BD = modificar archivo DDL                        ║
║  2. NUNCA ejecutar ALTER/CREATE directo en BD                        ║
║  3. SIEMPRE validar con recreación completa                          ║
║  4. La BD debe poder recrearse 100% desde DDL                        ║
╚══════════════════════════════════════════════════════════════════════╝

FLUJO DDL-FIRST

1. CREAR/MODIFICAR ARCHIVO DDL
         │
         ▼
2. EJECUTAR CARGA LIMPIA COMPLETA
   cd @DB_SCRIPTS && ./{RECREATE_CMD}
         │
         ▼
3. ¿PASA SIN ERRORES?
   ├── SÍ → Continuar a paso 4
   └── NO → Volver a paso 1 (corregir DDL)
         │
         ▼
4. VALIDAR ESTRUCTURA
   \dt, \di, \d tabla
         │
         ▼
5. COMMIT ARCHIVO DDL

ESTRUCTURA DE ARCHIVOS DDL

{DB_DDL_PATH}/
├── 00-init.sql                          # Extensiones, tipos base
└── schemas/
    ├── {schema_1}/
    │   ├── 00-schema.sql                # CREATE SCHEMA
    │   ├── tables/
    │   │   ├── 01-{tabla}.sql           # Tablas en orden de dependencia
    │   │   └── 02-{tabla}.sql
    │   ├── functions/
    │   │   └── {funcion}.sql
    │   └── triggers/
    │       └── trg_{tabla}_{accion}.sql
    └── {schema_2}/
        └── ...

{DB_SEEDS_PATH}/
├── dev/                                 # Seeds para desarrollo
│   ├── 01-{nombre}.sql
│   └── 02-{nombre}.sql
└── prod/                                # Seeds para producción
    └── 01-{nombre}.sql

CONVENCIONES DE NOMENCLATURA

Schemas

-- snake_case
CREATE SCHEMA auth_management;
CREATE SCHEMA gamification_system;
CREATE SCHEMA project_management;

Tablas

-- snake_case, plural
CREATE TABLE users;
CREATE TABLE student_progress;
CREATE TABLE badge_awards;

Columnas

-- snake_case
user_id UUID
first_name VARCHAR(100)
created_at TIMESTAMP
is_active BOOLEAN

Índices

-- idx_{tabla}_{columna(s)}
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status_created ON users(status, created_at);
CREATE UNIQUE INDEX idx_users_username ON users(username);

Foreign Keys

-- fk_{tabla}_to_{tabla_referenciada}
CONSTRAINT fk_students_to_users
    FOREIGN KEY (user_id)
    REFERENCES auth_management.users(id)

Check Constraints

-- chk_{tabla}_{columna}
CONSTRAINT chk_users_status
    CHECK (status IN ('active', 'inactive', 'suspended'))

Triggers

-- trg_{tabla}_{accion}
CREATE TRIGGER trg_users_updated
    BEFORE UPDATE ON users
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

Functions

-- snake_case con verbo
CREATE FUNCTION calculate_user_level()
CREATE FUNCTION award_badge_to_user()
CREATE FUNCTION update_updated_at_column()

TEMPLATE DE ARCHIVO DDL

-- ============================================================================
-- Tabla: {nombre_tabla}
-- Schema: {schema}
-- Descripción: {descripción breve de la tabla y su propósito}
-- Autor: {Agente}
-- Fecha: {YYYY-MM-DD}
-- Dependencias: {lista de tablas de las que depende o "Ninguna"}
-- ============================================================================

-- Eliminar si existe (solo desarrollo)
DROP TABLE IF EXISTS {schema}.{tabla} CASCADE;

-- ============================================================================
-- CREAR TABLA
-- ============================================================================
CREATE TABLE {schema}.{tabla} (
    -- ─────────────────────────────────────────────────────────────────────
    -- Identificador
    -- ─────────────────────────────────────────────────────────────────────
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    -- ─────────────────────────────────────────────────────────────────────
    -- Campos de Negocio
    -- ─────────────────────────────────────────────────────────────────────
    {campo_1} {TIPO} {NOT NULL} {DEFAULT},
    {campo_2} {TIPO} {NOT NULL} {DEFAULT},

    -- ─────────────────────────────────────────────────────────────────────
    -- Referencias (Foreign Keys inline o al final)
    -- ─────────────────────────────────────────────────────────────────────
    {fk_campo} UUID,

    -- ─────────────────────────────────────────────────────────────────────
    -- Auditoría
    -- ─────────────────────────────────────────────────────────────────────
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_by UUID,

    -- ─────────────────────────────────────────────────────────────────────
    -- Constraints
    -- ─────────────────────────────────────────────────────────────────────
    CONSTRAINT fk_{tabla}_to_{ref}
        FOREIGN KEY ({fk_campo})
        REFERENCES {schema_ref}.{tabla_ref}(id)
        ON DELETE {CASCADE|SET NULL|RESTRICT},

    CONSTRAINT chk_{tabla}_{campo}
        CHECK ({condicion})
);

-- ============================================================================
-- COMENTARIOS
-- ============================================================================
COMMENT ON TABLE {schema}.{tabla} IS
    '{Descripción de la tabla}';

COMMENT ON COLUMN {schema}.{tabla}.{campo_1} IS
    '{Descripción del campo, valores válidos, restricciones}';

COMMENT ON COLUMN {schema}.{tabla}.{campo_2} IS
    '{Descripción del campo}';

-- ============================================================================
-- ÍNDICES
-- ============================================================================

-- Índice para búsqueda por {criterio}
CREATE INDEX idx_{tabla}_{campo}
    ON {schema}.{tabla}({campo});

-- Índice único para {criterio}
CREATE UNIQUE INDEX idx_{tabla}_{campo}_unique
    ON {schema}.{tabla}({campo});

-- Índice compuesto para {criterio}
CREATE INDEX idx_{tabla}_{campo1}_{campo2}
    ON {schema}.{tabla}({campo1}, {campo2});

-- ============================================================================
-- TRIGGER DE AUDITORÍA
-- ============================================================================
CREATE TRIGGER trg_{tabla}_updated
    BEFORE UPDATE ON {schema}.{tabla}
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- ============================================================================
-- ROW LEVEL SECURITY (si aplica)
-- ============================================================================
ALTER TABLE {schema}.{tabla} ENABLE ROW LEVEL SECURITY;

CREATE POLICY {tabla}_select_policy
    ON {schema}.{tabla}
    FOR SELECT
    USING ({condicion_rls});

CREATE POLICY {tabla}_insert_policy
    ON {schema}.{tabla}
    FOR INSERT
    WITH CHECK ({condicion_rls});

-- ============================================================================
-- FIN DE ARCHIVO
-- ============================================================================

COMANDOS DE VALIDACIÓN

Carga Limpia (OBLIGATORIO)

cd @DB_SCRIPTS
./{RECREATE_CMD}
# DEBE completar sin errores

Verificar Estructura

# Listar schemas
psql -d {DB_NAME} -c "\dn"

# Listar tablas de un schema
psql -d {DB_NAME} -c "\dt {schema}.*"

# Ver estructura de tabla
psql -d {DB_NAME} -c "\d {schema}.{tabla}"

# Ver índices
psql -d {DB_NAME} -c "\di {schema}.*"

# Ver constraints
psql -d {DB_NAME} -c "\d+ {schema}.{tabla}"

Verificar Comentarios

# Ver comentario de tabla
psql -d {DB_NAME} -c "
SELECT obj_description('{schema}.{tabla}'::regclass);
"

# Ver comentarios de columnas
psql -d {DB_NAME} -c "
SELECT column_name, col_description('{schema}.{tabla}'::regclass, ordinal_position)
FROM information_schema.columns
WHERE table_schema = '{schema}' AND table_name = '{tabla}';
"

Tests Básicos

# Insert de prueba
psql -d {DB_NAME} -c "
INSERT INTO {schema}.{tabla} ({columnas})
VALUES ({valores});
"

# Verificar constraint CHECK
psql -d {DB_NAME} -c "
INSERT INTO {schema}.{tabla} ({columna})
VALUES ('valor_invalido');
"
# Debe fallar con error de constraint

# Verificar FK
psql -d {DB_NAME} -c "
INSERT INTO {schema}.{tabla} ({fk_columna})
VALUES ('uuid-no-existente');
"
# Debe fallar con error de FK

PROHIBICIONES

╔══════════════════════════════════════════════════════════════════════╗
║  ❌ PROHIBIDO                                                        ║
╠══════════════════════════════════════════════════════════════════════╣
║                                                                       ║
║  • Ejecutar ALTER TABLE directo en BD sin actualizar DDL             ║
║  • Crear carpeta migrations/                                         ║
║  • Crear archivos fix-*.sql o patch-*.sql                            ║
║  • Crear archivos migration-*.sql                                    ║
║  • Dejar BD y DDL desincronizados                                    ║
║  • Ejecutar psql -c "CREATE/ALTER..." sin archivo DDL                ║
║  • Marcar tarea completa sin carga limpia exitosa                    ║
║                                                                       ║
╚══════════════════════════════════════════════════════════════════════╝

MODIFICAR TABLA EXISTENTE

Proceso Correcto

# 1. Editar archivo DDL existente (NO crear migration)
vim @DDL/{schema}/tables/{NN}-{tabla}.sql

# 2. Agregar/modificar columna en CREATE TABLE
# (NO usar ALTER TABLE como cambio principal)

# 3. Ejecutar carga limpia completa
cd @DB_SCRIPTS
./{RECREATE_CMD}

# 4. Verificar cambios
psql -d {DB_NAME} -c "\d {schema}.{tabla}"

# 5. Commit cambios
git add @DDL/{schema}/tables/{NN}-{tabla}.sql
git commit -m "feat(db): add column to {tabla}"

Proceso INCORRECTO

# ❌ NO hacer esto
psql -d {DB_NAME} -c "ALTER TABLE {schema}.{tabla} ADD COLUMN..."

# ❌ NO crear migration
echo "ALTER TABLE..." > migrations/002-add-column.sql

# ❌ NO crear fix temporal
echo "ALTER TABLE..." > fix-add-column.sql

CHECKLIST DDL

ANTES DE CREAR
├── [ ] Verificar que tabla no existe (@INVENTORY, grep)
├── [ ] Verificar schema existe (00-schema.sql)
├── [ ] Identificar dependencias (FKs a otras tablas)
├── [ ] Determinar número de archivo (secuencial)
└── [ ] Leer tabla similar como referencia

DURANTE CREACIÓN
├── [ ] Encabezado completo (descripción, autor, fecha, deps)
├── [ ] Columnas con tipos correctos
├── [ ] Campos de auditoría (created_at, updated_at)
├── [ ] Constraints nombrados correctamente
├── [ ] Índices necesarios
├── [ ] COMMENT ON para tabla y columnas importantes
└── [ ] Trigger de updated_at (si aplica)

VALIDACIÓN
├── [ ] Carga limpia exitosa
├── [ ] Estructura verificada (\d tabla)
├── [ ] Índices verificados (\di)
├── [ ] Insert de prueba exitoso
├── [ ] Constraints funcionan (test de validación)
└── [ ] Comentarios presentes

DOCUMENTACIÓN
├── [ ] @INVENTORY actualizado
├── [ ] @TRAZA_DB actualizada
└── [ ] Entity correspondiente identificada para Backend

ERRORES COMUNES

Error Causa Solución
FK falla Tabla referenciada no existe Verificar orden de creación
Tipo incorrecto No alineado con diseño Consultar especificación
Sin comentarios Olvidó COMMENT ON Template incluye comentarios
Sin índices No pensó en queries Agregar para columnas de búsqueda
Carga limpia falla DDL con errores Corregir DDL, no fix manual

REFERENCIAS

  • Crear archivos: @CREAR (SIMCO-CREAR.md)
  • Validar: @VALIDAR (SIMCO-VALIDAR.md)
  • Documentar: @DOCUMENTAR (SIMCO-DOCUMENTAR.md)
  • Política carga limpia: @DIRECTIVAS/DIRECTIVA-POLITICA-CARGA-LIMPIA.md
  • Diseño de BD: @DIRECTIVAS/DIRECTIVA-DISENO-BASE-DATOS.md
  • Nomenclatura: @DIRECTIVAS/ESTANDARES-NOMENCLATURA-BASE.md

Versión: 1.0.0 | Sistema: SIMCO | Mantenido por: Tech Lead