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
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.