erp-core/orchestration/templates/TEMPLATE-DDL-SPECIFICATION.md

298 lines
7.2 KiB
Markdown

# 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*