platform-marketing-content/docs/02-definicion-modulos/PMC-001-TENANTS.md
rckrdmrd 74b5ed7f38 feat: Complete documentation update and orchestration configuration
- Update vision, architecture and technical documentation
- Update module definitions (PMC-001 to PMC-008)
- Update requirements documentation
- Add CONTEXT-MAP.yml and ENVIRONMENT-INVENTORY.yml
- Add orchestration guidelines and references

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:38:31 -06:00

307 lines
7.6 KiB
Markdown

---
id: "PMC-001-TENANTS"
title: "PMC-001: Módulo de Tenants"
type: "Module Definition"
epic: "PMC-001"
status: "Draft"
project: "platform_marketing_content"
version: "1.0.0"
created_date: "2026-01-04"
updated_date: "2026-01-04"
---
# PMC-001: Módulo de Tenants
**Versión:** 1.0.0
**Fecha:** 2025-12-08
**Estado:** Definición
**Prioridad:** Alta
---
## Descripción General
El módulo de Tenants proporciona la arquitectura multi-tenant que permite aislar datos y configuraciones entre diferentes organizaciones (agencias) que utilicen la plataforma.
---
## Objetivos
1. Aislar completamente los datos entre tenants
2. Permitir configuración personalizada por tenant
3. Soportar branding personalizado (logo, colores)
4. Gestionar límites y cuotas por tenant
5. Preparar arquitectura para comercialización SaaS futura
---
## Entidades del Dominio
### Tenant
```yaml
Entidad: Tenant
Descripción: Organización/agencia que utiliza la plataforma
Atributos:
- id: UUID (PK)
- name: string (nombre de la organización)
- slug: string (identificador URL-friendly, único)
- status: enum [active, suspended, trial, cancelled]
- plan_id: UUID (FK a Plan)
- settings: JSONB (configuración personalizada)
- branding: JSONB (logo_url, primary_color, secondary_color)
- limits: JSONB (cuotas y límites)
- created_at: timestamp
- updated_at: timestamp
- deleted_at: timestamp (soft delete)
Relaciones:
- 1:N con User
- 1:N con Client (CRM)
- 1:N con Project
- 1:N con Asset
- N:1 con Plan
```
### Plan
```yaml
Entidad: Plan
Descripción: Plan de suscripción con límites definidos
Atributos:
- id: UUID (PK)
- name: string (Free, Pro, Enterprise, Internal)
- code: string (identificador único)
- features: JSONB (funcionalidades habilitadas)
- limits: JSONB
- generations_per_month: number
- trainings_per_month: number
- storage_gb: number
- users_max: number
- projects_max: number
- price_monthly: decimal
- price_yearly: decimal
- is_active: boolean
- created_at: timestamp
- updated_at: timestamp
Relaciones:
- 1:N con Tenant
```
### TenantSettings
```yaml
Estructura JSONB: settings
Campos:
- default_language: string (es, en)
- timezone: string
- date_format: string
- currency: string
- notifications:
email_enabled: boolean
slack_webhook: string
- integrations:
crm_external_url: string
n8n_webhook_base: string
- generation:
default_model: string
default_quality: string
watermark_enabled: boolean
```
---
## Funcionalidades
### F-001.1: Gestión de Tenants
| ID | Funcionalidad | Descripción | Prioridad |
|----|---------------|-------------|-----------|
| F-001.1.1 | Crear tenant | Registro de nueva organización | Alta |
| F-001.1.2 | Editar tenant | Modificar datos y configuración | Alta |
| F-001.1.3 | Suspender tenant | Desactivar acceso temporalmente | Media |
| F-001.1.4 | Eliminar tenant | Soft delete con retención de datos | Baja |
### F-001.2: Configuración por Tenant
| ID | Funcionalidad | Descripción | Prioridad |
|----|---------------|-------------|-----------|
| F-001.2.1 | Branding | Personalizar logo y colores | Media |
| F-001.2.2 | Límites | Configurar cuotas de uso | Alta |
| F-001.2.3 | Integraciones | URLs de webhooks y APIs externas | Media |
| F-001.2.4 | Preferencias | Idioma, zona horaria, formatos | Baja |
### F-001.3: Aislamiento de Datos
| ID | Funcionalidad | Descripción | Prioridad |
|----|---------------|-------------|-----------|
| F-001.3.1 | RLS PostgreSQL | Row-Level Security por tenant_id | Alta |
| F-001.3.2 | Middleware | Inyección automática de tenant_id | Alta |
| F-001.3.3 | Storage isolation | Prefijos S3 por tenant | Alta |
---
## Reglas de Negocio
```yaml
RN-001.1:
Descripción: Todo tenant debe tener un plan asignado
Validación: plan_id NOT NULL
Default: Plan "Free" o "Internal"
RN-001.2:
Descripción: El slug del tenant debe ser único y URL-safe
Validación: Regex ^[a-z0-9-]+$, único en BD
RN-001.3:
Descripción: Tenant suspendido no permite login de usuarios
Acción: Validar status en middleware de autenticación
RN-001.4:
Descripción: Límites del plan se heredan al tenant
Override: Tenant puede tener límites personalizados que sobreescriban el plan
RN-001.5:
Descripción: Soft delete conserva datos 90 días
Acción: deleted_at marca fecha, cron job limpia después
```
---
## API Endpoints
```yaml
Base: /api/v1/tenants
Endpoints:
POST /tenants:
Descripción: Crear nuevo tenant (Super Admin)
Body: { name, slug, plan_id, settings? }
Response: 201 Created
GET /tenants:
Descripción: Listar tenants (Super Admin)
Query: ?status=active&page=1&limit=20
Response: 200 OK (paginado)
GET /tenants/:id:
Descripción: Obtener tenant por ID
Response: 200 OK
PUT /tenants/:id:
Descripción: Actualizar tenant
Body: { name?, settings?, branding?, limits? }
Response: 200 OK
PATCH /tenants/:id/status:
Descripción: Cambiar estado del tenant
Body: { status: "suspended" | "active" }
Response: 200 OK
DELETE /tenants/:id:
Descripción: Soft delete tenant
Response: 204 No Content
GET /tenants/current:
Descripción: Obtener tenant del usuario actual
Response: 200 OK
```
---
## Dependencias
```yaml
Dependencias del Catálogo:
- @CATALOG_TENANT:
path: shared/catalog/multi-tenancy/
uso: Patron base multi-tenancy con RLS
adaptar:
- Extender modelo Tenant con campos branding
- Agregar sistema de quotas por plan
- Integrar con limites de generacion
docs: shared/catalog/multi-tenancy/README.md
- @CATALOG_PAYMENTS:
path: shared/catalog/payments/
uso: Suscripciones y billing (Fase 4)
adaptar:
- Crear productos/precios en Stripe
- Definir planes PMC (Starter, Pro, Business, Enterprise)
- Integrar creditos de generacion
docs: shared/catalog/payments/README.md
Dependencias de Módulos:
- PMC-007 Admin: Gestión de planes y configuración global
Servicios Externos:
- Stripe (Fase 4 - SaaS comercial)
Referencia de Implementacion:
- Proyecto origen: projects/gamilit/apps/backend/src/modules/auth/entities/tenant.entity.ts
- RLS policies: projects/gamilit/apps/database/ddl/policies/
```
---
## Consideraciones Técnicas
### Estrategia Multi-Tenant
```yaml
Tipo: Single Database, Shared Schema
Aislamiento: Row-Level Security (RLS) en PostgreSQL
Implementación:
1. Columna tenant_id en todas las tablas principales
2. Políticas RLS que filtran por tenant_id
3. Middleware que extrae tenant del JWT/sesión
4. SET app.current_tenant antes de cada query
```
### Ejemplo RLS PostgreSQL
```sql
-- Política para tabla clients
CREATE POLICY tenant_isolation_policy ON clients
USING (tenant_id = current_setting('app.current_tenant')::uuid);
-- Habilitar RLS
ALTER TABLE clients ENABLE ROW LEVEL SECURITY;
```
### Storage Isolation
```yaml
Estructura S3:
bucket/
├── {tenant_slug}/
│ ├── assets/
│ ├── generated/
│ ├── models/
│ └── temp/
```
---
## Criterios de Aceptación
- [ ] Tenant puede ser creado con datos mínimos (name, slug, plan)
- [ ] RLS impide acceso a datos de otros tenants
- [ ] Branding se refleja en UI del tenant
- [ ] Límites del plan se validan antes de operaciones
- [ ] Soft delete funciona correctamente
- [ ] API responde correctamente a todos los endpoints
---
## Referencias
- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
- [@CATALOG_TENANT](../../../shared/catalog/modules/multi-tenancy/)
---
**Documento generado por:** Requirements-Analyst
**Fecha:** 2025-12-08