Arquitectura Multi-tenant
🏢 ¿Qué es Multi-tenancy?
La arquitectura multi-tenant permite que una sola instancia del CDP sirva a múltiples organizaciones (tenants) de forma aislada y segura, cada una con sus propios datos, configuraciones e integraciones.
🏗️ Diseño de Arquitectura
Aislamiento de Datos
-- Todas las tablas incluyen tenant_id
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
email VARCHAR(255),
created_at TIMESTAMP,
CONSTRAINT fk_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id)
);
-- Índices optimizados por tenant
CREATE INDEX idx_customers_tenant ON customers(tenant_id, email);
Row-Level Security (RLS)
-- Política de seguridad automática
CREATE POLICY tenant_isolation ON customers
FOR ALL TO app_role
USING (tenant_id = current_setting('app.current_tenant_id')::INTEGER);
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
🔐 Modelo de Tenants
Tipos de Tenant
1. Enterprise Tenant
- Características: Multi-marca, múltiples integraciones
- Ejemplos: Grupo Nerdistan (Chelsea, MundoJuguete, Seven Sport)
- Recursos: Dedicados, SLA premium
2. Business Tenant
- Características: Single-brand, integraciones básicas
- Ejemplos: Marca individual con VTEX
- Recursos: Compartidos, SLA estándar
3. Trial Tenant
- Características: Evaluación, datos limitados
- Duración: 30 días
- Recursos: Limitados, sin SLA
Configuración de Tenant
{
"id": 56,
"name": "Chelsea",
"slug": "chelsea",
"type": "enterprise",
"plan": "premium",
"status": "active",
"settings": {
"timezone": "America/Argentina/Buenos_Aires",
"currency": "ARS",
"language": "es",
"data_retention_days": 2555,
"max_customers": 1000000,
"max_api_calls_day": 100000
},
"integrations": [
{
"type": "vtex",
"account": "chelseaio",
"environment": "vtexcommercestable",
"status": "active"
}
],
"features": {
"rfm_analysis": true,
"clv_prediction": true,
"churn_detection": true,
"email_automation": true,
"api_access": true,
"custom_reports": true
}
}
📊 Tenants Activos
Distribución Actual
| Tenant ID | Nombre | Tipo | Clientes | Estado | Última Sync |
|---|---|---|---|---|---|
| 56 | Chelsea | Enterprise | 65,226 | Activo | 2h ago |
| 57 | MundoJuguete | Enterprise | 45,282 | Activo | 1h ago |
| 58 | Seven Sport | Enterprise | 29,707 | Activo | 3h ago |
| 59 | Test Brand | Business | 8,521 | Activo | 6h ago |
| 60 | Demo Account | Trial | 1,286 | Activo | 12h ago |
Métricas Globales
{
"total_tenants": 5,
"total_customers": 149522,
"active_integrations": 8,
"total_api_calls_today": 45230,
"storage_used_gb": 127.5,
"processing_time_avg_minutes": 15.3
}
🚀 APIs de Tenant Management
Listar Tenants
GET /api/v2/tenants
Respuesta
{
"success": true,
"data": [
{
"id": 56,
"name": "Chelsea",
"slug": "chelsea",
"type": "enterprise",
"status": "active",
"customer_count": 65226,
"last_sync": "2024-09-16T17:30:00Z",
"integrations": [
{
"type": "vtex",
"status": "active",
"last_sync": "2024-09-16T17:30:00Z"
}
]
}
]
}
Obtener Tenant Específico
GET /api/v2/tenants/56
Crear Nuevo Tenant
POST /api/v2/tenants
{
"name": "Nueva Marca",
"slug": "nueva-marca",
"type": "business",
"settings": {
"timezone": "America/Argentina/Buenos_Aires",
"currency": "ARS",
"language": "es"
}
}
Actualizar Configuración
PUT /api/v2/tenants/56/settings
{
"max_customers": 2000000,
"max_api_calls_day": 200000,
"features": {
"advanced_analytics": true
}
}
🔌 Gestión de Integraciones
Integraciones por Tenant
GET /api/v2/tenant-integrations?tenant_id=56
Tipos de Integración Soportados
VTEX E-commerce
{
"type": "vtex",
"config": {
"account_name": "chelseaio",
"environment": "vtexcommercestable",
"app_key": "vtexappkey-chelseaio-XXXXX",
"app_token": "encrypted_token",
"sync_frequency": "hourly"
}
}
MercadoLibre
{
"type": "mercadolibre",
"config": {
"client_id": "ml_client_id",
"client_secret": "encrypted_secret",
"refresh_token": "encrypted_token",
"site_id": "MLA"
}
}
Google Ads
{
"type": "google_ads",
"config": {
"customer_id": "1234567890",
"developer_token": "encrypted_token",
"client_id": "oauth_client_id",
"client_secret": "encrypted_secret"
}
}
Facebook Ads
{
"type": "facebook_ads",
"config": {
"access_token": "encrypted_token",
"ad_account_id": "act_1234567890",
"app_id": "facebook_app_id"
}
}
Crear Nueva Integración
POST /api/v2/tenant-integrations
{
"tenant_id": 56,
"integration_type": "vtex",
"account_name": "nueva-cuenta",
"environment": "vtexcommercestable",
"app_key": "vtexappkey-nueva-cuenta-XXXXX",
"app_token": "token_aqui",
"auto_sync": true,
"sync_frequency": "daily"
}
Validar Credenciales
POST /api/v2/tenant-integrations/validate/vtex
{
"account_name": "chelseaio",
"app_key": "vtexappkey-chelseaio-XXXXX",
"app_token": "token_here",
"environment": "vtexcommercestable"
}
🔄 Sincronización de Datos
Estrategias de Sync
Real-time (Webhooks)
- VTEX: Order hooks, customer updates
- Latencia: <1 minuto
- Uso: Eventos críticos
Scheduled Batch
- Frecuencia: Hourly, daily, weekly
- Latencia: Configurable
- Uso: Datos históricos, reportes
Manual Trigger
- On-demand: Via API o dashboard
- Uso: Troubleshooting, testing
Estado de Sincronización
GET /api/v2/tenant-integrations/56/sync-status
{
"tenant_id": 56,
"integrations": [
{
"type": "vtex",
"status": "syncing",
"last_sync": "2024-09-16T17:30:00Z",
"next_sync": "2024-09-16T18:30:00Z",
"records_synced": 1250,
"errors": 0,
"sync_duration_minutes": 15.3
}
],
"overall_status": "healthy"
}
Trigger Manual Sync
POST /api/v2/tenant-integrations/56/sync
{
"integration_types": ["vtex", "google_ads"],
"sync_type": "incremental",
"priority": "high"
}
📊 Monitoring Multi-tenant
Health Dashboard
-- Vista de salud por tenant
SELECT
t.id,
t.name,
COUNT(c.id) as customer_count,
ti.last_sync,
CASE
WHEN ti.last_sync > NOW() - INTERVAL '2 hours' THEN 'healthy'
WHEN ti.last_sync > NOW() - INTERVAL '1 day' THEN 'warning'
ELSE 'critical'
END as health_status
FROM tenants t
LEFT JOIN customers c ON t.id = c.tenant_id
LEFT JOIN tenant_integrations ti ON t.id = ti.tenant_id
GROUP BY t.id, t.name, ti.last_sync;
Alertas Automáticas
# Monitoreo de salud por tenant
def monitor_tenant_health():
for tenant in get_all_tenants():
# Check sync delays
if tenant.last_sync < datetime.now() - timedelta(hours=6):
alert_sync_delay(tenant.id)
# Check API rate limits
if tenant.api_calls_today > tenant.max_api_calls * 0.9:
alert_api_limit(tenant.id)
# Check storage usage
if tenant.storage_used > tenant.storage_limit * 0.8:
alert_storage_usage(tenant.id)
🔐 Seguridad y Aislamiento
Encryption at Rest
- Customer Data: AES-256 encryption
- Credentials: Separate keystore
- Backups: Encrypted backups
Network Isolation
- VPC: Isolated networks per tenant type
- API Gateway: Rate limiting per tenant
- Database: Connection pooling with tenant context
Access Control
# Middleware de autenticación
@require_tenant_access
def api_endpoint(tenant_id):
# Verificar que usuario tiene acceso al tenant
if not user_has_tenant_access(current_user, tenant_id):
raise Forbidden("Access denied to tenant")
# Set tenant context para queries
set_tenant_context(tenant_id)
# Proceder con lógica de negocio
return process_request()
📈 Escalabilidad
Horizontal Scaling
- Read Replicas: Por región geográfica
- Sharding: Por tenant_id ranges
- Caching: Redis per tenant
Resource Allocation
# Límites por tipo de tenant
TENANT_LIMITS = {
'trial': {
'max_customers': 1000,
'max_api_calls_day': 1000,
'storage_gb': 1,
'processing_priority': 'low'
},
'business': {
'max_customers': 100000,
'max_api_calls_day': 10000,
'storage_gb': 10,
'processing_priority': 'normal'
},
'enterprise': {
'max_customers': 10000000,
'max_api_calls_day': 100000,
'storage_gb': 100,
'processing_priority': 'high'
}
}
🔮 Roadmap Multi-tenant
Q4 2024
- Tenant self-service portal
- Advanced billing integration
- Cross-tenant analytics (aggregated)
- White-label dashboard
Q1 2025
- Geographic data residency
- Advanced RBAC per tenant
- Custom domain support
- API rate limiting per user
💡 Tip: La arquitectura multi-tenant permite escalar eficientemente, pero requiere cuidadoso diseño de seguridad y aislamiento. Cada tenant debe sentirse como si tuviera su propia instancia dedicada.