> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Schemas — el modelo de datos, tabla por tabla

> Una página por tabla con sus atributos, referencias, restricciones y su propio registro de cambios. Es lo que Drizzle necesita para modelar y lo que las APIs necesitan para no inventar.

Las specs de módulo dicen **qué existe y por qué**. Esta sección dice **cómo está construido**: cada
tabla con sus columnas, sus tipos, sus referencias cruzadas, sus restricciones y la fecha de cada
decisión que la cambió.

Existe porque son dos audiencias distintas con dos preguntas distintas. Quien escribe una feature
spec pregunta "¿de quién es este dato?". Quien escribe la migración de Drizzle o el endpoint
pregunta "¿de qué tipo es, admite nulo, a qué apunta y qué pasa si borro el padre?". Mezclar ambas
en un solo documento hizo que la segunda nunca se escribiera del todo.

## Cómo leer una página de schema

Cada página abre declarando la **forma** de la tabla ([ADR-024](/adr/adr-024-table-naming-and-base-structure)),
porque la forma determina qué columnas tiene sin que nadie las elija:

| Forma               | Qué es                                                                                              | Columnas base                                                                                         |
| ------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **A · dominio**     | El caso por defecto. Entidad con alcance de tenant que se crea, se actualiza y se borra lógicamente | `id`, `tenant_id`, `cell_id`, `created_at`, `updated_at`, `deleted_at`                                |
| **B · append-only** | Ledger, eventos, auditoría, medición, outbox. Se escribe y no se toca más                           | `id`, `tenant_id`, `cell_id`, una columna de tiempo del dominio. **Sin** `updated_at` ni `deleted_at` |
| **C · catálogo**    | Conjunto cerrado de valores de negocio, en vez de un enum de Postgres                               | `code` TEXT PK, `label`, `is_system`, `is_active`, `sort_order`, `metadata`                           |

Las columnas base aparecen marcadas como `base` y no se repiten con explicación en cada página: su
significado está fijado por el estándar, no por la tabla. Lo que cada página describe en detalle es
lo propio — los atributos específicos, las claves foráneas y las restricciones.

## Qué lleva cada página

1. **Clave primaria** — qué es y cómo se genera.
2. **Atributos específicos** — tipo, obligatoriedad, default, reglas de validación.
3. **Claves foráneas** — a qué tabla apuntan, con enlace, y qué pasa al borrar el padre.
4. **Atributos base** — los que vienen de la forma, marcados `base`.
5. **Restricciones e índices** — unicidad (siempre con `tenant_id`), checks, índices que existen por
   una consulta concreta que está escrita.
6. **RLS y particionamiento** — la política de tenant y, si aplica, la clave de partición.
7. **Registro de cambios** — cada cambio con su fecha, su motivo y el FS o ADR que lo decidió.

Ese último punto es el que hace útil la sección con el tiempo. Una columna que aparece sin
explicación seis meses después es una columna que nadie se atreve a borrar.

## Reglas que no se repiten en cada página

Están en [`standards/data.md`](/standards/data) y aplican siempre:

* **Toda unicidad incluye `tenant_id`** (§2b). Doña María es dos personas distintas si es clienta de
  dos empresas.
* **`created_by` / `updated_by` están prohibidos** (ADR-024). El actor vive en `core.audit_log` con
  el diff completo.
* **Nunca un enum de Postgres** para un valor de negocio (§2): va a un catálogo forma C.
* **Nunca un monto sin su moneda** (§3), y los puntos no son dinero.
* **FK entre schemas solo hacia `core`** (§1). `identity` no tiene ninguna.

## Estado

La sección se construye módulo por módulo, en el mismo orden en que se aprueban las specs. Una tabla
sin página de schema es una tabla que no se puede implementar: el validador `schemas` lo reporta.
