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