Tablas del CDP - Documentación Completa
📋 Resumen de Tablas
Total: 40+ tablas organizadas en 4 categorías
| Categoría | Tablas | Propósito |
|---|---|---|
| Core | 10 | Gestión básica de tenants, usuarios y clientes |
| Analytics | 15 | Análisis RFM, CLV, churn y BI |
| Integrations | 8 | Sincronización con sistemas externos |
| Processing | 7 | Gestión de ETL y trabajos en background |
🏗️ Core Tables (10)
1. tenants
Propósito: Gestión de organizaciones/marcas en el sistema multi-tenant.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK, identificador único | 56 |
| name | VARCHAR(255) | Nombre comercial | "Chelsea" |
| slug | VARCHAR(100) | URL-friendly identifier | "chelsea" |
| type | VARCHAR(50) | Tipo de tenant | "enterprise" |
| status | VARCHAR(50) | Estado actual | "active" |
| settings | JSONB | Configuración específica | {"currency": "ARS"} |
| created_at | TIMESTAMP | Fecha de creación | |
| updated_at | TIMESTAMP | Última modificación |
Índices:
PRIMARY KEY (id)UNIQUE INDEX (slug)
Constraints:
CHECK (type IN ('trial', 'business', 'enterprise'))CHECK (status IN ('active', 'suspended', 'terminated'))
2. users
Propósito: Usuarios del sistema CDP (administradores, analistas, etc.).
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK, identificador único | 123 |
| VARCHAR(255) | Email de login | "admin@nerdistan.com" | |
| password_hash | VARCHAR(255) | Hash de contraseña | |
| first_name | VARCHAR(255) | Nombre | "Miguel" |
| last_name | VARCHAR(255) | Apellido | "Hernandez" |
| role | VARCHAR(50) | Rol del usuario | "admin" |
| is_active | BOOLEAN | Estado del usuario | true |
| last_login | TIMESTAMP | Último acceso | |
| created_at | TIMESTAMP | Fecha de creación |
Roles disponibles: admin, analyst, marketing_manager, readonly
3. tenant_users
Propósito: Relación many-to-many entre usuarios y tenants.
| Campo | Tipo | Descripción |
|---|---|---|
| id | SERIAL | PK |
| tenant_id | INTEGER | FK a tenants |
| user_id | INTEGER | FK a users |
| role | VARCHAR(50) | Rol específico en el tenant |
| permissions | JSONB | Permisos granulares |
| created_at | TIMESTAMP | Fecha de asignación |
4. customers
Propósito: Perfiles centralizados de clientes con deduplicación.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK, identificador único | 12345 |
| tenant_id | INTEGER | FK a tenants | 56 |
| external_id | VARCHAR(255) | ID en sistema origen | "vtex_user_123" |
| VARCHAR(255) | Email principal | "cliente@example.com" | |
| phone | VARCHAR(50) | Teléfono | "+5491123456789" |
| first_name | VARCHAR(255) | Nombre | "Juan" |
| last_name | VARCHAR(255) | Apellido | "Pérez" |
| document_number | VARCHAR(50) | DNI/CUIT | "12345678" |
| document_type | VARCHAR(20) | Tipo de documento | "DNI" |
| birth_date | DATE | Fecha de nacimiento | "1985-03-15" |
| gender | VARCHAR(20) | Género | "M" |
| city | VARCHAR(255) | Ciudad | "Buenos Aires" |
| state | VARCHAR(255) | Provincia/Estado | "CABA" |
| country | VARCHAR(3) | País (ISO) | "ARG" |
| registration_date | TIMESTAMP | Primera registración | |
| first_purchase_date | TIMESTAMP | Primera compra | |
| last_purchase_date | TIMESTAMP | Última compra | |
| total_orders | INTEGER | Total de órdenes | 15 |
| total_spent | DECIMAL(15,2) | Gasto total | 25000.50 |
| avg_order_value | DECIMAL(15,2) | AOV promedio | 1666.70 |
Índices principales:
idx_customers_tenant_email(tenant_id, email)idx_customers_tenant_document(tenant_id, document_number)idx_customers_last_purchase(tenant_id, last_purchase_date)
5. customer_orders
Propósito: Historial completo de órdenes/compras por cliente.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 67890 |
| tenant_id | INTEGER | FK a tenants | 56 |
| customer_id | INTEGER | FK a customers | 12345 |
| external_order_id | VARCHAR(255) | ID en sistema origen | "ORD-VTEX-123456" |
| order_number | VARCHAR(255) | Número de orden | "CHE-2024-001234" |
| order_date | TIMESTAMP | Fecha de la orden | "2024-09-15 14:30:00" |
| order_status | VARCHAR(100) | Estado de la orden | "completed" |
| payment_status | VARCHAR(100) | Estado del pago | "approved" |
| payment_method | VARCHAR(100) | Método de pago | "credit_card" |
| shipping_method | VARCHAR(100) | Método de envío | "express" |
| subtotal | DECIMAL(15,2) | Subtotal sin impuestos | 2000.00 |
| tax_amount | DECIMAL(15,2) | Impuestos | 420.00 |
| shipping_cost | DECIMAL(15,2) | Costo de envío | 500.00 |
| discount_amount | DECIMAL(15,2) | Descuentos aplicados | 200.00 |
| total_amount | DECIMAL(15,2) | Total final | 2720.00 |
| shipping_address | JSONB | Dirección de envío | {"street": "Av. Corrientes 1234"} |
| source_system | VARCHAR(50) | Sistema origen | "vtex" |
| raw_data | JSONB | Datos originales completos |
Estados de orden: pending, processing, shipped, delivered, completed, cancelled, refunded
6. customer_order_items
Propósito: Detalle de productos por orden (line items).
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 456789 |
| tenant_id | INTEGER | FK a tenants | 56 |
| order_id | INTEGER | FK a customer_orders | 67890 |
| product_id | INTEGER | FK a products | 98765 |
| sku | VARCHAR(255) | SKU del producto | "CHE-ZAPATO-001-39" |
| product_name | VARCHAR(500) | Nombre del producto | "Zapato Cuero Negro Talle 39" |
| category | VARCHAR(255) | Categoría principal | "Calzado" |
| subcategory | VARCHAR(255) | Subcategoría | "Zapatos Hombre" |
| brand | VARCHAR(255) | Marca | "Chelsea" |
| quantity | INTEGER | Cantidad | 2 |
| unit_price | DECIMAL(15,2) | Precio unitario | 1000.00 |
| discount_amount | DECIMAL(15,2) | Descuento por item | 100.00 |
| total_amount | DECIMAL(15,2) | Total del line item | 1900.00 |
7. products
Propósito: Catálogo centralizado de productos multi-tenant.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 98765 |
| tenant_id | INTEGER | FK a tenants | 56 |
| external_id | VARCHAR(255) | ID en sistema origen | "vtex_product_123" |
| sku | VARCHAR(255) | SKU único | "CHE-ZAPATO-001" |
| name | VARCHAR(500) | Nombre del producto | "Zapato Cuero Negro" |
| description | TEXT | Descripción completa | |
| category | VARCHAR(255) | Categoría principal | "Calzado" |
| subcategory | VARCHAR(255) | Subcategoría | "Zapatos Hombre" |
| brand | VARCHAR(255) | Marca | "Chelsea" |
| price | DECIMAL(15,2) | Precio base | 1000.00 |
| cost | DECIMAL(15,2) | Costo del producto | 400.00 |
| weight | DECIMAL(10,3) | Peso en kg | 0.8 |
| dimensions | JSONB | Dimensiones del producto | {"length": 30, "width": 12} |
| attributes | JSONB | Atributos específicos | {"material": "cuero", "color": "negro"} |
| is_active | BOOLEAN | Producto activo | true |
📊 Analytics Tables (15)
8. customer_rfm_analysis
Propósito: Análisis RFM (Recency, Frequency, Monetary) por cliente.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 789012 |
| tenant_id | INTEGER | FK a tenants | 56 |
| customer_id | INTEGER | FK a customers | 12345 |
| recency_days | INTEGER | Días desde última compra | 30 |
| frequency | INTEGER | Número de órdenes | 8 |
| monetary | DECIMAL(15,2) | Valor monetario total | 12500.00 |
| recency_score | INTEGER | Score 1-5 para recency | 5 |
| frequency_score | INTEGER | Score 1-5 para frequency | 5 |
| monetary_score | INTEGER | Score 1-5 para monetary | 5 |
| rfm_score | VARCHAR(3) | Score combinado | "555" |
| rfm_segment | VARCHAR(50) | Segmento final | "Champions" |
| calculation_date | TIMESTAMP | Fecha de cálculo | |
| is_current | BOOLEAN | Es el análisis actual | true |
Segmentos RFM: Champions, Loyal Customers, Potential Loyalists, Recent Customers, Promising, Need Attention, About to Sleep, At Risk, Cannot Lose Them, Hibernating, Lost
9. customer_clv_analysis
Propósito: Análisis de Customer Lifetime Value predictivo.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 345678 |
| tenant_id | INTEGER | FK a tenants | 56 |
| customer_id | INTEGER | FK a customers | 12345 |
| historical_value | DECIMAL(15,2) | Valor histórico real | 25000.00 |
| predicted_value | DECIMAL(15,2) | Valor futuro predicho | 35000.00 |
| total_clv | DECIMAL(15,2) | CLV total (computed) | 60000.00 |
| clv_tier | VARCHAR(20) | Tier de CLV | "high" |
| percentile_rank | INTEGER | Percentil (1-100) | 85 |
| rfm_multiplier | DECIMAL(5,2) | Factor RFM aplicado | 2.5 |
| churn_probability | DECIMAL(5,4) | Probabilidad de churn | 0.05 |
| confidence_score | DECIMAL(5,4) | Confianza del modelo | 0.85 |
| model_version | VARCHAR(20) | Versión del modelo | "v2.1" |
CLV Tiers: high (>$10K), medium ($2K-$10K), low (<$2K)
10. customer_churn_analysis
Propósito: Análisis predictivo de riesgo de churn/abandono.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 234567 |
| tenant_id | INTEGER | FK a tenants | 56 |
| customer_id | INTEGER | FK a customers | 12345 |
| churn_probability | DECIMAL(5,4) | Probabilidad de churn | 0.15 |
| churn_risk | VARCHAR(20) | Nivel de riesgo | "active" |
| days_since_last_order | INTEGER | Días sin comprar | 45 |
| predicted_churn_date | DATE | Fecha predicha de churn | "2024-12-15" |
| recency_factor | DECIMAL(5,4) | Factor recency | 0.25 |
| frequency_factor | DECIMAL(5,4) | Factor frequency | 0.15 |
| engagement_factor | DECIMAL(5,4) | Factor engagement | 0.80 |
| model_confidence | DECIMAL(5,4) | Confianza del modelo | 0.82 |
Churn Risk Levels: active, at_risk, churning, churned
11. business_metrics
Propósito: KPIs y métricas agregadas por tenant y período.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 123456 |
| tenant_id | INTEGER | FK a tenants | 56 |
| metric_date | DATE | Fecha de la métrica | "2024-09-16" |
| period_type | VARCHAR(20) | Tipo de período | "daily" |
| total_customers | INTEGER | Total de clientes | 65226 |
| new_customers | INTEGER | Nuevos clientes | 125 |
| active_customers | INTEGER | Clientes activos | 45820 |
| total_orders | INTEGER | Total de órdenes | 1580 |
| total_revenue | DECIMAL(15,2) | Revenue total | 3950000.00 |
| avg_order_value | DECIMAL(15,2) | AOV promedio | 2500.00 |
| churn_rate | DECIMAL(5,4) | Tasa de churn | 0.15 |
| ltv_avg | DECIMAL(15,2) | LTV promedio | 15000.00 |
| cac_avg | DECIMAL(15,2) | CAC promedio | 850.00 |
Period Types: daily, weekly, monthly, quarterly, yearly
12. customer_segments
Propósito: Segmentación dinámica de clientes con criterios personalizables.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 567890 |
| tenant_id | INTEGER | FK a tenants | 56 |
| segment_name | VARCHAR(255) | Nombre del segmento | "VIP High Spenders" |
| segment_type | VARCHAR(50) | Tipo de segmento | "dynamic" |
| criteria | JSONB | Criterios de segmentación | {"clv_tier": "high", "rfm_segment": ["Champions"]} |
| customer_count | INTEGER | Número de clientes | 5000 |
| last_updated | TIMESTAMP | Última actualización | |
| is_active | BOOLEAN | Segmento activo | true |
Segment Types: dynamic (auto-updating), static (fixed list)
🔌 Integration Tables (8)
13. tenant_integrations
Propósito: Configuración de integraciones con sistemas externos.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 101 |
| tenant_id | INTEGER | FK a tenants | 56 |
| integration_type | VARCHAR(50) | Tipo de integración | "vtex" |
| account_name | VARCHAR(255) | Nombre de cuenta | "chelseaio" |
| environment | VARCHAR(100) | Entorno | "vtexcommercestable" |
| credentials | JSONB | Credenciales encriptadas | {"app_key": "encrypted_key"} |
| is_active | BOOLEAN | Integración activa | true |
| last_sync | TIMESTAMP | Última sincronización | |
| last_sync_status | VARCHAR(50) | Estado última sync | "success" |
| sync_frequency | VARCHAR(50) | Frecuencia de sync | "hourly" |
Integration Types: vtex, mercadolibre, google_ads, facebook_ads, klaviyo, sendgrid
14. integration_sync_log
Propósito: Log detallado de todas las sincronizaciones.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 789123 |
| tenant_id | INTEGER | FK a tenants | 56 |
| integration_id | INTEGER | FK a tenant_integrations | 101 |
| sync_type | VARCHAR(50) | Tipo de sincronización | "incremental" |
| start_time | TIMESTAMP | Inicio del proceso | |
| end_time | TIMESTAMP | Fin del proceso | |
| status | VARCHAR(50) | Estado final | "success" |
| records_processed | INTEGER | Registros procesados | 1250 |
| records_created | INTEGER | Registros creados | 45 |
| records_updated | INTEGER | Registros actualizados | 1200 |
| records_failed | INTEGER | Registros fallidos | 5 |
| error_message | TEXT | Mensaje de error | |
| sync_details | JSONB | Detalles del proceso |
15. vtex_orders
Propósito: Raw data de órdenes desde VTEX (antes de procesamiento).
| Campo | Tipo | Descripción |
|---|---|---|
| id | SERIAL | PK |
| tenant_id | INTEGER | FK a tenants |
| order_id | VARCHAR(255) | ID de orden VTEX |
| raw_order_data | JSONB | JSON completo de VTEX |
| processed | BOOLEAN | Ya procesada |
| created_at | TIMESTAMP | Fecha de importación |
⚙️ Processing Tables (7)
16. processing_jobs
Propósito: Cola de trabajos de procesamiento y ETL.
| Campo | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| id | SERIAL | PK | 456123 |
| tenant_id | INTEGER | FK a tenants | 56 |
| job_type | VARCHAR(100) | Tipo de trabajo | "rfm_analysis" |
| job_status | VARCHAR(50) | Estado del trabajo | "running" |
| priority | VARCHAR(20) | Prioridad | "high" |
| parameters | JSONB | Parámetros del job | {"force_recalc": true} |
| scheduled_at | TIMESTAMP | Hora programada | |
| started_at | TIMESTAMP | Hora de inicio | |
| completed_at | TIMESTAMP | Hora de finalización | |
| error_message | TEXT | Mensaje de error | |
| result_data | JSONB | Resultado del proceso |
Job Types: rfm_analysis, clv_calculation, churn_prediction, data_sync, report_generation
Job Status: pending, running, completed, failed, cancelled
17. processing_log
Propósito: Log detallado de todos los procesos ejecutados.
| Campo | Tipo | Descripción |
|---|---|---|
| id | SERIAL | PK |
| tenant_id | INTEGER | FK a tenants |
| process_type | VARCHAR(100) | Tipo de proceso |
| process_name | VARCHAR(255) | Nombre específico |
| start_time | TIMESTAMP | Inicio |
| end_time | TIMESTAMP | Fin |
| status | VARCHAR(50) | Estado final |
| records_affected | INTEGER | Registros afectados |
| execution_time_seconds | INTEGER | Tiempo de ejecución |
| memory_used_mb | INTEGER | Memoria utilizada |
| log_details | JSONB | Detalles del log |
| created_at | TIMESTAMP | Timestamp del log |
18. data_quality_checks
Propósito: Validaciones automáticas de calidad de datos.
| Campo | Tipo | Descripción |
|---|---|---|
| id | SERIAL | PK |
| tenant_id | INTEGER | FK a tenants |
| check_type | VARCHAR(100) | Tipo de validación |
| table_name | VARCHAR(100) | Tabla validada |
| check_query | TEXT | Query de validación |
| expected_result | JSONB | Resultado esperado |
| actual_result | JSONB | Resultado real |
| status | VARCHAR(50) | Estado de la validación |
| executed_at | TIMESTAMP | Fecha de ejecución |
Check Types: completeness, uniqueness, validity, consistency, accuracy
🔍 Índices y Constraints Principales
Performance Indexes
-- Multi-tenant queries optimization
CREATE INDEX idx_customers_tenant_analytics ON customers
(tenant_id, last_purchase_date, total_spent);
-- RFM analysis optimization
CREATE INDEX idx_rfm_segment_analysis ON customer_rfm_analysis
(tenant_id, rfm_segment, monetary DESC);
-- Churn risk monitoring
CREATE INDEX idx_churn_risk_monitoring ON customer_churn_analysis
(tenant_id, churn_risk, churn_probability DESC)
WHERE is_current = true;
-- Order analytics
CREATE INDEX idx_orders_analytics ON customer_orders
(tenant_id, order_date, total_amount)
WHERE order_status = 'completed';
Foreign Key Constraints
-- Todas las tablas principales
ALTER TABLE customers ADD CONSTRAINT fk_customers_tenant
FOREIGN KEY (tenant_id) REFERENCES tenants(id);
ALTER TABLE customer_orders ADD CONSTRAINT fk_orders_customer
FOREIGN KEY (customer_id) REFERENCES customers(id);
ALTER TABLE customer_rfm_analysis ADD CONSTRAINT fk_rfm_customer
FOREIGN KEY (customer_id) REFERENCES customers(id);
-- ... etc para todas las FK
Check Constraints
-- Validaciones de datos
ALTER TABLE customer_rfm_analysis ADD CONSTRAINT chk_rfm_scores
CHECK (recency_score BETWEEN 1 AND 5 AND
frequency_score BETWEEN 1 AND 5 AND
monetary_score BETWEEN 1 AND 5);
ALTER TABLE customer_churn_analysis ADD CONSTRAINT chk_churn_probability
CHECK (churn_probability BETWEEN 0 AND 1);
💡 Tip: Esta estructura permite análisis complejos manteniendo performance óptima. Los índices están optimizados para las queries más comunes del CDP.