# DDL-SPEC-{schema_name}: Especificacion de Schema > **INSTRUCCIONES:** Copiar este template para cada schema nuevo. > Eliminar esta seccion antes de guardar. --- ## Metadatos | Campo | Valor | |-------|-------| | **Schema** | `{schema_name}` | | **Modulo** | {MGN-NNN / MAI-NNN} | | **Estado** | {Borrador / Aprobado / Implementado} | | **Version** | 1.0.0 | | **Autor** | {nombre} | | **Fecha** | {YYYY-MM-DD} | --- ## Resumen | Metrica | Cantidad | |---------|----------| | Tablas | {N} | | Vistas | {N} | | Funciones | {N} | | Triggers | {N} | | Indices | {N} | | RLS Policies | {N} | --- ## Diagrama ER ```mermaid erDiagram %% Ejemplo - reemplazar con diagrama real TABLA_PRINCIPAL ||--o{ TABLA_DETALLE : tiene TABLA_PRINCIPAL ||--|| TABLA_CONFIG : configura TABLA_PRINCIPAL { uuid id PK uuid tenant_id FK varchar nombre timestamp created_at timestamp updated_at } TABLA_DETALLE { uuid id PK uuid principal_id FK varchar descripcion decimal cantidad } ``` --- ## Tablas ### {nombre_tabla_1} **Proposito:** {Descripcion breve del proposito de la tabla} **DDL Path:** `database/ddl/schemas/{schema}/tables/{NN}-{nombre}.sql` #### Columnas | Columna | Tipo | Nullable | Default | Descripcion | |---------|------|----------|---------|-------------| | `id` | UUID | NOT NULL | `gen_random_uuid()` | Primary Key | | `tenant_id` | UUID | NOT NULL | - | FK a tenants (multi-tenant) | | `{columna}` | {tipo} | {NULL/NOT NULL} | {default} | {descripcion} | | `created_at` | TIMESTAMPTZ | NOT NULL | `NOW()` | Fecha creacion | | `updated_at` | TIMESTAMPTZ | NOT NULL | `NOW()` | Fecha actualizacion | | `created_by` | UUID | NULL | - | Usuario que creo | | `updated_by` | UUID | NULL | - | Usuario que actualizo | | `is_active` | BOOLEAN | NOT NULL | `TRUE` | Soft delete | #### Constraints | Tipo | Nombre | Definicion | |------|--------|------------| | PK | `pk_{tabla}` | `PRIMARY KEY (id)` | | FK | `fk_{tabla}_tenant` | `FOREIGN KEY (tenant_id) REFERENCES core_system.tenants(id)` | | FK | `fk_{tabla}_{ref}` | `FOREIGN KEY ({col}) REFERENCES {schema}.{tabla}(id)` | | UQ | `uq_{tabla}_{cols}` | `UNIQUE (tenant_id, {columna})` | | CHK | `chk_{tabla}_{regla}` | `CHECK ({condicion})` | #### Indices | Nombre | Columnas | Tipo | Proposito | |--------|----------|------|-----------| | `idx_{tabla}_tenant` | `(tenant_id)` | BTREE | Filtro multi-tenant | | `idx_{tabla}_{col}` | `({columna})` | BTREE | Busqueda por {col} | | `idx_{tabla}_search` | `({cols})` | GIN/GIST | Busqueda full-text | #### Triggers | Nombre | Evento | Funcion | Proposito | |--------|--------|---------|-----------| | `trg_{tabla}_updated_at` | BEFORE UPDATE | `core_system.update_timestamp()` | Actualizar updated_at | | `trg_{tabla}_audit` | AFTER INSERT/UPDATE/DELETE | `audit_logging.log_change()` | Auditoria | #### RLS Policies | Nombre | Operacion | Definicion | |--------|-----------|------------| | `tenant_isolation_{tabla}` | ALL | `tenant_id = current_setting('app.tenant_id')::uuid` | | `{policy_name}` | {SELECT/INSERT/UPDATE/DELETE} | `{condicion}` | #### SQL de Creacion ```sql -- Schema: {schema_name} -- Tabla: {nombre_tabla} -- Modulo: {MGN-NNN} CREATE TABLE {schema_name}.{nombre_tabla} ( -- Primary Key id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Multi-tenant (OBLIGATORIO) tenant_id UUID NOT NULL REFERENCES core_system.tenants(id), -- Columnas de negocio {columna} {TIPO} {NOT NULL} {DEFAULT}, -- Auditoria (OBLIGATORIO) created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_by UUID REFERENCES core_auth.users(id), updated_by UUID REFERENCES core_auth.users(id), is_active BOOLEAN NOT NULL DEFAULT TRUE ); -- Comentarios COMMENT ON TABLE {schema_name}.{nombre_tabla} IS '{Descripcion de la tabla}'; COMMENT ON COLUMN {schema_name}.{nombre_tabla}.{columna} IS '{Descripcion columna}'; -- Indices CREATE INDEX idx_{tabla}_tenant ON {schema_name}.{nombre_tabla}(tenant_id); CREATE INDEX idx_{tabla}_{col} ON {schema_name}.{nombre_tabla}({columna}); -- Unique constraints ALTER TABLE {schema_name}.{nombre_tabla} ADD CONSTRAINT uq_{tabla}_{cols} UNIQUE (tenant_id, {columna}); -- Trigger updated_at CREATE TRIGGER trg_{tabla}_updated_at BEFORE UPDATE ON {schema_name}.{nombre_tabla} FOR EACH ROW EXECUTE FUNCTION core_system.update_timestamp(); -- RLS ALTER TABLE {schema_name}.{nombre_tabla} ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_{tabla} ON {schema_name}.{nombre_tabla} USING (tenant_id = current_setting('app.tenant_id')::uuid); ``` --- ### {nombre_tabla_2} > Repetir la estructura anterior para cada tabla --- ## Vistas ### v_{nombre_vista} **Proposito:** {Descripcion} ```sql CREATE OR REPLACE VIEW {schema_name}.v_{nombre} AS SELECT t1.id, t1.nombre, t2.descripcion FROM {schema_name}.{tabla1} t1 JOIN {schema_name}.{tabla2} t2 ON t1.id = t2.{fk} WHERE t1.is_active = TRUE; ``` --- ## Funciones ### {nombre_funcion} **Proposito:** {Descripcion} **Parametros:** | Nombre | Tipo | Descripcion | |--------|------|-------------| | `p_{param}` | {tipo} | {descripcion} | **Retorna:** {tipo} ```sql CREATE OR REPLACE FUNCTION {schema_name}.{nombre_funcion}( p_param1 UUID, p_param2 VARCHAR ) RETURNS {tipo} AS $$ DECLARE v_result {tipo}; BEGIN -- Logica RETURN v_result; END; $$ LANGUAGE plpgsql; ``` --- ## Datos Iniciales (Seeds) ### Catalogos Base ```sql -- Seeds para {schema_name} -- Ejecutar despues de crear tablas INSERT INTO {schema_name}.{tabla} (id, tenant_id, {columnas}) VALUES ('uuid-fijo-1', 'tenant-default', {valores}), ('uuid-fijo-2', 'tenant-default', {valores}); ``` > **Nota:** Usar UUIDs fijos para datos de referencia (catalogos) --- ## Dependencias ### Schemas Requeridos | Schema | Proposito | |--------|-----------| | `core_system` | Tenants, sequences | | `core_auth` | Users (para FK created_by/updated_by) | ### Funciones Requeridas | Funcion | Schema | Proposito | |---------|--------|-----------| | `update_timestamp()` | `core_system` | Trigger updated_at | | `log_change()` | `audit_logging` | Auditoria | --- ## Orden de Ejecucion 1. `00-schema.sql` - Crear schema 2. `01-{tabla_principal}.sql` - Tabla sin FK a otras del schema 3. `02-{tabla_dependiente}.sql` - Tablas con FK 4. `10-functions.sql` - Funciones 5. `20-views.sql` - Vistas 6. `30-triggers.sql` - Triggers adicionales 7. `90-seeds.sql` - Datos iniciales --- ## Validaciones Pre-Implementacion - [ ] Diagrama ER revisado - [ ] Todas las tablas tienen tenant_id - [ ] Columnas de auditoria presentes - [ ] Indices definidos para consultas frecuentes - [ ] RLS policies definidas - [ ] Triggers de auditoria configurados - [ ] Seeds con UUIDs fijos - [ ] Comentarios en tablas y columnas criticas --- ## Referencias | Documento | Path | |-----------|------| | Directiva BD | `core/orchestration/directivas/DIRECTIVA-DISENO-BASE-DATOS.md` | | Patrones Odoo | `erp-core/orchestration/directivas/DIRECTIVA-PATRONES-ODOO.md` | | Requerimiento | `docs/01-requerimientos/RF-{modulo}/` | --- ## Historial | Version | Fecha | Autor | Cambios | |---------|-------|-------|---------| | 1.0 | {YYYY-MM-DD} | {nombre} | Creacion inicial | --- *Template version 1.0 - ERP Suite*