--- id: "SAAS-002" title: "Multi-Tenancy" type: "Module" status: "Published" priority: "P0" module: "tenants" version: "1.0.0" created_date: "2026-01-07" updated_date: "2026-01-10" --- # SAAS-002: Multi-Tenancy ## Metadata - **Codigo:** SAAS-002 - **Modulo:** Tenants - **Prioridad:** P0 - **Estado:** Completado - **Fase:** 1 - Foundation ## Descripcion Sistema de multi-tenancy con aislamiento completo de datos via Row-Level Security (RLS): creacion de tenants, configuracion por tenant, y contexto automatico en todas las operaciones. ## Objetivos 1. Aislamiento de datos por tenant 2. RLS en todas las tablas 3. Tenant context automatico 4. Configuracion por tenant 5. Subdominios/custom domains ## Alcance ### Incluido - Creacion de tenant al registrar owner - RLS policies en todas las tablas - Tenant context via middleware - tenant_id en JWT claims - Configuraciones por tenant (JSONB) - Slug unico por tenant ### Excluido - Custom domains - fase posterior - White-labeling completo - Tenant isolation fisica (DB separadas) ## Modelo de Datos ### Tablas (schema: tenants) **tenants** - id, name, slug (unique) - domain, logo_url, favicon_url - settings (JSONB), status - trial_ends_at, created_at **tenant_settings** - id, tenant_id, key, value - created_at, updated_at ## Estrategia RLS ### Implementacion ```sql -- Funcion de contexto CREATE FUNCTION current_tenant_id() RETURNS UUID AS $$ SELECT current_setting('app.tenant_id', TRUE)::UUID; $$ LANGUAGE SQL STABLE; -- Policy generica CREATE POLICY tenant_isolation ON table_name USING (tenant_id = current_tenant_id()); ``` ### Middleware Backend ```typescript // Set tenant context antes de queries await db.query(`SELECT set_config('app.tenant_id', $1, true)`, [tenantId]); ``` ## Endpoints API | Metodo | Endpoint | Descripcion | |--------|----------|-------------| | GET | /tenants/current | Tenant actual (incluye settings) | | PATCH | /tenants/current | Actualizar tenant (incluye settings) | | GET | /tenants/:id | Obtener tenant por ID | | POST | /tenants | Crear tenant | ### Configuraciones de Tenant Las configuraciones se almacenan en el campo `settings` (JSONB) de la tabla tenants. **Acceso via API:** - GET `/tenants/current` - Retorna tenant con settings incluidos - PATCH `/tenants/current` - Permite actualizar settings junto con otros campos **Estructura del Campo Settings:** ```json { "branding": { "logo_url": "https://...", "primary_color": "#3B82F6" }, "notifications": { "email_enabled": true, "push_enabled": false }, "features": { "ai_enabled": true, "whatsapp_enabled": false } } ``` **Nota:** Los endpoints dedicados `/tenants/current/settings` y `/tenants/current/logo` estan planificados pero no implementados actualmente ## Flujos ### Creacion de Tenant ``` 1. Usuario se registra como owner 2. Se crea usuario 3. Se crea tenant con slug unico 4. Se asocia usuario a tenant 5. Se aplican settings default 6. Se inicia trial ``` ### Resolucion de Tenant ``` Request llega a API │ ├─► JWT contiene tenant_id? │ └─► Si: usar ese tenant_id │ ├─► Header X-Tenant-ID? │ └─► Si: validar y usar │ └─► Subdominio? └─► Si: buscar tenant por slug ``` ## Configuraciones Default ```typescript const DEFAULT_SETTINGS = { timezone: 'America/Mexico_City', locale: 'es-MX', currency: 'MXN', date_format: 'DD/MM/YYYY', features: { ai_enabled: false, webhooks_enabled: false }, limits: { users: 5, storage_mb: 1000 } }; ``` ## Entregables | Entregable | Estado | Archivo | |------------|--------|---------| | tenants.module.ts | Completado | `modules/tenants/` | | tenant.middleware.ts | Completado | `middleware/` | | DDL tenants schema | Completado | `ddl/schemas/tenants/` | | RLS policies | Completado | En cada schema | ## Dependencias ### Depende de - SAAS-001 (Auth) ### Bloquea a - SAAS-003 (Users) - Todos los modulos multi-tenant ## Criterios de Aceptacion - [x] Tenant se crea automaticamente - [x] RLS aisla datos correctamente - [x] Contexto se setea automaticamente - [x] Settings se guardan y recuperan - [x] Slug es unico ## Seguridad - RLS activo en todas las tablas (excepto plans) - Tenant ID no modificable por usuario - Validacion de pertenencia a tenant - Logs de cambios en configuracion --- **Ultima actualizacion:** 2026-01-10