- Add MetricsPage and useOnboarding hook - Update superadmin controller and service - Add module documentation (docs/01-modulos/) - Add CONTEXT-MAP.yml and Sprint 5 execution report - Update project status and task traces 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
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
- Aislamiento de datos por tenant
- RLS en todas las tablas
- Tenant context automatico
- Configuracion por tenant
- 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
-- 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
// 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 |
| PUT | /tenants/current | Actualizar tenant |
| GET | /tenants/current/settings | Configuraciones |
| PUT | /tenants/current/settings | Actualizar config |
| POST | /tenants/current/logo | Subir logo |
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
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
- Tenant se crea automaticamente
- RLS aisla datos correctamente
- Contexto se setea automaticamente
- Settings se guardan y recuperan
- 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-07