03. Modelo de Datos (ERD)
DATA-03 / POSTGRESQL_RELATIONAL_SCHEMA / MULTI-TENANT BY TENANT_ID

Esquema de Base de Datos y Diagrama Entidad-Relación

Modelo relacional PostgreSQL con aislamiento lógico multi-tenant, llaves primarias UUID, indexación optimizada y columnas dedicadas de mapeo para desacoplar IDs de proveedores externos.

Diagrama Entidad-Relación Completo

Relaciones de cardinalidad entre Tenants, Líneas, Plantillas, Campañas y Eventos

100%
PostgreSQL
erDiagram TENANTS ||--o{ USERS : "posee" TENANTS ||--o{ API_KEYS : "autentica" TENANTS ||--o{ PHONE_NUMBERS : "administra" TENANTS ||--o{ TEMPLATES : "posee" TENANTS ||--o{ CAMPAIGNS : "ejecuta" PHONE_NUMBERS ||--o{ CAMPAIGNS : "origina" PHONE_NUMBERS ||--o{ MESSAGES : "envia" TEMPLATES ||--o{ CAMPAIGNS : "usa" CAMPAIGNS ||--o{ MESSAGES : "agrupa" MESSAGES ||--o{ MESSAGE_EVENTS : "dispara" TENANTS { uuid id PK varchar name varchar slug varchar status varchar provider_customer_id timestamp created_at timestamp updated_at } USERS { uuid id PK uuid tenant_id FK varchar email varchar password_hash varchar role varchar full_name timestamp created_at } API_KEYS { uuid id PK uuid tenant_id FK varchar name varchar key_prefix varchar key_hash timestamp last_used_at timestamp created_at } PHONE_NUMBERS { uuid id PK uuid tenant_id FK varchar e164_number varchar display_name varchar waba_id varchar meta_phone_number_id varchar provider varchar provider_phone_id varchar status timestamp created_at } TEMPLATES { uuid id PK uuid tenant_id FK varchar name varchar language varchar category varchar status jsonb components varchar provider_template_id timestamp synced_at } CAMPAIGNS { uuid id PK uuid tenant_id FK uuid phone_number_id FK uuid template_id FK varchar name varchar status timestamp scheduled_at timestamp executed_at varchar provider_broadcast_id int total_recipients int delivered_count timestamp created_at } MESSAGES { uuid id PK uuid tenant_id FK uuid campaign_id FK uuid phone_number_id FK varchar recipient_phone varchar status varchar provider varchar provider_message_id jsonb variables timestamp created_at timestamp delivered_at timestamp read_at } MESSAGE_EVENTS { uuid id PK uuid message_id FK varchar event_type varchar error_code varchar error_message jsonb raw_payload timestamp occurred_at }

Especificación Estructural de Tablas

1 Tabla tenants (Empresas / Organizaciones)

Columna Tipo Restricción Descripción de Negocio
id UUID PRIMARY KEY Identificador único de la empresa en Innovia.
name VARCHAR(120) NOT NULL Razón social o nombre comercial.
slug VARCHAR(80) UNIQUE NOT NULL Identificador alfanumérico para subdominios o URLs.
provider_customer_id VARCHAR(100) NULLABLE Mapping del Customer en Kapso (kps_cus_...).
status VARCHAR(30) DEFAULT 'ACTIVE' ACTIVE, SUSPENDED, TRIAL.

2 Tabla phone_numbers (Líneas WhatsApp Conectadas)

Columna Tipo Restricción Descripción de Negocio
id UUID PRIMARY KEY ID propio de la línea en Innovia.
tenant_id UUID FK -> tenants.id Aislamiento por cliente.
e164_number VARCHAR(20) NOT NULL Número en formato internacional (+56912345678).
provider VARCHAR(30) DEFAULT 'kapso' Proveedor que gestiona la línea ('kapso', 'gupshup', etc.).
provider_phone_id VARCHAR(100) NULLABLE ID técnico de la línea en Kapso.
status VARCHAR(30) DEFAULT 'PENDING' PENDING, CONNECTED, DISCONNECTED, RESTRICTED.

Esquema Relacional & Migraciones DDL

El script SQL completo ha sido consolidado en la documentación técnica interna

Ver Script DDL SQL en MD
Llaves Primarias UUIDv4

Uso de `uuid_generate_v4()` para evitar enumeración y facilitar sincronizaciones distribuidas.

Índices de Aislamiento

Índices en `tenant_id` en todas las tablas para búsquedas sub-milisegundo multi-tenant.

Campos de Mapeo Desacoplados

`provider_phone_id`, `provider_broadcast_id` y `provider_message_id` para aislar Kapso.