# Multitenant - Core Module **Modulo:** shared/modules/multitenant/ **Version:** 0.1.0 **Fecha:** 2026-01-03 **Owner:** Backend-Agent **Estado:** desarrollo --- ## Descripcion Modulo de multi-tenancy compartido que provee aislamiento de datos por organizacion usando Row Level Security (RLS) de PostgreSQL. Incluye middleware, decorators y utilidades para gestion de tenant context. --- ## Instalacion ### Prerequisitos ```bash # Requiere TypeORM y PostgreSQL con RLS habilitado npm install typeorm pg ``` ### Configuracion de Paths ```json { "compilerOptions": { "paths": { "@shared/modules/*": ["../../shared/modules/*"] } } } ``` --- ## API Publica (Planificada) ### Middleware | Middleware | Descripcion | |------------|-------------| | `TenantMiddleware` | Extrae tenant_id de JWT/header y lo setea en contexto | ### Guards | Guard | Descripcion | |-------|-------------| | `TenantGuard` | Verifica que usuario pertenece al tenant | ### Decorators | Decorator | Descripcion | Ejemplo | |-----------|-------------|---------| | `@CurrentTenant()` | Extrae tenant actual | `@CurrentTenant() tenantId: string` | | `@TenantAware()` | Marca entity como tenant-aware | En entity class | ### Servicios | Servicio | Descripcion | |----------|-------------| | `TenantService` | Gestion de tenants | | `TenantContextService` | Almacena contexto del request | ### Tipos ```typescript interface Tenant { id: string; name: string; slug: string; settings: TenantSettings; plan: string; status: 'active' | 'suspended' | 'trial'; createdAt: Date; } interface TenantSettings { timezone: string; locale: string; currency: string; features: Record; } interface TenantContext { tenantId: string; userId: string; roles: string[]; } ``` --- ## Ejemplos de Uso ### Ejemplo 1: Entity con RLS ```typescript import { TenantAware } from '@shared/modules/multitenant'; @Entity('projects') @TenantAware() export class Project { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; @Column({ name: 'tenant_id' }) tenantId: string; // RLS filtra automaticamente por este campo } ``` ### Ejemplo 2: Acceder al Tenant Actual ```typescript import { CurrentTenant, TenantGuard } from '@shared/modules/multitenant'; @Controller('projects') @UseGuards(TenantGuard) export class ProjectsController { @Get() findAll(@CurrentTenant() tenantId: string) { // Solo retorna proyectos del tenant actual // RLS en PostgreSQL filtra automaticamente return this.projectService.findAll(); } } ``` ### Ejemplo 3: Configurar RLS en PostgreSQL ```sql -- Habilitar RLS en tabla ALTER TABLE projects ENABLE ROW LEVEL SECURITY; -- Politica de lectura CREATE POLICY tenant_isolation ON projects FOR ALL USING (tenant_id = current_setting('app.current_tenant_id')::uuid); -- Setear tenant en sesion (lo hace el middleware) SET app.current_tenant_id = 'uuid-del-tenant'; ``` --- ## Dependencias ### Internas | Modulo | Uso | |--------|-----| | `@shared/modules/auth` | JWT, user context | ### Externas (npm) | Paquete | Version | Uso | |---------|---------|-----| | `typeorm` | `^0.3` | ORM | | `pg` | `^8.0` | PostgreSQL driver | | `nestjs-cls` | `^4.0` | Context storage | --- ## Configuracion RLS ### Tablas Requeridas ```sql -- Tabla de tenants CREATE TABLE core.tenants ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, slug VARCHAR(100) UNIQUE NOT NULL, settings JSONB DEFAULT '{}', status VARCHAR(20) DEFAULT 'active', created_at TIMESTAMPTZ DEFAULT NOW() ); -- Para cada tabla tenant-aware: ALTER TABLE {schema}.{table} ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON {schema}.{table} FOR ALL USING (tenant_id = current_setting('app.current_tenant_id')::uuid); ``` --- ## Estado Actual ```markdown - [ ] TenantMiddleware - [ ] TenantGuard - [ ] @CurrentTenant decorator - [ ] @TenantAware decorator - [ ] TenantService - [ ] TenantContextService con CLS - [ ] Integracion TypeORM - [ ] Tests con RLS ``` --- ## Changelog ### v0.1.0 (2026-01-03) - Estructura inicial - README con planificacion --- **Modulo:** shared/modules/multitenant/ | **Owner:** Backend-Agent