New projects created: - michangarrito (marketplace mobile) - template-saas (SaaS template) - clinica-dental (dental ERP) - clinica-veterinaria (veterinary ERP) Architecture updates: - Move catalog from core/ to shared/ - Add MCP servers structure and templates - Add git management scripts - Update SUBREPOSITORIOS.md with 15 new repos - Update .gitignore for new projects Repository infrastructure: - 4 main repositories - 11 subrepositorios - Gitea remotes configured 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
217 lines
4.1 KiB
Markdown
217 lines
4.1 KiB
Markdown
# 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<string, boolean>;
|
|
}
|
|
|
|
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
|