workspace-v1/shared/modules/multitenant/README.md
rckrdmrd cb4c0681d3 feat(workspace): Add new projects and update architecture
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>
2026-01-07 04:43:28 -06:00

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