diff --git a/core/orchestration/directivas/simco/_INDEX.md b/core/orchestration/directivas/simco/_INDEX.md
index 4287568..d9c4e58 100644
--- a/core/orchestration/directivas/simco/_INDEX.md
+++ b/core/orchestration/directivas/simco/_INDEX.md
@@ -74,6 +74,29 @@ core/
β βββ CONTEXTO-NIVEL-SUITE-CORE.md # π Template para core de suite
β βββ CONTEXTO-NIVEL-VERTICAL.md # π Template para verticales
β
+ βββ patrones/ # PATRONES DE CΓDIGO
+ β βββ MAPEO-TIPOS-DDL-TYPESCRIPT.md # Mapeo PostgreSQL β TypeScript
+ β βββ PATRON-VALIDACION.md # ValidaciΓ³n con class-validator/Zod
+ β βββ PATRON-EXCEPTION-HANDLING.md # Manejo de errores y excepciones
+ β βββ PATRON-TESTING.md # Patrones de testing
+ β βββ PATRON-LOGGING.md # Logging estructurado
+ β βββ PATRON-CONFIGURACION.md # Variables de entorno y config
+ β βββ PATRON-SEGURIDAD.md # Seguridad y OWASP
+ β βββ PATRON-PERFORMANCE.md # OptimizaciΓ³n y caching
+ β βββ PATRON-TRANSACCIONES.md # Transacciones de BD
+ β βββ ANTIPATRONES.md # Lo que NUNCA hacer
+ β βββ NOMENCLATURA-UNIFICADA.md # Convenciones de nombres
+ β
+ βββ impactos/ # IMPACTO DE CAMBIOS
+ β βββ IMPACTO-CAMBIOS-DDL.md # Cascada de cambios en BD
+ β βββ IMPACTO-CAMBIOS-BACKEND.md # SincronizaciΓ³n BackendβFrontend
+ β βββ IMPACTO-CAMBIOS-ENTITY.md # Cambios en Entities TypeORM
+ β βββ IMPACTO-CAMBIOS-API.md # Cambios en endpoints REST
+ β βββ MATRIZ-DEPENDENCIAS.md # Matriz completa de dependencias
+ β
+ βββ procesos/ # PROCESOS DE TRABAJO
+ β βββ ORDEN-IMPLEMENTACION.md # DDL-First, orden de capas
+ β
βββ _historico/
β βββ MAPA-CONTEXTO-AGENTE.md # Trazabilidad (histΓ³rico)
β
diff --git a/core/orchestration/impactos/IMPACTO-CAMBIOS-API.md b/core/orchestration/impactos/IMPACTO-CAMBIOS-API.md
new file mode 100644
index 0000000..a80b116
--- /dev/null
+++ b/core/orchestration/impactos/IMPACTO-CAMBIOS-API.md
@@ -0,0 +1,669 @@
+# IMPACTO DE CAMBIOS EN API
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Consultar antes de modificar endpoints
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Documentar el impacto de modificar endpoints REST (Controllers), rutas, metodos HTTP, y contratos de API en el sistema.
+
+---
+
+## 1. CLASIFICACION DE CAMBIOS API
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β TIPOS DE CAMBIOS EN API β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β BREAKING CHANGES (β οΈ ROMPEN CLIENTES): β
+β β’ Eliminar endpoint β
+β β’ Cambiar ruta de endpoint β
+β β’ Cambiar metodo HTTP β
+β β’ Eliminar campo de response β
+β β’ Cambiar tipo de campo en response β
+β β’ Agregar campo requerido a request β
+β β’ Cambiar formato de error β
+β β
+β NON-BREAKING CHANGES (β
COMPATIBLES): β
+β β’ Agregar endpoint nuevo β
+β β’ Agregar campo opcional a request β
+β β’ Agregar campo a response β
+β β’ Agregar nuevo codigo de error β
+β β’ Mejorar mensaje de error β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. CAMBIOS EN RUTAS (BREAKING)
+
+### 2.1 Cambiar Ruta de Endpoint
+
+```typescript
+// ANTES
+@Get('users/by-email/:email')
+
+// DESPUES
+@Get('users/search/email/:email')
+```
+
+**Impacto:**
+
+| Componente | Impacto | Accion Requerida |
+|------------|---------|------------------|
+| Frontend Service | ROMPE | Actualizar URL |
+| Frontend Hooks | ROMPE | Actualizar llamadas |
+| Documentacion | Desactualizada | Actualizar |
+| Clientes externos | ROMPE | Notificar + migrar |
+| Tests e2e | ROMPE | Actualizar URLs |
+
+**Proceso de Migracion:**
+
+```
+OPCION A: Migracion Inmediata (proyectos internos)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Actualizar Frontend primero (cambiar URL)
+2. Actualizar Backend (cambiar ruta)
+3. Deploy coordinado
+
+OPCION B: Deprecacion Gradual (APIs publicas)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Agregar nueva ruta (mantener vieja)
+2. Marcar vieja como @Deprecated
+3. Notificar clientes
+4. Periodo de gracia (30-90 dias)
+5. Eliminar ruta vieja
+```
+
+**Implementacion Deprecacion:**
+
+```typescript
+// Mantener ambas rutas temporalmente
+@Get('users/by-email/:email')
+@ApiOperation({
+ summary: 'Buscar por email (DEPRECATED)',
+ deprecated: true,
+ description: 'Use GET /users/search/email/:email instead'
+})
+async findByEmailDeprecated(@Param('email') email: string) {
+ return this.findByEmail(email);
+}
+
+@Get('users/search/email/:email')
+@ApiOperation({ summary: 'Buscar usuario por email' })
+async findByEmail(@Param('email') email: string) {
+ return this.userService.findByEmail(email);
+}
+```
+
+### 2.2 Cambiar Prefijo de Controller
+
+```typescript
+// ANTES
+@Controller('products')
+
+// DESPUES
+@Controller('catalog/products')
+```
+
+**Impacto:** TODOS los endpoints del controller cambian de ruta.
+
+```
+ANTES:
+GET /api/products
+POST /api/products
+GET /api/products/:id
+
+DESPUES:
+GET /api/catalog/products
+POST /api/catalog/products
+GET /api/catalog/products/:id
+```
+
+**Checklist:**
+
+```
+[ ] 1. Buscar en frontend: grep -rn "/products" apps/
+[ ] 2. Actualizar TODOS los services que usan estos endpoints
+[ ] 3. Actualizar tests e2e
+[ ] 4. Actualizar documentacion
+[ ] 5. Verificar Swagger refleja cambios
+```
+
+---
+
+## 3. CAMBIOS EN METODO HTTP (BREAKING)
+
+### Cambiar Metodo
+
+```typescript
+// ANTES: Actualizar con POST
+@Post(':id/update')
+async update() {}
+
+// DESPUES: Actualizar con PUT (RESTful correcto)
+@Put(':id')
+async update() {}
+```
+
+**Impacto Frontend:**
+
+```typescript
+// ANTES
+const response = await api.post(`/users/${id}/update`, data);
+
+// DESPUES
+const response = await api.put(`/users/${id}`, data);
+```
+
+**Checklist:**
+
+```
+[ ] 1. Identificar todos los lugares que llaman al endpoint
+[ ] 2. Actualizar metodo HTTP en frontend service
+[ ] 3. Actualizar tests
+[ ] 4. Si API publica: periodo de deprecacion
+```
+
+---
+
+## 4. CAMBIOS EN REQUEST DTO
+
+### 4.1 Agregar Campo Requerido (BREAKING)
+
+```typescript
+// ANTES
+export class CreateOrderDto {
+ productId: string;
+ quantity: number;
+}
+
+// DESPUES - Nuevo campo requerido
+export class CreateOrderDto {
+ productId: string;
+ quantity: number;
+ @IsNotEmpty()
+ deliveryAddress: string; // β BREAKING: requerido
+}
+```
+
+**Impacto:**
+
+| Componente | Impacto | Accion |
+|------------|---------|--------|
+| Frontend Form | ROMPE | Agregar campo |
+| Frontend Zod | ROMPE | Agregar validacion |
+| Clientes existentes | ROMPE | Falla validacion |
+| Tests | ROMPE | Actualizar fixtures |
+
+**Mitigacion:**
+
+```typescript
+// OPCION 1: Hacer opcional con default
+@IsOptional()
+@IsString()
+deliveryAddress?: string = 'Por definir';
+
+// OPCION 2: Migrar en fases
+// Fase 1: Agregar como opcional
+// Fase 2: Poblar datos existentes
+// Fase 3: Hacer requerido
+```
+
+### 4.2 Agregar Campo Opcional (NON-BREAKING)
+
+```typescript
+// Agregar campo opcional - NO rompe
+export class CreateOrderDto {
+ productId: string;
+ quantity: number;
+
+ @IsOptional()
+ @IsString()
+ notes?: string; // β NON-BREAKING: opcional
+}
+```
+
+**Impacto:**
+
+| Componente | Impacto | Accion |
+|------------|---------|--------|
+| Frontend | Ninguno inmediato | Agregar si se quiere usar |
+| Clientes existentes | Ninguno | Siguen funcionando |
+| Tests | Ninguno | Siguen pasando |
+
+### 4.3 Eliminar Campo de Request (BREAKING si requerido)
+
+```typescript
+// ANTES
+export class CreateUserDto {
+ email: string;
+ password: string;
+ legacyCode: string; // β Se va a eliminar
+}
+
+// DESPUES
+export class CreateUserDto {
+ email: string;
+ password: string;
+ // legacyCode eliminado
+}
+```
+
+**Proceso:**
+
+```
+1. Hacer campo opcional primero (si era requerido)
+2. Marcar como @Deprecated en Swagger
+3. Ignorar en backend (no procesar)
+4. Notificar clientes
+5. Eliminar despues de periodo de gracia
+```
+
+### 4.4 Cambiar Validacion (Puede ser BREAKING)
+
+```typescript
+// ANTES: email cualquier formato
+@IsString()
+email: string;
+
+// DESPUES: email debe ser valido
+@IsEmail()
+email: string;
+```
+
+**Impacto:** Requests que antes pasaban ahora fallan.
+
+**Mitigacion:**
+
+```typescript
+// Agregar transformacion para casos edge
+@IsEmail()
+@Transform(({ value }) => value?.toLowerCase().trim())
+email: string;
+```
+
+---
+
+## 5. CAMBIOS EN RESPONSE DTO
+
+### 5.1 Eliminar Campo de Response (BREAKING)
+
+```typescript
+// ANTES
+export class UserResponseDto {
+ id: string;
+ email: string;
+ legacyCode: string; // β Se elimina
+}
+
+// DESPUES
+export class UserResponseDto {
+ id: string;
+ email: string;
+ // legacyCode eliminado
+}
+```
+
+**Impacto Frontend:**
+
+```typescript
+// Si frontend usa el campo, ROMPE
+const UserCard = ({ user }) => {
+ return
{user.legacyCode}
; // β TypeError: undefined
+};
+```
+
+**Proceso Seguro:**
+
+```
+1. Buscar uso en frontend: grep -rn "legacyCode" apps/
+2. Eliminar uso en frontend primero
+3. Luego eliminar de ResponseDto
+4. Deploy coordinado
+```
+
+### 5.2 Agregar Campo a Response (NON-BREAKING)
+
+```typescript
+// Agregar campo - NO rompe
+export class UserResponseDto {
+ id: string;
+ email: string;
+ createdAt: Date; // β Nuevo campo
+}
+```
+
+**Impacto:**
+
+- Frontend puede ignorar campos nuevos
+- TypeScript mostrara warning si interface no coincide
+- Actualizar interface en frontend eventualmente
+
+### 5.3 Cambiar Tipo de Campo (BREAKING)
+
+```typescript
+// ANTES
+export class ProductResponseDto {
+ price: number; // 99
+}
+
+// DESPUES
+export class ProductResponseDto {
+ price: string; // "99.00"
+}
+```
+
+**Impacto Frontend:**
+
+```typescript
+// ANTES funcionaba
+const total = product.price * quantity;
+
+// DESPUES rompe (string * number = NaN)
+const total = product.price * quantity; // NaN!
+
+// Debe cambiar a
+const total = parseFloat(product.price) * quantity;
+```
+
+### 5.4 Cambiar Estructura de Response (BREAKING)
+
+```typescript
+// ANTES: Array directo
+@Get()
+async findAll(): Promise {
+ return this.users;
+}
+// Response: [{ id: 1 }, { id: 2 }]
+
+// DESPUES: Objeto paginado
+@Get()
+async findAll(): Promise> {
+ return { data: this.users, total: 100, page: 1 };
+}
+// Response: { data: [...], total: 100, page: 1 }
+```
+
+**Impacto Frontend:**
+
+```typescript
+// ANTES
+const users = await api.get('/users');
+users.map(u => ...);
+
+// DESPUES
+const response = await api.get('/users');
+response.data.map(u => ...); // Acceder a .data
+```
+
+---
+
+## 6. CAMBIOS EN CODIGOS DE ERROR
+
+### 6.1 Agregar Nuevo Codigo (NON-BREAKING)
+
+```typescript
+// Agregar nueva excepcion - generalmente no rompe
+throw new ConflictException('Email already registered');
+// HTTP 409 - nuevo codigo
+```
+
+**Impacto:** Frontend deberia manejar, pero no rompe si no lo hace.
+
+### 6.2 Cambiar Codigo Existente (BREAKING)
+
+```typescript
+// ANTES: 400 para duplicado
+throw new BadRequestException('Email exists');
+
+// DESPUES: 409 para duplicado (correcto)
+throw new ConflictException('Email exists');
+```
+
+**Impacto:** Frontend que verifica status code especifico rompe.
+
+```typescript
+// Frontend que rompe
+if (error.status === 400 && error.message.includes('Email')) {
+ // Ya no entra aqui
+}
+
+// Frontend robusto
+if (error.status === 409 || error.message.includes('Email')) {
+ // Maneja ambos casos
+}
+```
+
+### 6.3 Cambiar Formato de Error (BREAKING)
+
+```typescript
+// ANTES
+{
+ "statusCode": 400,
+ "message": "Validation failed"
+}
+
+// DESPUES
+{
+ "error": {
+ "code": "VALIDATION_ERROR",
+ "message": "Validation failed",
+ "details": [...]
+ }
+}
+```
+
+**Impacto:** TODO el manejo de errores en frontend debe cambiar.
+
+---
+
+## 7. VERSIONADO DE API
+
+### Cuando Usar Versionado
+
+```
+USA VERSIONADO CUANDO:
+β’ API es consumida por clientes externos
+β’ Cambios breaking frecuentes
+β’ Necesitas mantener compatibilidad largo plazo
+
+NO NECESITAS VERSIONADO CUANDO:
+β’ Solo frontend interno consume la API
+β’ Puedes coordinar deploys
+β’ Equipo pequeno con comunicacion directa
+```
+
+### Implementacion de Versiones
+
+```typescript
+// Opcion 1: En URL
+@Controller('v1/users')
+export class UsersV1Controller {}
+
+@Controller('v2/users')
+export class UsersV2Controller {}
+
+// Opcion 2: En Header
+@Controller('users')
+@ApiHeader({ name: 'Api-Version', enum: ['1', '2'] })
+export class UsersController {
+ @Get()
+ findAll(@Headers('Api-Version') version: string) {
+ if (version === '2') {
+ return this.findAllV2();
+ }
+ return this.findAllV1();
+ }
+}
+```
+
+---
+
+## 8. CHECKLIST POR TIPO DE CAMBIO
+
+### Agregar Endpoint Nuevo
+
+```
+[ ] 1. Crear metodo en Controller
+[ ] 2. Agregar decoradores Swagger (@ApiOperation, @ApiResponse)
+[ ] 3. Crear/actualizar DTOs si necesario
+[ ] 4. Implementar en Service
+[ ] 5. Agregar tests
+[ ] 6. Actualizar Frontend service
+[ ] 7. Crear Frontend hook si necesario
+[ ] 8. Verificar Swagger
+```
+
+### Modificar Endpoint Existente (NON-BREAKING)
+
+```
+[ ] 1. Verificar que cambio es non-breaking
+[ ] 2. Actualizar Controller
+[ ] 3. Actualizar DTOs si necesario
+[ ] 4. Actualizar Swagger decoradores
+[ ] 5. Actualizar tests
+[ ] 6. Actualizar Frontend si aprovecha nuevas features
+```
+
+### Modificar Endpoint Existente (BREAKING)
+
+```
+[ ] 1. Evaluar: ΒΏse puede hacer non-breaking?
+[ ] 2. Buscar todos los consumidores: grep -rn "endpoint" apps/
+[ ] 3. Planear estrategia de migracion
+[ ] 4. Si API publica: crear version nueva, deprecar vieja
+[ ] 5. Si API interna: coordinar con frontend
+[ ] 6. Actualizar Frontend PRIMERO (apuntar a nuevo)
+[ ] 7. Actualizar Backend
+[ ] 8. Actualizar tests
+[ ] 9. Deploy coordinado
+[ ] 10. Eliminar codigo deprecated despues de periodo
+```
+
+### Eliminar Endpoint
+
+```
+[ ] 1. Buscar todos los usos: grep -rn "endpoint" apps/ tests/
+[ ] 2. Eliminar uso en Frontend
+[ ] 3. Eliminar tests del endpoint
+[ ] 4. Marcar como @Deprecated (si API publica)
+[ ] 5. Periodo de gracia
+[ ] 6. Eliminar de Controller
+[ ] 7. Limpiar Service si metodos quedan sin usar
+```
+
+---
+
+## 9. FRONTEND: ADAPTARSE A CAMBIOS API
+
+### Service Layer Pattern
+
+```typescript
+// Encapsular llamadas API en service
+// Facilita cambiar cuando API cambia
+
+// user.service.ts
+export const userService = {
+ // Si cambia la ruta, solo cambiar aqui
+ getAll: () => api.get('/users'),
+
+ // Si cambia estructura response
+ getAllPaginated: async (page: number) => {
+ const response = await api.get>('/users', { params: { page } });
+ return response.data; // Extraer data aqui
+ },
+
+ // Si cambia metodo HTTP
+ update: (id: string, data: UpdateUserDto) =>
+ api.put(`/users/${id}`, data), // Cambiar postβput aqui
+};
+```
+
+### Type Guards para Cambios de Estructura
+
+```typescript
+// Manejar diferentes versiones de response
+interface UserV1 {
+ name: string;
+}
+
+interface UserV2 {
+ firstName: string;
+ lastName: string;
+}
+
+function isUserV2(user: UserV1 | UserV2): user is UserV2 {
+ return 'firstName' in user;
+}
+
+function getDisplayName(user: UserV1 | UserV2): string {
+ if (isUserV2(user)) {
+ return `${user.firstName} ${user.lastName}`;
+ }
+ return user.name;
+}
+```
+
+---
+
+## 10. MATRIZ DE DECISION
+
+```
+ΒΏEs BREAKING CHANGE?
+ β
+ βΌ
+ ββββββββββββββ
+ β ΒΏCambio de ββββNOββββΆ Implementar directamente
+ β ruta? β Actualizar Swagger
+ ββββββββββββββ Actualizar Frontend (opcional)
+ β
+ YES
+ β
+ βΌ
+ ββββββββββββββ
+ β ΒΏAPI ββββNOββββΆ Actualizar Frontend PRIMERO
+ β publica? β Luego actualizar Backend
+ ββββββββββββββ Deploy coordinado
+ β
+ YES
+ β
+ βΌ
+ ββββββββββββββββββββββββββββββββββββββββββ
+ β 1. Crear endpoint nuevo β
+ β 2. Deprecar endpoint viejo β
+ β 3. Notificar clientes β
+ β 4. Periodo de gracia (30-90 dias) β
+ β 5. Eliminar endpoint viejo β
+ ββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 11. COMANDOS UTILES
+
+```bash
+# Ver todos los endpoints actuales
+curl http://localhost:3000/api-json | jq '.paths | keys'
+
+# Ver detalle de un endpoint
+curl http://localhost:3000/api-json | jq '.paths["/users/{id}"]'
+
+# Buscar uso de endpoint en frontend
+grep -rn "users" apps/*/services/
+grep -rn "/api/users" apps/
+
+# Comparar Swagger entre versiones
+diff <(curl -s http://localhost:3000/api-json | jq -S) \
+ <(curl -s http://production/api-json | jq -S)
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guia de Impacto
diff --git a/core/orchestration/impactos/IMPACTO-CAMBIOS-BACKEND.md b/core/orchestration/impactos/IMPACTO-CAMBIOS-BACKEND.md
new file mode 100644
index 0000000..77d8063
--- /dev/null
+++ b/core/orchestration/impactos/IMPACTO-CAMBIOS-BACKEND.md
@@ -0,0 +1,498 @@
+# IMPACTO DE CAMBIOS EN BACKEND
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Consultar antes de modificar Backend
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Documentar la cascada de cambios que ocurre cuando se modifica cualquier componente del Backend (Entity, DTO, Service, Controller) y su impacto en Frontend.
+
+---
+
+## 1. MATRIZ DE IMPACTO POR COMPONENTE
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β CAMBIO EN BACKEND β IMPACTO EN CAPAS β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ENTITY DTO SERVICE CONTROLLER FRONTEND β
+β βββββββ βββββββ βββββββ βββββββ βββββββ β
+β β ββββββββΆβ βββββββββΆβ βββββββββΆβ βββββββββΆβ β β
+β βββββββ βββββββ βββββββ βββββββ βββββββ β
+β β β β β β β
+β βΌ βΌ βΌ βΌ βΌ β
+β Refleja Valida Logica Endpoints Types β
+β DDL Input Negocio REST Zod β
+β Hooks β
+β Components β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. CAMBIOS EN ENTITY
+
+### 2.1 Agregar Campo a Entity
+
+```typescript
+// CAMBIO: Agregar campo 'phone' a UserEntity
+@Column({ type: 'varchar', length: 20, nullable: true })
+phone: string | null;
+```
+
+**Cascada de Cambios:**
+
+| Capa | Archivo | Accion | Obligatorio |
+|------|---------|--------|-------------|
+| DDL | `XX-users.sql` | Agregar columna (DDL-First) | SI - PRIMERO |
+| Entity | `user.entity.ts` | Ya agregado | SI |
+| CreateDto | `create-user.dto.ts` | Agregar campo + validacion | SI |
+| UpdateDto | `update-user.dto.ts` | Hereda de CreateDto | AUTO |
+| ResponseDto | `user-response.dto.ts` | Agregar campo | SI |
+| Service | `user.service.ts` | Sin cambios (TypeORM maneja) | NO |
+| Controller | `user.controller.ts` | Sin cambios | NO |
+| **Frontend** | `user.types.ts` | Agregar campo a interface | SI |
+| **Frontend** | `user.schema.ts` | Agregar a Zod schema | SI |
+| **Frontend** | `UserForm.tsx` | Agregar input si editable | CONDICIONAL |
+
+**Checklist:**
+
+```
+[ ] 1. DDL tiene la columna (DDL-First)
+[ ] 2. Entity refleja DDL exactamente
+[ ] 3. CreateDto tiene validacion apropiada
+[ ] 4. ResponseDto incluye el campo
+[ ] 5. Swagger muestra campo correctamente
+[ ] 6. Frontend types actualizados
+[ ] 7. Frontend Zod schema actualizado
+[ ] 8. Componentes de formulario actualizados (si aplica)
+[ ] 9. npm run build (backend)
+[ ] 10. npm run build (frontend)
+[ ] 11. npm run typecheck (frontend)
+```
+
+### 2.2 Eliminar Campo de Entity
+
+```typescript
+// CAMBIO: Eliminar campo 'legacyCode' de ProductEntity
+// @Column() legacyCode: string; // ELIMINADO
+```
+
+**Cascada de Cambios:**
+
+| Capa | Archivo | Accion | Obligatorio |
+|------|---------|--------|-------------|
+| DDL | `XX-products.sql` | DROP COLUMN (con migracion) | SI - PRIMERO |
+| Entity | `product.entity.ts` | Eliminar @Column | SI |
+| CreateDto | `create-product.dto.ts` | Eliminar campo | SI |
+| UpdateDto | `update-product.dto.ts` | Hereda cambio | AUTO |
+| ResponseDto | `product-response.dto.ts` | Eliminar campo | SI |
+| Service | `product.service.ts` | Eliminar referencias | VERIFICAR |
+| Controller | `product.controller.ts` | Eliminar de queries | VERIFICAR |
+| **Frontend** | `product.types.ts` | Eliminar de interface | SI |
+| **Frontend** | `product.schema.ts` | Eliminar de Zod | SI |
+| **Frontend** | Componentes | Eliminar referencias | SI |
+
+**ADVERTENCIA:**
+
+```
+β οΈ ANTES DE ELIMINAR UN CAMPO:
+1. Buscar TODAS las referencias en backend: grep -r "legacyCode" src/
+2. Buscar TODAS las referencias en frontend: grep -r "legacyCode" apps/
+3. Verificar que no hay datos importantes en la columna
+4. Considerar soft-delete o campo deprecated primero
+```
+
+### 2.3 Cambiar Tipo de Campo
+
+```typescript
+// CAMBIO: price de number a Decimal
+// ANTES
+@Column({ type: 'integer' })
+price: number;
+
+// DESPUES
+@Column({ type: 'decimal', precision: 10, scale: 2 })
+price: string; // String para precision decimal
+```
+
+**Cascada de Cambios:**
+
+| Capa | Archivo | Accion | Obligatorio |
+|------|---------|--------|-------------|
+| DDL | `XX-products.sql` | ALTER COLUMN type | SI - PRIMERO |
+| Entity | `product.entity.ts` | Cambiar tipo TS | SI |
+| CreateDto | `create-product.dto.ts` | Cambiar validador | SI |
+| ResponseDto | `product-response.dto.ts` | Cambiar tipo | SI |
+| Service | `product.service.ts` | Ajustar transformaciones | VERIFICAR |
+| **Frontend** | `product.types.ts` | Cambiar tipo | SI |
+| **Frontend** | `product.schema.ts` | Cambiar validador Zod | SI |
+| **Frontend** | Componentes | Ajustar formateo/parsing | SI |
+
+---
+
+## 3. CAMBIOS EN DTO
+
+### 3.1 Agregar Validacion a DTO
+
+```typescript
+// CAMBIO: Agregar validacion de formato a email
+@IsEmail({}, { message: 'Email invalido' })
+@MaxLength(255)
+@Transform(({ value }) => value?.toLowerCase().trim())
+email: string;
+```
+
+**Impacto:**
+
+| Capa | Impacto | Accion Requerida |
+|------|---------|------------------|
+| Entity | Ninguno | - |
+| Service | Ninguno | - |
+| Controller | Ninguno (validacion automatica) | - |
+| Swagger | Actualiza automaticamente | Verificar |
+| **Frontend** | Debe sincronizar validacion | Actualizar Zod |
+
+**Frontend debe reflejar:**
+
+```typescript
+// Zod schema debe coincidir con backend
+const userSchema = z.object({
+ email: z.string()
+ .email('Email invalido')
+ .max(255)
+ .transform(v => v.toLowerCase().trim()),
+});
+```
+
+### 3.2 Agregar Campo a ResponseDto
+
+```typescript
+// CAMBIO: Agregar campo calculado 'fullName'
+@ApiProperty({ example: 'Juan Perez' })
+fullName: string;
+```
+
+**Impacto:**
+
+| Capa | Impacto | Accion Requerida |
+|------|---------|------------------|
+| Entity | Ninguno (campo calculado) | - |
+| Service | Debe calcular el campo | Agregar logica |
+| Controller | Ninguno | - |
+| **Frontend** | Debe tipar el campo | Actualizar interface |
+
+**Service debe mapear:**
+
+```typescript
+// En service
+toResponseDto(entity: UserEntity): UserResponseDto {
+ return {
+ ...entity,
+ fullName: `${entity.firstName} ${entity.lastName}`,
+ };
+}
+```
+
+---
+
+## 4. CAMBIOS EN SERVICE
+
+### 4.1 Agregar Metodo al Service
+
+```typescript
+// CAMBIO: Agregar metodo de busqueda avanzada
+async searchByFilters(filters: SearchFiltersDto): Promise {
+ // ...
+}
+```
+
+**Impacto:**
+
+| Capa | Impacto | Accion Requerida |
+|------|---------|------------------|
+| Entity | Ninguno | - |
+| DTO | Crear SearchFiltersDto | SI |
+| Controller | Exponer endpoint | SI |
+| **Frontend** | Crear servicio + hook | SI |
+
+### 4.2 Modificar Logica de Negocio
+
+```typescript
+// CAMBIO: Agregar validacion de negocio en create
+async create(dto: CreateOrderDto): Promise {
+ // NUEVA: Validar stock antes de crear
+ await this.validateStock(dto.items);
+ // ... resto
+}
+```
+
+**Impacto:**
+
+| Capa | Impacto | Accion Requerida |
+|------|---------|------------------|
+| Entity | Ninguno | - |
+| DTO | Posible nuevo error response | Documentar |
+| Controller | Ninguno | - |
+| Swagger | Documentar nuevo error | SI |
+| **Frontend** | Manejar nuevo error | SI |
+
+**Frontend debe manejar:**
+
+```typescript
+// Hook debe manejar error especifico
+const { mutate } = useCreateOrder({
+ onError: (error) => {
+ if (error.message.includes('stock')) {
+ toast.error('Stock insuficiente');
+ }
+ }
+});
+```
+
+---
+
+## 5. CAMBIOS EN CONTROLLER
+
+### 5.1 Agregar Endpoint
+
+```typescript
+// CAMBIO: Agregar endpoint de exportacion
+@Get('export')
+@ApiOperation({ summary: 'Exportar usuarios a CSV' })
+async exportToCsv(): Promise {
+ // ...
+}
+```
+
+**Impacto Frontend:**
+
+| Componente | Accion Requerida |
+|------------|------------------|
+| `user.service.ts` | Agregar metodo `exportToCsv()` |
+| `useExportUsers.ts` | Crear hook (si necesario) |
+| Componente UI | Agregar boton de exportar |
+
+### 5.2 Modificar Ruta de Endpoint
+
+```typescript
+// CAMBIO: Renombrar endpoint
+// ANTES: @Get('by-email/:email')
+// DESPUES: @Get('search/email/:email')
+```
+
+**ADVERTENCIA - BREAKING CHANGE:**
+
+```
+β οΈ CAMBIO DE RUTA ES BREAKING CHANGE
+
+PROCESO OBLIGATORIO:
+1. Verificar que frontend no usa la ruta antigua
+2. Si usa: Actualizar frontend PRIMERO
+3. Considerar: Mantener ruta antigua con @Deprecated
+4. Documentar en CHANGELOG
+
+BUSCAR EN FRONTEND:
+grep -r "by-email" apps/
+grep -r "users/by-email" apps/
+```
+
+### 5.3 Cambiar Metodo HTTP
+
+```typescript
+// CAMBIO: De POST a PUT para update
+// ANTES: @Post(':id/update')
+// DESPUES: @Put(':id')
+```
+
+**Impacto Frontend:**
+
+```typescript
+// ANTES
+await api.post(`/users/${id}/update`, data);
+
+// DESPUES
+await api.put(`/users/${id}`, data);
+```
+
+---
+
+## 6. SINCRONIZACION BACKEND-FRONTEND
+
+### 6.1 Mapeo de Tipos
+
+| Backend (NestJS) | Frontend (TypeScript) | Notas |
+|------------------|----------------------|-------|
+| `string` | `string` | Directo |
+| `number` | `number` | Directo |
+| `boolean` | `boolean` | Directo |
+| `Date` | `string` | ISO string en JSON |
+| `Decimal` (string) | `string` o `number` | Parsear si necesario |
+| `UUID` | `string` | Directo |
+| `enum Status` | `type Status = ...` | Replicar valores |
+| `T[]` | `T[]` | Directo |
+| `T \| null` | `T \| null` | Directo |
+
+### 6.2 Patron de Sincronizacion
+
+```typescript
+// BACKEND: ResponseDto define contrato
+export class UserResponseDto {
+ @ApiProperty()
+ id: string;
+
+ @ApiProperty()
+ email: string;
+
+ @ApiProperty({ enum: UserStatus })
+ status: UserStatus;
+
+ @ApiProperty()
+ createdAt: Date; // Se serializa como ISO string
+}
+
+// FRONTEND: Interface refleja ResponseDto
+export interface User {
+ id: string;
+ email: string;
+ status: UserStatus;
+ createdAt: string; // String porque viene de JSON
+}
+
+// FRONTEND: Enum replicado
+export enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+}
+
+// FRONTEND: Zod refleja CreateDto
+export const createUserSchema = z.object({
+ email: z.string().email(),
+ // ... campos de CreateUserDto
+});
+```
+
+### 6.3 Checklist de Sincronizacion
+
+```
+Cuando cambias Backend, verificar en Frontend:
+
+[ ] 1. Interfaces actualizadas (types/*.ts)
+[ ] 2. Enums sincronizados
+[ ] 3. Zod schemas actualizados
+[ ] 4. Services API actualizados
+[ ] 5. Hooks actualizados (si cambia endpoint)
+[ ] 6. Componentes manejan nuevos campos
+[ ] 7. Componentes manejan campos eliminados
+[ ] 8. Manejo de errores actualizado
+[ ] 9. npm run typecheck pasa
+[ ] 10. npm run build pasa
+```
+
+---
+
+## 7. COMANDOS DE VERIFICACION
+
+```bash
+# Buscar referencias a campo en backend
+grep -rn "fieldName" src/
+
+# Buscar referencias a campo en frontend
+grep -rn "fieldName" apps/ shared/
+
+# Verificar tipos TypeScript
+npm run typecheck
+
+# Verificar que Swagger refleja cambios
+curl http://localhost:3000/api-json | jq '.paths["/users"]'
+
+# Comparar DTO con Interface
+diff <(grep -A 50 "class UserResponseDto" src/modules/user/dto/user-response.dto.ts) \
+ <(grep -A 50 "interface User" apps/web/types/user.types.ts)
+```
+
+---
+
+## 8. ANTI-PATRONES
+
+### Anti-Patron 1: Cambiar Backend sin Frontend
+
+```
+β INCORRECTO:
+1. Backend-Agent agrega campo a ResponseDto
+2. Se hace deploy
+3. Frontend falla porque no espera el campo (usualmente OK)
+4. O peor: Frontend espera campo que ya no existe (ROMPE)
+
+β
CORRECTO:
+1. Backend-Agent agrega campo
+2. Frontend-Agent actualiza types ANTES de deploy
+3. Deploy coordinado
+```
+
+### Anti-Patron 2: Tipos Diferentes
+
+```
+β INCORRECTO:
+// Backend
+@Column({ type: 'decimal' })
+price: string; // String para precision
+
+// Frontend
+interface Product {
+ price: number; // β INCORRECTO: tipo diferente
+}
+
+β
CORRECTO:
+// Frontend
+interface Product {
+ price: string; // String como backend
+}
+
+// O usar transformacion explicita
+const displayPrice = parseFloat(product.price).toFixed(2);
+```
+
+### Anti-Patron 3: Validaciones Desincronizadas
+
+```
+β INCORRECTO:
+// Backend: max 100 caracteres
+@MaxLength(100)
+name: string;
+
+// Frontend: max 50 caracteres
+const schema = z.object({
+ name: z.string().max(50) // β INCORRECTO: limite diferente
+});
+
+β
CORRECTO:
+// Mismos limites en ambos lados
+// Backend: @MaxLength(100)
+// Frontend: z.string().max(100)
+```
+
+---
+
+## 9. MATRIZ RESUMEN
+
+| Si Cambias... | Actualiza en Backend | Actualiza en Frontend |
+|---------------|---------------------|----------------------|
+| Entity campo | DTO, posible Service | Types, Schema, Components |
+| Entity relacion | DTO, Service | Types, Hooks |
+| CreateDto campo | - | Schema (Zod) |
+| CreateDto validacion | - | Schema (Zod) |
+| ResponseDto campo | Service (si calculado) | Types, Components |
+| Service metodo | Controller (si expuesto) | Service, Hook |
+| Service logica | - | Manejo errores |
+| Controller endpoint | Swagger | Service, Hook |
+| Controller ruta | Swagger | Service (URL) |
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guia de Impacto
diff --git a/core/orchestration/impactos/IMPACTO-CAMBIOS-DDL.md b/core/orchestration/impactos/IMPACTO-CAMBIOS-DDL.md
new file mode 100644
index 0000000..14b425b
--- /dev/null
+++ b/core/orchestration/impactos/IMPACTO-CAMBIOS-DDL.md
@@ -0,0 +1,428 @@
+# IMPACTO: CAMBIOS EN DDL (Base de Datos)
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** CRΓTICA - Leer antes de modificar DDL
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPΓSITO
+
+Documentar el impacto cascada de cambios en DDL y las acciones requeridas en cada capa.
+
+---
+
+## PRINCIPIO FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β CAMBIO EN DDL = CAMBIO EN CASCADA β
+β β
+β DDL β Entity β DTO β Service β Controller β Frontend β
+β β
+β β οΈ NUNCA cambiar DDL sin actualizar las capas dependientes β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 1. AGREGAR COLUMNA
+
+### Impacto por Capa
+
+| Capa | Archivo(s) Afectado(s) | AcciΓ³n Requerida |
+|------|------------------------|------------------|
+| **DDL** | `schemas/{schema}/tables/{tabla}.sql` | Agregar columna |
+| **Entity** | `{nombre}.entity.ts` | Agregar @Column |
+| **DTO Create** | `create-{nombre}.dto.ts` | Agregar campo (si input) |
+| **DTO Update** | `update-{nombre}.dto.ts` | Heredado de Create |
+| **DTO Response** | `{nombre}-response.dto.ts` | Agregar campo (si output) |
+| **Service** | `{nombre}.service.ts` | Ajustar lΓ³gica si necesario |
+| **Controller** | `{nombre}.controller.ts` | Swagger actualizado automΓ‘tico |
+| **Frontend Types** | `{nombre}.types.ts` | Agregar campo |
+| **Frontend Forms** | `{Nombre}Form.tsx` | Agregar input (si editable) |
+| **Frontend Display** | `{Nombre}Card.tsx`, etc. | Mostrar campo (si visible) |
+| **Tests** | `*.spec.ts`, `*.test.tsx` | Actualizar fixtures |
+
+### Checklist: Agregar Columna
+
+```
+DDL (Database-Agent):
+[ ] ALTER TABLE o modificar CREATE TABLE
+[ ] Definir tipo correcto (ver MAPEO-TIPOS.md)
+[ ] Definir NULL/NOT NULL
+[ ] Definir DEFAULT si aplica
+[ ] Crear Γndice si es buscable
+[ ] Ejecutar carga limpia exitosa
+[ ] Actualizar DATABASE_INVENTORY.yml
+
+Backend (Backend-Agent):
+[ ] Agregar @Column en Entity
+ - type: coincide con DDL
+ - nullable: coincide con DDL
+ - default: coincide con DDL
+[ ] Agregar campo en CreateDto (si es input)
+ - Validaciones apropiadas
+ - @ApiProperty con ejemplo
+[ ] Agregar campo en ResponseDto (si es output)
+[ ] Ajustar Service si hay lΓ³gica nueva
+[ ] npm run build β pasa
+[ ] npm run lint β pasa
+[ ] Actualizar BACKEND_INVENTORY.yml
+
+Frontend (Frontend-Agent):
+[ ] Agregar campo en interface/type
+[ ] Actualizar Zod schema si hay form
+[ ] Agregar input en formulario (si editable)
+[ ] Mostrar en UI (si visible)
+[ ] npm run build β pasa
+[ ] npm run lint β pasa
+[ ] Actualizar FRONTEND_INVENTORY.yml
+
+IntegraciΓ³n:
+[ ] Test e2e funciona
+[ ] Swagger muestra campo nuevo
+[ ] Frontend consume correctamente
+```
+
+### Ejemplo Completo: Agregar Campo `phone`
+
+**1. DDL:**
+```sql
+-- schemas/auth/tables/01-users.sql
+ALTER TABLE auth.users
+ADD COLUMN phone VARCHAR(20);
+```
+
+**2. Entity:**
+```typescript
+// entities/user.entity.ts
+@Column({ type: 'varchar', length: 20, nullable: true })
+phone: string;
+```
+
+**3. DTO Create:**
+```typescript
+// dto/create-user.dto.ts
+@ApiPropertyOptional({ description: 'TelΓ©fono', example: '+521234567890' })
+@IsOptional()
+@IsPhoneNumber('MX')
+phone?: string;
+```
+
+**4. DTO Response:**
+```typescript
+// dto/user-response.dto.ts
+@ApiPropertyOptional()
+phone?: string;
+```
+
+**5. Frontend Type:**
+```typescript
+// types/user.types.ts
+interface User {
+ id: string;
+ email: string;
+ name: string;
+ phone?: string; // β NUEVO
+}
+```
+
+**6. Frontend Form:**
+```typescript
+// components/UserForm.tsx
+
+```
+
+---
+
+## 2. ELIMINAR COLUMNA
+
+### Impacto por Capa
+
+| Capa | AcciΓ³n | Riesgo |
+|------|--------|--------|
+| **DDL** | `ALTER TABLE DROP COLUMN` | ALTO - Datos perdidos |
+| **Entity** | Eliminar @Column | MEDIO |
+| **DTO** | Eliminar campo | MEDIO |
+| **Service** | Eliminar referencias | ALTO - LΓ³gica rota |
+| **Frontend** | Eliminar campo y usos | ALTO - UI rota |
+| **Tests** | Actualizar fixtures | MEDIO |
+
+### Checklist: Eliminar Columna
+
+```
+β οΈ ANTES DE ELIMINAR:
+[ ] Confirmar que datos no son necesarios
+[ ] Verificar que no hay dependencias en cΓ³digo
+[ ] Grep en todo el proyecto: grep -rn "{columna}" apps/
+[ ] Planificar migraciΓ³n de datos si necesario
+
+DDL:
+[ ] ALTER TABLE DROP COLUMN
+[ ] Verificar que no rompe constraints/FK
+[ ] Carga limpia exitosa
+
+Backend:
+[ ] Eliminar @Column de Entity
+[ ] Eliminar de DTOs
+[ ] Buscar y eliminar referencias en Services
+[ ] npm run build β sin errores de tipo
+[ ] npm run test β pasa
+
+Frontend:
+[ ] Eliminar de types/interfaces
+[ ] Eliminar de formularios
+[ ] Eliminar de displays
+[ ] npm run build β sin errores de tipo
+
+Post-eliminaciΓ³n:
+[ ] Verificar que aplicaciΓ³n funciona
+[ ] Verificar que no hay errores en consola
+[ ] Actualizar documentaciΓ³n
+```
+
+---
+
+## 3. MODIFICAR TIPO DE COLUMNA
+
+### Impacto por Capa
+
+| Cambio | Backend | Frontend | Riesgo |
+|--------|---------|----------|--------|
+| `VARCHAR(50)` β `VARCHAR(100)` | Cambiar length | - | BAJO |
+| `VARCHAR` β `TEXT` | Cambiar type | - | BAJO |
+| `INTEGER` β `BIGINT` | `number` β `string` | Cambiar tipo | MEDIO |
+| `VARCHAR` β `ENUM` | Agregar enum | Agregar enum | MEDIO |
+| `TEXT` β `JSON` | Cambiar tipo, parsear | Cambiar tipo | ALTO |
+
+### Checklist: Modificar Tipo
+
+```
+DDL:
+[ ] ALTER TABLE ALTER COLUMN TYPE
+[ ] Verificar que datos existentes son compatibles
+[ ] Carga limpia exitosa
+
+Backend:
+[ ] Actualizar @Column type
+[ ] Actualizar tipo TypeScript si cambiΓ³
+[ ] Actualizar validaciones en DTO
+[ ] npm run build β pasa
+
+Frontend:
+[ ] Actualizar tipo en interface
+[ ] Actualizar validaciΓ³n Zod
+[ ] Ajustar componentes si tipo cambiΓ³
+[ ] npm run build β pasa
+
+Datos:
+[ ] Migrar datos existentes si necesario
+[ ] Validar integridad post-migraciΓ³n
+```
+
+---
+
+## 4. AGREGAR/MODIFICAR FOREIGN KEY
+
+### Impacto por Capa
+
+| Capa | AcciΓ³n |
+|------|--------|
+| **DDL** | Agregar FK + Γndice |
+| **Entity** | Agregar @ManyToOne + @JoinColumn |
+| **Service** | Validar existencia antes de insertar |
+| **DTO** | Agregar campo ID de relaciΓ³n |
+| **Frontend** | Agregar selector/dropdown |
+
+### Checklist: Agregar FK
+
+```
+DDL:
+[ ] Agregar columna FK (UUID)
+[ ] Agregar FOREIGN KEY constraint
+[ ] Definir ON DELETE (CASCADE/SET NULL/RESTRICT)
+[ ] Crear Γndice en FK
+[ ] Verificar que tabla referenciada existe
+
+Backend:
+[ ] Agregar columna en Entity: {relation}Id: string
+[ ] Agregar relaciΓ³n: @ManyToOne(() => RelatedEntity)
+[ ] Agregar @JoinColumn({ name: '{relation}_id' })
+[ ] Validar existencia en Service antes de crear
+[ ] Agregar en DTO con @IsUUID
+
+Frontend:
+[ ] Agregar campo en type
+[ ] Crear selector si es editable
+[ ] Mostrar relaciΓ³n en UI
+```
+
+---
+
+## 5. AGREGAR/MODIFICAR ΓNDICE
+
+### Impacto
+
+- **DDL**: Agregar `CREATE INDEX`
+- **Otras capas**: Sin impacto directo
+- **Performance**: Mejora en queries
+
+### Checklist: Agregar Γndice
+
+```
+[ ] Identificar columnas frecuentemente buscadas
+[ ] Agregar CREATE INDEX en DDL
+[ ] Para bΓΊsquedas compuestas: Γndice compuesto
+[ ] Ejecutar carga limpia
+[ ] Verificar plan de query (EXPLAIN)
+```
+
+---
+
+## 6. AGREGAR TABLA NUEVA
+
+### Impacto Completo
+
+```
+NUEVA TABLA = Feature completa
+
+DDL:
+βββ CREATE TABLE con todas las columnas
+βββ PRIMARY KEY
+βββ FOREIGN KEYS
+βββ INDEXES
+βββ COMMENTS
+βββ Actualizar DATABASE_INVENTORY.yml
+
+Backend:
+βββ {nombre}.entity.ts
+βββ create-{nombre}.dto.ts
+βββ update-{nombre}.dto.ts
+βββ {nombre}-response.dto.ts
+βββ {nombre}.service.ts
+βββ {nombre}.controller.ts
+βββ {nombre}.module.ts
+βββ Tests unitarios
+βββ Actualizar BACKEND_INVENTORY.yml
+
+Frontend:
+βββ {nombre}.types.ts
+βββ {nombre}.service.ts (API calls)
+βββ use{Nombre}.ts (hook)
+βββ {Nombre}Form.tsx
+βββ {Nombre}List.tsx
+βββ {Nombre}Page.tsx
+βββ Tests de componentes
+βββ Actualizar FRONTEND_INVENTORY.yml
+```
+
+---
+
+## 7. ELIMINAR TABLA
+
+### Impacto CRΓTICO
+
+```
+β οΈ ELIMINAR TABLA = DESTRUIR FEATURE
+
+ANTES de eliminar:
+[ ] Confirmar que feature ya no se usa
+[ ] Backup de datos si necesario
+[ ] Verificar que no hay FK apuntando a esta tabla
+[ ] Grep completo: grep -rn "{tabla}" apps/
+
+Orden de eliminaciΓ³n (inverso a creaciΓ³n):
+1. Frontend: Eliminar pΓ‘ginas, componentes, types
+2. Backend: Eliminar controller, service, entity, DTOs, module
+3. DDL: DROP TABLE
+4. Actualizar todos los inventarios
+
+Post-eliminaciΓ³n:
+[ ] Build pasa en todas las capas
+[ ] AplicaciΓ³n funciona sin errores
+[ ] DocumentaciΓ³n actualizada
+```
+
+---
+
+## 8. MATRIZ DE PROPAGACIΓN RΓPIDA
+
+```
+βββββββββββββββββββ¬ββββββββββ¬βββββββββ¬ββββββββββ¬βββββββββββ¬βββββββββββ
+β Cambio DDL β Entity β DTO β Service β Frontend β Tests β
+βββββββββββββββββββΌββββββββββΌβββββββββΌββββββββββΌβββββββββββΌβββββββββββ€
+β + Columna β +Column β +Field β ?LΓ³gica β +Type β +Fixture β
+β - Columna β -Column β -Field β -Refs β -Type β -Fixture β
+β ~ Tipo β ~Type β ~Valid β ?Parse β ~Type β ~Fixture β
+β + FK β +Rel β +UUID β +Valid β +Select β +Test β
+β + Γndice β - β - β - β - β - β
+β + Tabla β +Todo β +Todo β +Todo β +Todo β +Todo β
+β - Tabla β -Todo β -Todo β -Todo β -Todo β -Todo β
+βββββββββββββββββββ΄ββββββββββ΄βββββββββ΄ββββββββββ΄βββββββββββ΄βββββββββββ
+
+Leyenda:
++ = Agregar
+- = Eliminar
+~ = Modificar
+? = Posiblemente
+```
+
+---
+
+## 9. COMANDOS DE VERIFICACIΓN
+
+```bash
+# Verificar que cambio DDL no rompe
+cd {DB_SCRIPTS_PATH}
+./recreate-database.sh # Carga limpia completa
+
+# Verificar build backend
+cd {BACKEND_ROOT}
+npm run build && npm run lint
+
+# Verificar build frontend
+cd {FRONTEND_ROOT}
+npm run build && npm run lint && npm run typecheck
+
+# Buscar referencias a columna/tabla
+grep -rn "{nombre}" apps/
+
+# Verificar alineaciΓ³n Entity-DDL
+# Comparar @Column en Entity vs columnas en DDL
+```
+
+---
+
+## 10. ANTI-PATRONES
+
+```
+β NUNCA: Cambiar DDL sin actualizar Entity
+ β Resultado: Runtime error al acceder columna
+
+β NUNCA: Agregar columna NOT NULL sin DEFAULT
+ β Resultado: INSERT falla en registros existentes
+
+β NUNCA: Eliminar columna sin verificar uso
+ β Resultado: CΓ³digo roto en mΓΊltiples lugares
+
+β NUNCA: Cambiar tipo sin migrar datos
+ β Resultado: Datos corruptos o perdidos
+
+β NUNCA: Modificar FK sin ajustar relaciones en Entity
+ β Resultado: ORM genera queries incorrectas
+
+β
SIEMPRE: DDL primero β Entity segundo β DTO tercero β Frontend cuarto
+β
SIEMPRE: Verificar build en TODAS las capas despuΓ©s de cambio
+β
SIEMPRE: Actualizar inventarios y trazas
+β
SIEMPRE: Grep antes de eliminar para encontrar usos
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** GuΓa de Impacto
diff --git a/core/orchestration/impactos/IMPACTO-CAMBIOS-ENTITY.md b/core/orchestration/impactos/IMPACTO-CAMBIOS-ENTITY.md
new file mode 100644
index 0000000..7c7974a
--- /dev/null
+++ b/core/orchestration/impactos/IMPACTO-CAMBIOS-ENTITY.md
@@ -0,0 +1,439 @@
+# IMPACTO DE CAMBIOS EN ENTITY
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Consultar antes de modificar Entities
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Documentar especificamente los impactos de modificar Entities de TypeORM, que son el puente entre la base de datos y la logica de negocio.
+
+---
+
+## 1. PRINCIPIO FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β ENTITY ES REFLEJO DE DDL, NO AL REVES β
+β β
+β DDL (fuente) βββββββΆ Entity (reflejo) βββββββΆ DTO (contrato API) β
+β β
+β β οΈ NUNCA crear Entity sin DDL existente β
+β β οΈ NUNCA modificar Entity sin verificar DDL primero β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. TIPOS DE CAMBIOS EN ENTITY
+
+### 2.1 Cambios de Columna
+
+| Tipo de Cambio | Impacto DDL | Impacto DTO | Impacto Service | Impacto Frontend |
+|----------------|-------------|-------------|-----------------|------------------|
+| Agregar campo | SI | SI | Posible | SI |
+| Eliminar campo | SI | SI | Verificar | SI |
+| Renombrar campo | SI | SI | SI | SI |
+| Cambiar tipo | SI | SI | Posible | SI |
+| Cambiar nullable | SI | SI | Posible | SI |
+| Agregar default | SI | Posible | NO | NO |
+
+### 2.2 Cambios de Relacion
+
+| Tipo de Cambio | Impacto DDL | Impacto DTO | Impacto Service | Impacto Frontend |
+|----------------|-------------|-------------|-----------------|------------------|
+| Agregar ManyToOne | SI (FK) | SI | SI | SI |
+| Agregar OneToMany | NO | SI | SI | SI |
+| Agregar ManyToMany | SI (junction) | SI | SI | SI |
+| Eliminar relacion | SI | SI | SI | SI |
+| Cambiar cascade | NO | NO | Verificar | NO |
+
+### 2.3 Cambios de Indice/Constraint
+
+| Tipo de Cambio | Impacto DDL | Impacto DTO | Impacto Service | Impacto Frontend |
+|----------------|-------------|-------------|-----------------|------------------|
+| Agregar indice | SI | NO | NO | NO |
+| Agregar unique | SI | NO | Manejar error | Manejar error |
+| Agregar check | SI | NO | Manejar error | Manejar error |
+
+---
+
+## 3. AGREGAR CAMPO A ENTITY
+
+### Flujo Completo
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PASO 1: DDL (Database-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β ALTER TABLE auth.users ADD COLUMN phone VARCHAR(20); β
+β β
+β Validar: ./recreate-database.sh && psql -c "\d auth.users" β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PASO 2: Entity (Backend-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β @Column({ type: 'varchar', length: 20, nullable: true }) β
+β phone: string | null; β
+β β
+β Validar: npm run build β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PASO 3: DTOs (Backend-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β CreateUserDto: β
+β @IsOptional() β
+β @IsString() β
+β @MaxLength(20) β
+β phone?: string; β
+β β
+β UserResponseDto: β
+β @ApiProperty({ required: false }) β
+β phone: string | null; β
+β β
+β Validar: npm run build && npm run lint β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PASO 4: Frontend (Frontend-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β user.types.ts: β
+β interface User { β
+β phone: string | null; β
+β } β
+β β
+β user.schema.ts: β
+β phone: z.string().max(20).optional() β
+β β
+β Validar: npm run build && npm run typecheck β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+### Checklist Agregar Campo
+
+```
+[ ] 1. DDL tiene la columna con tipo correcto
+[ ] 2. Entity @Column refleja DDL (tipo, length, nullable)
+[ ] 3. CreateDto tiene validaciones apropiadas
+[ ] 4. UpdateDto hereda de CreateDto (automatico con PartialType)
+[ ] 5. ResponseDto tiene el campo con ApiProperty
+[ ] 6. Frontend interface tiene el campo
+[ ] 7. Frontend Zod schema tiene validacion equivalente
+[ ] 8. Swagger documenta correctamente
+[ ] 9. Build pasa en backend
+[ ] 10. Build y typecheck pasan en frontend
+```
+
+---
+
+## 4. ELIMINAR CAMPO DE ENTITY
+
+### ADVERTENCIA
+
+```
+β οΈ ELIMINAR CAMPO ES OPERACION DESTRUCTIVA
+
+ANTES DE ELIMINAR:
+1. Verificar que no hay datos importantes
+2. Buscar TODAS las referencias en codigo
+3. Considerar deprecar primero (nullable + ignorar)
+4. Planear migracion de datos si necesario
+```
+
+### Flujo de Eliminacion
+
+```bash
+# PASO 0: Buscar todas las referencias
+grep -rn "fieldName" src/
+grep -rn "fieldName" apps/
+grep -rn "field_name" db/ # snake_case en DDL
+
+# PASO 1: Eliminar uso en Frontend primero (evita errores de tipo)
+# PASO 2: Eliminar uso en Service/Controller
+# PASO 3: Eliminar de DTOs
+# PASO 4: Eliminar de Entity
+# PASO 5: Eliminar de DDL (ultimo porque es irreversible)
+```
+
+### Checklist Eliminar Campo
+
+```
+[ ] 1. Buscar referencias en backend: grep -rn "field" src/
+[ ] 2. Buscar referencias en frontend: grep -rn "field" apps/
+[ ] 3. Eliminar de componentes Frontend
+[ ] 4. Eliminar de types/interfaces Frontend
+[ ] 5. Eliminar de Zod schemas Frontend
+[ ] 6. Eliminar de Service (si hay logica)
+[ ] 7. Eliminar de ResponseDto
+[ ] 8. Eliminar de CreateDto
+[ ] 9. Eliminar de Entity
+[ ] 10. Eliminar de DDL (con migracion)
+[ ] 11. Build pasa en todos los proyectos
+```
+
+---
+
+## 5. AGREGAR RELACION A ENTITY
+
+### 5.1 ManyToOne (FK hacia otra tabla)
+
+```typescript
+// Entity: Order tiene un User
+@ManyToOne(() => UserEntity, { nullable: false })
+@JoinColumn({ name: 'user_id' })
+user: UserEntity;
+
+// Columna FK explicita (opcional pero recomendado)
+@Column({ type: 'uuid' })
+userId: string;
+```
+
+**Impacto:**
+
+| Capa | Archivo | Cambio Requerido |
+|------|---------|------------------|
+| DDL | `XX-orders.sql` | `user_id UUID REFERENCES auth.users(id)` |
+| Entity | `order.entity.ts` | `@ManyToOne` + `@JoinColumn` |
+| CreateDto | `create-order.dto.ts` | `@IsUUID() userId: string;` |
+| ResponseDto | `order-response.dto.ts` | `userId: string;` o `user: UserResponseDto;` |
+| Service | `order.service.ts` | Decidir: cargar relacion o no |
+| Frontend | `order.types.ts` | `userId: string;` o `user: User;` |
+
+### 5.2 OneToMany (Coleccion inversa)
+
+```typescript
+// Entity: User tiene muchos Orders
+@OneToMany(() => OrderEntity, order => order.user)
+orders: OrderEntity[];
+```
+
+**Impacto:**
+
+| Capa | Archivo | Cambio Requerido |
+|------|---------|------------------|
+| DDL | N/A | Sin cambio (FK esta en orders) |
+| Entity | `user.entity.ts` | `@OneToMany` |
+| ResponseDto | `user-response.dto.ts` | Decidir: incluir o no |
+| Service | `user.service.ts` | Decidir: cargar relacion o no |
+| Frontend | `user.types.ts` | `orders?: Order[];` |
+
+### 5.3 ManyToMany (Tabla junction)
+
+```typescript
+// Entity: User tiene muchos Roles
+@ManyToMany(() => RoleEntity)
+@JoinTable({
+ name: 'user_roles',
+ joinColumn: { name: 'user_id' },
+ inverseJoinColumn: { name: 'role_id' },
+})
+roles: RoleEntity[];
+```
+
+**Impacto:**
+
+| Capa | Archivo | Cambio Requerido |
+|------|---------|------------------|
+| DDL | `XX-user-roles.sql` | Crear tabla junction |
+| Entity | `user.entity.ts` | `@ManyToMany` + `@JoinTable` |
+| ResponseDto | `user-response.dto.ts` | `roles: RoleResponseDto[];` |
+| Service | `user.service.ts` | Logica para asignar/remover roles |
+| Controller | `user.controller.ts` | Endpoints para manejar roles |
+| Frontend | `user.types.ts` | `roles: Role[];` |
+| Frontend | `useUserRoles.ts` | Hook para manejar roles |
+
+### Checklist Agregar Relacion
+
+```
+[ ] 1. DDL tiene FK o tabla junction
+[ ] 2. Entity tiene decorador de relacion correcto
+[ ] 3. Entity relacionada tiene relacion inversa (si necesario)
+[ ] 4. CreateDto acepta ID de relacion
+[ ] 5. ResponseDto decide: incluir objeto o solo ID
+[ ] 6. Service decide: eager loading o lazy
+[ ] 7. Frontend types reflejan estructura
+[ ] 8. Frontend tiene logica para manejar relacion
+```
+
+---
+
+## 6. CAMBIAR TIPO DE CAMPO
+
+### Mapeo de Cambios Comunes
+
+| Cambio | DDL | Entity | DTO | Frontend |
+|--------|-----|--------|-----|----------|
+| `INT` β `BIGINT` | ALTER TYPE | `number` (sin cambio) | Sin cambio | Sin cambio |
+| `VARCHAR` β `TEXT` | ALTER TYPE | Sin cambio | Ajustar MaxLength | Ajustar max |
+| `INTEGER` β `DECIMAL` | ALTER TYPE | `number` β `string` | Ajustar validador | Ajustar tipo |
+| `BOOLEAN` β `ENUM` | ALTER TYPE | `boolean` β `enum` | Cambiar validador | Cambiar tipo |
+| `VARCHAR` β `UUID` | ALTER TYPE + datos | `string` (sin cambio) | Agregar @IsUUID | Agregar validacion |
+
+### Ejemplo: INTEGER a DECIMAL
+
+```sql
+-- DDL
+ALTER TABLE products ALTER COLUMN price TYPE DECIMAL(10,2);
+```
+
+```typescript
+// Entity ANTES
+@Column({ type: 'integer' })
+price: number;
+
+// Entity DESPUES
+@Column({ type: 'decimal', precision: 10, scale: 2 })
+price: string; // String para precision
+```
+
+```typescript
+// CreateDto ANTES
+@IsNumber()
+price: number;
+
+// CreateDto DESPUES
+@IsNumberString()
+@Matches(/^\d+(\.\d{1,2})?$/)
+price: string;
+```
+
+```typescript
+// Frontend ANTES
+interface Product {
+ price: number;
+}
+
+// Frontend DESPUES
+interface Product {
+ price: string;
+}
+
+// Uso en componente
+const displayPrice = parseFloat(product.price).toFixed(2);
+```
+
+---
+
+## 7. PATRON DE MIGRACION SEGURA
+
+### Para cambios que pueden romper
+
+```
+FASE 1: Agregar nuevo (sin eliminar viejo)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Agregar nuevo campo/columna junto al existente
+2. Actualizar codigo para escribir en ambos
+3. Deploy backend
+
+FASE 2: Migrar datos
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Script para copiar datos de viejo a nuevo
+2. Verificar integridad
+
+FASE 3: Cambiar lecturas
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Actualizar codigo para leer de nuevo
+2. Deploy backend + frontend
+
+FASE 4: Eliminar viejo
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+1. Eliminar campo viejo de codigo
+2. Eliminar columna de DDL
+3. Deploy final
+```
+
+---
+
+## 8. DECORADORES ENTITY Y SU IMPACTO
+
+### @Column Options
+
+| Option | Impacto si cambia | Requiere DDL |
+|--------|-------------------|--------------|
+| `type` | Tipo TS, validacion DTO | SI |
+| `length` | Validacion DTO | SI |
+| `nullable` | Tipo TS (null), validacion | SI |
+| `default` | Posible logica Service | SI |
+| `unique` | Manejo error Service | SI |
+| `name` | Ninguno (mapeo interno) | SI |
+| `precision/scale` | Tipo TS, formateo FE | SI |
+
+### @Index
+
+| Cambio | Impacto |
+|--------|---------|
+| Agregar | Solo performance, DDL |
+| Eliminar | Solo performance, DDL |
+| Cambiar columnas | Solo performance, DDL |
+
+### Relation Options
+
+| Option | Impacto si cambia |
+|--------|-------------------|
+| `eager: true` | Queries cargan automatico |
+| `cascade: true` | Operaciones se propagan |
+| `onDelete` | Comportamiento al eliminar padre |
+| `nullable` | Validacion, tipo TS |
+
+---
+
+## 9. COMANDOS DE VERIFICACION
+
+```bash
+# Ver diferencias entre DDL y Entity
+# (manual: comparar columnas)
+psql -d mydb -c "\d schema.table"
+cat src/modules/x/entities/x.entity.ts
+
+# Verificar que Entity compila
+npm run build
+
+# Verificar que no hay referencias rotas
+npm run lint
+
+# Verificar sincronizacion con frontend
+npm run typecheck --prefix apps/web
+
+# Buscar uso de campo especifico
+grep -rn "fieldName" src/ apps/
+```
+
+---
+
+## 10. MATRIZ DE DECISION
+
+```
+ΒΏQue tipo de cambio en Entity?
+
+βββββββββββββββββββββββ
+β Agregar campo ββββΆ DDL primero β Entity β DTO β Frontend
+βββββββββββββββββββββββ
+
+βββββββββββββββββββββββ
+β Eliminar campo ββββΆ Frontend primero β Service β DTO β Entity β DDL
+βββββββββββββββββββββββ
+
+βββββββββββββββββββββββ
+β Cambiar tipo ββββΆ DDL primero β Entity β DTO β Frontend
+βββββββββββββββββββββββ
+
+βββββββββββββββββββββββ
+β Agregar relacion ββββΆ DDL (FK) β Entity β DTO β Service β Frontend
+βββββββββββββββββββββββ
+
+βββββββββββββββββββββββ
+β Renombrar campo ββββΆ Migracion segura (agregar nuevo β migrar β eliminar viejo)
+βββββββββββββββββββββββ
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Guia de Impacto
diff --git a/core/orchestration/impactos/MATRIZ-DEPENDENCIAS.md b/core/orchestration/impactos/MATRIZ-DEPENDENCIAS.md
new file mode 100644
index 0000000..4b3830f
--- /dev/null
+++ b/core/orchestration/impactos/MATRIZ-DEPENDENCIAS.md
@@ -0,0 +1,445 @@
+# MATRIZ DE DEPENDENCIAS ENTRE CAPAS
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** REFERENCIA - Consultar para entender impactos
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Proporcionar una matriz completa de dependencias entre todos los componentes del sistema para que los agentes puedan identificar rapidamente que se debe actualizar cuando se modifica algo.
+
+---
+
+## 1. VISION GENERAL DE DEPENDENCIAS
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β FLUJO DE DEPENDENCIAS β
+β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β DDL ββββββΆβ Entity ββββββΆβ DTO ββββββΆβ Service β β
+β β (SQL) β β(TypeORM)β β (class) β β (logic) β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β β β β β
+β β β β βΌ β
+β β β β βββββββββββ β
+β β β β βControllerβ β
+β β β β β (REST) β β
+β β β β βββββββββββ β
+β β β β β β
+β β β β βΌ β
+β β β β βββββββββββββββββββ β
+β β β β β SWAGGER β β
+β β β β β (API Contract) β β
+β β β β βββββββββββββββββββ β
+β β β β β β
+β β β βΌ βΌ β
+β β β βββββββββββββββββββββββββββ β
+β β β β FRONTEND β β
+β β β β TypesβSchemaβHooksβUI β β
+β β β βββββββββββββββββββββββββββ β
+β β β β
+β βΌ βΌ β
+β βββββββββββββββββββββββββββ β
+β β INVENTARIOS β β
+β β DBβBEβFEβMASTER β β
+β βββββββββββββββββββββββββββ β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. MATRIZ DE DEPENDENCIA: DDL
+
+### Cuando se modifica DDL (tablas, columnas)
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Entity** | SI | 1 - Inmediato | Debe reflejar estructura DDL |
+| **CreateDto** | SI | 2 | Campos nuevos/eliminados |
+| **UpdateDto** | AUTO | 2 | Hereda de CreateDto |
+| **ResponseDto** | SI | 2 | Campos en response |
+| **Service** | POSIBLE | 3 | Si hay logica de campo |
+| **Controller** | NO | - | Usa DTOs |
+| **Frontend Types** | SI | 4 | Reflejar ResponseDto |
+| **Frontend Schema** | SI | 4 | Reflejar CreateDto |
+| **Frontend Components** | POSIBLE | 5 | Si muestran campo |
+| **Swagger** | AUTO | - | Generado de DTOs |
+| **DATABASE_INVENTORY** | SI | 6 | Registrar cambio |
+| **Tests** | POSIBLE | 5 | Si prueban campo |
+
+### Diagrama de Propagacion DDL
+
+```
+DDL Change
+ β
+ ββββΆ Entity (obligatorio)
+ β β
+ β ββββΆ CreateDto (obligatorio)
+ β β β
+ β β ββββΆ Frontend Schema (obligatorio)
+ β β
+ β ββββΆ ResponseDto (obligatorio)
+ β β β
+ β β ββββΆ Frontend Types (obligatorio)
+ β β β
+ β β ββββΆ Frontend Components (si usa campo)
+ β β
+ β ββββΆ Service (si logica de campo)
+ β
+ ββββΆ DATABASE_INVENTORY (obligatorio)
+```
+
+---
+
+## 3. MATRIZ DE DEPENDENCIA: ENTITY
+
+### Cuando se modifica Entity
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **DDL** | VERIFICAR | 0 | DDL debe existir primero |
+| **CreateDto** | SI | 1 | Reflejar campos |
+| **UpdateDto** | AUTO | 1 | Hereda de CreateDto |
+| **ResponseDto** | SI | 1 | Reflejar campos |
+| **Service** | POSIBLE | 2 | Si usa campo directamente |
+| **Controller** | NO | - | Usa DTOs |
+| **Frontend Types** | SI | 3 | Reflejar ResponseDto |
+| **Frontend Schema** | SI | 3 | Reflejar CreateDto |
+| **Frontend Components** | POSIBLE | 4 | Si muestran campo |
+| **BACKEND_INVENTORY** | SI | 5 | Registrar cambio |
+| **Unit Tests** | SI | 4 | Actualizar mocks |
+
+### Por Tipo de Cambio en Entity
+
+| Cambio | DTOs | Service | Frontend | Tests |
+|--------|------|---------|----------|-------|
+| Agregar @Column | SI | NO | SI | SI |
+| Eliminar @Column | SI | Verificar | SI | SI |
+| Cambiar tipo @Column | SI | Posible | SI | SI |
+| Agregar @ManyToOne | SI | SI | SI | SI |
+| Agregar @OneToMany | SI | Posible | SI | Posible |
+| Cambiar @Index | NO | NO | NO | NO |
+| Cambiar nullable | SI | NO | SI | Posible |
+
+---
+
+## 4. MATRIZ DE DEPENDENCIA: DTO
+
+### Cuando se modifica CreateDto
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **UpdateDto** | AUTO | 1 | Si usa PartialType |
+| **Service** | NO | - | Recibe DTO |
+| **Controller** | NO | - | Usa DTO |
+| **Swagger** | AUTO | - | Generado |
+| **Frontend Schema (Zod)** | SI | 2 | Mismas validaciones |
+| **Frontend Forms** | POSIBLE | 3 | Si campos cambian |
+| **Integration Tests** | SI | 3 | Fixtures |
+
+### Cuando se modifica ResponseDto
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Service** | SI | 1 | Si mapea a ResponseDto |
+| **Controller** | NO | - | Retorna Service result |
+| **Swagger** | AUTO | - | Generado |
+| **Frontend Types** | SI | 2 | Interface debe coincidir |
+| **Frontend Components** | POSIBLE | 3 | Si muestran campo |
+| **Frontend Hooks** | NO | - | Usan Types |
+
+---
+
+## 5. MATRIZ DE DEPENDENCIA: SERVICE
+
+### Cuando se modifica Service
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Controller** | POSIBLE | 1 | Si cambia firma metodo |
+| **Swagger** | POSIBLE | 2 | Si cambia response/errors |
+| **Frontend** | POSIBLE | 2 | Si cambia contrato API |
+| **Unit Tests** | SI | 1 | Tests del service |
+| **Integration Tests** | POSIBLE | 2 | Si cambia comportamiento |
+
+### Por Tipo de Cambio en Service
+
+| Cambio | Controller | Frontend | Tests |
+|--------|------------|----------|-------|
+| Agregar metodo | SI (nuevo endpoint) | SI | SI |
+| Eliminar metodo | SI | SI | SI |
+| Cambiar firma | SI | SI | SI |
+| Cambiar logica interna | NO | NO | SI |
+| Agregar validacion | NO | Manejar error | SI |
+| Cambiar error thrown | NO | Manejar error | SI |
+
+---
+
+## 6. MATRIZ DE DEPENDENCIA: CONTROLLER
+
+### Cuando se modifica Controller
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Service** | NO | - | Controller consume Service |
+| **Swagger** | AUTO | - | Generado de decoradores |
+| **Frontend Service** | SI | 1 | Si cambia ruta/metodo |
+| **Frontend Hooks** | POSIBLE | 2 | Si cambia endpoint |
+| **E2E Tests** | SI | 2 | Tests de endpoint |
+
+### Por Tipo de Cambio en Controller
+
+| Cambio | Frontend Service | Frontend Hooks | Tests |
+|--------|------------------|----------------|-------|
+| Agregar endpoint | SI (nuevo metodo) | SI (nuevo hook) | SI |
+| Eliminar endpoint | SI | SI | SI |
+| Cambiar ruta | SI | NO | SI |
+| Cambiar metodo HTTP | SI | NO | SI |
+| Cambiar decoradores Swagger | NO | NO | NO |
+| Agregar guard | NO | Manejar 401/403 | SI |
+
+---
+
+## 7. MATRIZ DE DEPENDENCIA: FRONTEND
+
+### Cuando se modifica Frontend Types
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Zod Schema** | VERIFICAR | 1 | Debe ser consistente |
+| **Hooks** | NO | - | Usan Types |
+| **Components** | VERIFICAR | 2 | Si usan tipo |
+| **Services** | NO | - | Usan Types |
+
+### Cuando se modifica Frontend Schema (Zod)
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Forms** | VERIFICAR | 1 | Si usan schema |
+| **Types** | VERIFICAR | 1 | Deben coincidir |
+
+### Cuando se modifica Frontend Hook
+
+| Componente Dependiente | Requiere Actualizacion | Prioridad | Detalle |
+|------------------------|------------------------|-----------|---------|
+| **Components** | VERIFICAR | 1 | Si usan hook |
+| **Pages** | VERIFICAR | 1 | Si usan hook |
+
+---
+
+## 8. MATRIZ RAPIDA DE REFERENCIA
+
+### "Si cambio X, que debo actualizar?"
+
+```
+βββββββββββββββββββ¬ββββββ¬βββββββββ¬ββββββββββ¬ββββββββββ¬βββββββββ¬ββββββββββββββ
+β SI CAMBIO... β DDL β Entity βDTO-Crea βDTO-Resp βService β Controller β
+βββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββββββ€
+β DDL columna β ββ β SI β SI β SI β Posib β NO β
+β DDL FK β ββ β SI β SI β SI β SI β Posible β
+β DDL indice β ββ β NO β NO β NO β NO β NO β
+βββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββββββ€
+β Entity columna β Ver β ββ β SI β SI β Posib β NO β
+β Entity relacion β Ver β ββ β SI β SI β SI β Posible β
+βββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββββββ€
+β CreateDto campo β NO β NO β ββ β NO β NO β NO β
+β CreateDto valid β NO β NO β ββ β NO β NO β NO β
+β ResponseDto β NO β NO β NO β ββ β Ver β NO β
+βββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββββββ€
+β Service metodo β NO β NO β NO β Posib β ββ β SI β
+β Service logica β NO β NO β NO β NO β ββ β NO β
+βββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββββΌβββββββββΌββββββββββββββ€
+β Controller ruta β NO β NO β NO β NO β NO β ββ β
+β Controller meth β NO β NO β NO β NO β NO β ββ β
+βββββββββββββββββββ΄ββββββ΄βββββββββ΄ββββββββββ΄ββββββββββ΄βββββββββ΄ββββββββββββββ
+
+Continuacion β Frontend
+
+βββββββββββββββββββ¬ββββββββ¬βββββββββ¬ββββββββ¬ββββββββββββ¬ββββββββββββ
+β SI CAMBIO... β Types β Schema β Hooks βComponents β Inventory β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β DDL columna β SI β SI β NO β Posible β DB+MAST β
+β DDL FK β SI β SI β SI β Posible β DB+MAST β
+β DDL indice β NO β NO β NO β NO β DB β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β Entity columna β SI β SI β NO β Posible β BE+MAST β
+β Entity relacion β SI β SI β SI β Posible β BE+MAST β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β CreateDto campo β NO β SI β NO β Posible β BE β
+β CreateDto valid β NO β SI β NO β NO β NO β
+β ResponseDto β SI β NO β NO β Posible β BE β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β Service metodo β Posib β Posib β SI β Posible β BE β
+β Service logica β NO β NO β NO β NO β NO β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β Controller ruta β NO β NO β SI β NO β BE β
+β Controller meth β NO β NO β SI β NO β NO β
+βββββββββββββββββββΌββββββββΌβββββββββΌββββββββΌββββββββββββΌββββββββββββ€
+β Frontend Types β ββ β Ver β NO β Ver β FE β
+β Frontend Schema β Ver β ββ β NO β Ver β FE β
+β Frontend Hook β NO β NO β ββ β Ver β FE β
+β Frontend Comp β NO β NO β NO β ββ β FE β
+βββββββββββββββββββ΄ββββββββ΄βββββββββ΄ββββββββ΄ββββββββββββ΄ββββββββββββ
+
+Leyenda:
+SI = Siempre actualizar
+NO = No requiere actualizacion
+Ver = Verificar DDL primero
+Posib = Posiblemente, depende del caso
+ββ = No aplica (mismo componente)
+```
+
+---
+
+## 9. DEPENDENCIAS POR MODULO
+
+### Modulo Tipico NestJS
+
+```
+modules/user/
+βββ entities/
+β βββ user.entity.ts β Depende de: DDL
+β Impacta: DTOs, Service
+βββ dto/
+β βββ create-user.dto.ts β Depende de: Entity
+β β Impacta: Frontend Schema
+β βββ update-user.dto.ts β Depende de: CreateDto
+β β Impacta: Frontend Schema
+β βββ user-response.dto.ts β Depende de: Entity
+β Impacta: Frontend Types
+βββ services/
+β βββ user.service.ts β Depende de: Entity, DTOs
+β Impacta: Controller
+βββ controllers/
+β βββ user.controller.ts β Depende de: Service, DTOs
+β Impacta: Frontend Hooks
+βββ user.module.ts β Depende de: Todo lo anterior
+```
+
+### Modulo Tipico Frontend
+
+```
+shared/
+βββ types/
+β βββ user.types.ts β Depende de: ResponseDto
+β Impacta: Hooks, Components
+βββ schemas/
+β βββ user.schema.ts β Depende de: CreateDto
+β Impacta: Forms
+βββ services/
+ βββ user.service.ts β Depende de: Controller routes
+ Impacta: Hooks
+
+apps/web/
+βββ hooks/
+β βββ useUsers.ts β Depende de: Service, Types
+β Impacta: Pages, Components
+βββ components/
+β βββ UserCard.tsx β Depende de: Types, Hooks
+β Impacta: Pages
+βββ pages/
+ βββ UsersPage.tsx β Depende de: Hooks, Components
+```
+
+---
+
+## 10. COMANDOS DE VERIFICACION DE DEPENDENCIAS
+
+```bash
+# Ver todas las importaciones de un archivo
+grep -n "import" src/modules/user/user.service.ts
+
+# Ver quien importa un archivo
+grep -rn "from.*user.entity" src/
+
+# Ver dependencias de modulo
+grep -rn "UserModule" src/
+
+# Ver uso de tipo en frontend
+grep -rn "User" apps/web/
+
+# Arbol de dependencias (si usa herramientas)
+npx madge --image graph.svg src/modules/user/
+
+# TypeScript: ver errores de tipo despues de cambio
+npm run typecheck 2>&1 | head -50
+```
+
+---
+
+## 11. ESCENARIOS COMUNES
+
+### Escenario 1: Agregar campo a tabla existente
+
+```
+1. DDL: ALTER TABLE ADD COLUMN
+2. Entity: Agregar @Column
+3. CreateDto: Agregar campo + validacion
+4. ResponseDto: Agregar campo
+5. Service: Solo si hay logica especial
+6. Frontend Types: Agregar a interface
+7. Frontend Schema: Agregar validacion Zod
+8. Frontend Components: Agregar UI si necesario
+9. Inventarios: DB, BE, FE, MASTER
+```
+
+### Escenario 2: Crear nuevo modulo/feature
+
+```
+1. DDL: CREATE TABLE
+2. Entity: Crear archivo
+3. DTOs: Crear Create, Update, Response
+4. Service: Crear con CRUD basico
+5. Controller: Crear con endpoints REST
+6. Module: Crear y registrar en AppModule
+7. Frontend Types: Crear interface
+8. Frontend Schema: Crear Zod schema
+9. Frontend Service: Crear API service
+10. Frontend Hook: Crear useQuery/useMutation
+11. Frontend Components: Crear UI
+12. Inventarios: TODOS
+```
+
+### Escenario 3: Refactorizar nombre de campo
+
+```
+1. EVALUAR: ΒΏEs breaking change?
+2. OPCION A (breaking): Cambiar en cadena DDLβEntityβDTOβFE
+3. OPCION B (seguro):
+ a. Agregar nuevo campo
+ b. Migrar datos
+ c. Actualizar codigo para usar nuevo
+ d. Eliminar campo viejo
+```
+
+---
+
+## 12. ANTI-PATRON: DEPENDENCIAS CIRCULARES
+
+```
+β INCORRECTO: Dependencia circular entre Services
+UserService βββΆ OrderService
+ β² β
+ βββββββββββββββββ
+
+β
CORRECTO: Extraer a servicio compartido
+UserService βββΆ SharedService βββ OrderService
+```
+
+```
+β INCORRECTO: Frontend importa de Backend
+apps/web/types/user.ts
+import { UserEntity } from '@backend/modules/user';
+
+β
CORRECTO: Frontend tiene sus propios tipos
+apps/web/types/user.ts
+export interface User { ... } // Definido independiente
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Matriz de Referencia
diff --git a/core/orchestration/patrones/ANTIPATRONES.md b/core/orchestration/patrones/ANTIPATRONES.md
new file mode 100644
index 0000000..686630b
--- /dev/null
+++ b/core/orchestration/patrones/ANTIPATRONES.md
@@ -0,0 +1,714 @@
+# ANTIPATRONES: Lo que NUNCA Hacer
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Consultar antes de implementar
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPΓSITO
+
+Documentar antipatrones comunes para que agentes y subagentes los eviten. Cada antipatrΓ³n incluye el problema, por quΓ© es malo, y la soluciΓ³n correcta.
+
+---
+
+## 1. ANTIPATRONES DE DATABASE
+
+### DB-001: Crear tabla sin schema
+
+```sql
+-- β INCORRECTO
+CREATE TABLE users (
+ id UUID PRIMARY KEY
+);
+
+-- β
CORRECTO
+CREATE TABLE auth.users (
+ id UUID PRIMARY KEY
+);
+```
+
+**Por quΓ© es malo:** Sin schema, la tabla va a `public`, mezclando dominios y dificultando permisos.
+
+---
+
+### DB-002: Columna NOT NULL sin DEFAULT en tabla existente
+
+```sql
+-- β INCORRECTO (en tabla con datos)
+ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL;
+
+-- β
CORRECTO
+ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active';
+```
+
+**Por quΓ© es malo:** Falla en INSERT para registros existentes que no tienen valor.
+
+---
+
+### DB-003: Foreign Key sin ON DELETE
+
+```sql
+-- β INCORRECTO
+CREATE TABLE orders (
+ user_id UUID REFERENCES users(id)
+);
+
+-- β
CORRECTO
+CREATE TABLE orders (
+ user_id UUID REFERENCES users(id) ON DELETE CASCADE
+ -- o ON DELETE SET NULL, ON DELETE RESTRICT segΓΊn el caso
+);
+```
+
+**Por quΓ© es malo:** Al eliminar usuario, los orders quedan huΓ©rfanos o el DELETE falla sin explicaciΓ³n clara.
+
+---
+
+### DB-004: Usar TEXT cuando deberΓa ser ENUM
+
+```sql
+-- β INCORRECTO
+CREATE TABLE users (
+ status TEXT -- Permite cualquier valor
+);
+
+-- β
CORRECTO
+CREATE TYPE user_status AS ENUM ('active', 'inactive', 'suspended');
+CREATE TABLE users (
+ status user_status DEFAULT 'active'
+);
+
+-- O con CHECK constraint
+CREATE TABLE users (
+ status VARCHAR(20) CHECK (status IN ('active', 'inactive', 'suspended'))
+);
+```
+
+**Por quΓ© es malo:** TEXT permite valores invΓ‘lidos, causando bugs silenciosos.
+
+---
+
+### DB-005: Γndice faltante en columna de bΓΊsqueda frecuente
+
+```sql
+-- β INCORRECTO
+CREATE TABLE products (
+ sku VARCHAR(50) UNIQUE -- Sin Γndice adicional para bΓΊsquedas
+);
+
+-- β
CORRECTO
+CREATE TABLE products (
+ sku VARCHAR(50) UNIQUE
+);
+CREATE INDEX idx_products_sku ON products(sku);
+-- UNIQUE ya crea Γndice, pero para bΓΊsquedas parciales:
+CREATE INDEX idx_products_sku_pattern ON products(sku varchar_pattern_ops);
+```
+
+**Por quΓ© es malo:** Queries lentas en tablas grandes (full table scan).
+
+---
+
+### DB-006: Guardar contraseΓ±as en texto plano
+
+```sql
+-- β INCORRECTO
+CREATE TABLE users (
+ password VARCHAR(100) -- Almacena "mipassword123"
+);
+
+-- β
CORRECTO
+CREATE TABLE users (
+ password_hash VARCHAR(255) -- Almacena hash bcrypt
+);
+-- Hashing se hace en backend, no en SQL
+```
+
+**Por quΓ© es malo:** Vulnerabilidad de seguridad crΓtica.
+
+---
+
+## 2. ANTIPATRONES DE BACKEND
+
+### BE-001: LΓ³gica de negocio en Controller
+
+```typescript
+// β INCORRECTO
+@Controller('orders')
+export class OrderController {
+ @Post()
+ async create(@Body() dto: CreateOrderDto) {
+ // LΓ³gica de negocio en controller
+ const total = dto.items.reduce((sum, item) => sum + item.price * item.qty, 0);
+ const tax = total * 0.16;
+ const discount = dto.couponCode ? await this.calculateDiscount() : 0;
+ // ... mΓ‘s lΓ³gica
+ }
+}
+
+// β
CORRECTO
+@Controller('orders')
+export class OrderController {
+ @Post()
+ async create(@Body() dto: CreateOrderDto) {
+ return this.orderService.create(dto); // Delega a service
+ }
+}
+
+@Injectable()
+export class OrderService {
+ async create(dto: CreateOrderDto) {
+ const total = this.calculateTotal(dto.items);
+ const tax = this.calculateTax(total);
+ // LΓ³gica de negocio en service
+ }
+}
+```
+
+**Por quΓ© es malo:** Controller difΓcil de testear, lΓ³gica no reutilizable, violaciΓ³n de SRP.
+
+---
+
+### BE-002: Query directo en Service sin Repository
+
+```typescript
+// β INCORRECTO
+@Injectable()
+export class UserService {
+ async findActive() {
+ // Query directo con QueryBuilder
+ return this.connection.query(`
+ SELECT * FROM users WHERE status = 'active'
+ `);
+ }
+}
+
+// β
CORRECTO
+@Injectable()
+export class UserService {
+ constructor(
+ @InjectRepository(UserEntity)
+ private readonly repository: Repository,
+ ) {}
+
+ async findActive() {
+ return this.repository.find({
+ where: { status: UserStatus.ACTIVE },
+ });
+ }
+}
+```
+
+**Por quΓ© es malo:** No tipado, vulnerable a SQL injection, difΓcil de mantener.
+
+---
+
+### BE-003: ValidaciΓ³n en Service en lugar de DTO
+
+```typescript
+// β INCORRECTO
+@Injectable()
+export class UserService {
+ async create(dto: any) {
+ if (!dto.email) throw new BadRequestException('Email required');
+ if (!dto.email.includes('@')) throw new BadRequestException('Invalid email');
+ if (dto.name.length < 2) throw new BadRequestException('Name too short');
+ // ... mΓ‘s validaciones manuales
+ }
+}
+
+// β
CORRECTO
+export class CreateUserDto {
+ @IsEmail()
+ @IsNotEmpty()
+ email: string;
+
+ @IsString()
+ @MinLength(2)
+ name: string;
+}
+
+// Service recibe DTO ya validado
+```
+
+**Por quΓ© es malo:** ValidaciΓ³n duplicada, inconsistente, no documentada en Swagger.
+
+---
+
+### BE-004: Catch vacΓo o silencioso
+
+```typescript
+// β INCORRECTO
+async processPayment() {
+ try {
+ await this.paymentGateway.charge();
+ } catch (e) {
+ // Silencioso - error perdido
+ }
+}
+
+// β TAMBIΓN INCORRECTO
+async processPayment() {
+ try {
+ await this.paymentGateway.charge();
+ } catch (e) {
+ console.log(e); // Solo log, sin manejar
+ }
+}
+
+// β
CORRECTO
+async processPayment() {
+ try {
+ await this.paymentGateway.charge();
+ } catch (error) {
+ this.logger.error('Payment failed', { error, context: 'payment' });
+ throw new InternalServerErrorException('Error procesando pago');
+ }
+}
+```
+
+**Por quΓ© es malo:** Errores silenciosos causan bugs imposibles de debuggear.
+
+---
+
+### BE-005: Entity no alineada con DDL
+
+```typescript
+// DDL tiene:
+// status VARCHAR(20) CHECK (status IN ('active', 'inactive'))
+
+// β INCORRECTO
+@Column()
+status: string; // No valida valores
+
+// β
CORRECTO
+enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+}
+
+@Column({ type: 'varchar', length: 20 })
+status: UserStatus;
+```
+
+**Por quΓ© es malo:** Entity permite valores que BD rechaza, errores en runtime.
+
+---
+
+### BE-006: Hardcodear configuraciΓ³n
+
+```typescript
+// β INCORRECTO
+const API_URL = 'https://api.stripe.com/v1';
+const DB_HOST = '192.168.1.100';
+
+// β
CORRECTO
+const API_URL = this.configService.get('STRIPE_API_URL');
+const DB_HOST = this.configService.get('DB_HOST');
+
+// O usar decorador
+@Injectable()
+export class PaymentService {
+ constructor(
+ @Inject('STRIPE_CONFIG')
+ private readonly config: StripeConfig,
+ ) {}
+}
+```
+
+**Por quΓ© es malo:** DifΓcil cambiar entre ambientes, secretos expuestos en cΓ³digo.
+
+---
+
+### BE-007: N+1 Query Problem
+
+```typescript
+// β INCORRECTO
+async getOrdersWithItems() {
+ const orders = await this.orderRepository.find();
+ for (const order of orders) {
+ order.items = await this.itemRepository.find({
+ where: { orderId: order.id }
+ });
+ }
+ return orders;
+}
+// Resultado: 1 query para orders + N queries para items
+
+// β
CORRECTO
+async getOrdersWithItems() {
+ return this.orderRepository.find({
+ relations: ['items'], // JOIN en una query
+ });
+}
+// Resultado: 1 query con JOIN
+```
+
+**Por quΓ© es malo:** Performance terrible en listas grandes (100 orders = 101 queries).
+
+---
+
+## 3. ANTIPATRONES DE FRONTEND
+
+### FE-001: Fetch directo en componente
+
+```typescript
+// β INCORRECTO
+const UserProfile = () => {
+ const [user, setUser] = useState(null);
+
+ useEffect(() => {
+ fetch('/api/users/me')
+ .then(res => res.json())
+ .then(setUser);
+ }, []);
+
+ return {user?.name}
;
+};
+
+// β
CORRECTO
+// hooks/useUser.ts
+const useUser = () => {
+ return useQuery({
+ queryKey: ['user', 'me'],
+ queryFn: () => userService.getMe(),
+ });
+};
+
+// components/UserProfile.tsx
+const UserProfile = () => {
+ const { data: user, isLoading, error } = useUser();
+
+ if (isLoading) return ;
+ if (error) return ;
+
+ return {user.name}
;
+};
+```
+
+**Por quΓ© es malo:** No cachea, no maneja loading/error, lΓ³gica no reutilizable.
+
+---
+
+### FE-002: Hardcodear URLs de API
+
+```typescript
+// β INCORRECTO
+const response = await fetch('http://localhost:3000/api/users');
+
+// β
CORRECTO
+// config.ts
+export const API_URL = import.meta.env.VITE_API_URL;
+
+// services/api.ts
+const api = axios.create({
+ baseURL: API_URL,
+});
+```
+
+**Por quΓ© es malo:** Rompe en producciΓ³n, difΓcil cambiar backend.
+
+---
+
+### FE-003: Estado global para todo
+
+```typescript
+// β INCORRECTO - Redux/Zustand para estado de formulario
+const formStore = create((set) => ({
+ name: '',
+ email: '',
+ setName: (name) => set({ name }),
+ setEmail: (email) => set({ email }),
+}));
+
+// β
CORRECTO - Estado local para formularios
+const UserForm = () => {
+ const [name, setName] = useState('');
+ const [email, setEmail] = useState('');
+ // O usar react-hook-form
+};
+
+// Store global SOLO para:
+// - Auth state (usuario logueado)
+// - UI state (tema, sidebar abierto)
+// - Cache de server state (mejor usar React Query)
+```
+
+**Por quΓ© es malo:** Complejidad innecesaria, renders innecesarios, difΓcil de seguir.
+
+---
+
+### FE-004: Props drilling excesivo
+
+```typescript
+// β INCORRECTO
+
+
+
+
+ // Finalmente se usa
+
+
+
+
+
+// β
CORRECTO - Context para datos compartidos
+const UserContext = createContext(null);
+const useUser = () => useContext(UserContext);
+
+
+
+
+
+
+ // Usa useUser() internamente
+
+
+
+
+
+```
+
+**Por quΓ© es malo:** Componentes intermedios reciben props que no usan, refactoring doloroso.
+
+---
+
+### FE-005: useEffect para todo
+
+```typescript
+// β INCORRECTO
+const ProductList = ({ categoryId }) => {
+ const [products, setProducts] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ setLoading(true);
+ fetch(`/api/products?category=${categoryId}`)
+ .then(res => res.json())
+ .then(data => {
+ setProducts(data);
+ setLoading(false);
+ });
+ }, [categoryId]);
+ // Race conditions, no cleanup, no error handling
+};
+
+// β
CORRECTO - React Query
+const ProductList = ({ categoryId }) => {
+ const { data: products, isLoading } = useQuery({
+ queryKey: ['products', categoryId],
+ queryFn: () => productService.getByCategory(categoryId),
+ });
+ // Maneja cache, loading, error, race conditions automΓ‘ticamente
+};
+```
+
+**Por quΓ© es malo:** Race conditions, memory leaks, re-inventar la rueda.
+
+---
+
+### FE-006: Tipos no sincronizados con backend
+
+```typescript
+// Backend DTO (actualizado)
+class UserDto {
+ id: string;
+ email: string;
+ name: string;
+ phone: string; // β NUEVO CAMPO
+}
+
+// β INCORRECTO - Frontend desactualizado
+interface User {
+ id: string;
+ email: string;
+ name: string;
+ // Falta phone β undefined en runtime
+}
+
+// β
CORRECTO - Mantener sincronizado
+interface User {
+ id: string;
+ email: string;
+ name: string;
+ phone?: string; // Sincronizado con backend
+}
+```
+
+**Por quΓ© es malo:** Bugs silenciosos en runtime cuando backend cambia.
+
+---
+
+## 4. ANTIPATRONES DE ARQUITECTURA
+
+### ARCH-001: Importar de capa incorrecta
+
+```typescript
+// β INCORRECTO - Controller importa de otro mΓ³dulo directamente
+import { ProductEntity } from '../products/entities/product.entity';
+
+// β
CORRECTO - Usar exports del mΓ³dulo
+import { ProductService } from '../products/product.module';
+
+// O mejor: dependency injection
+@Module({
+ imports: [ProductModule],
+})
+export class OrderModule {}
+```
+
+**Por quΓ© es malo:** Acopla mΓ³dulos, rompe encapsulamiento, dependencias circulares.
+
+---
+
+### ARCH-002: Duplicar cΓ³digo entre mΓ³dulos
+
+```typescript
+// β INCORRECTO - Misma funciΓ³n en dos mΓ³dulos
+// users/utils.ts
+function formatDate(date: Date) { ... }
+
+// orders/utils.ts
+function formatDate(date: Date) { ... } // Duplicado
+
+// β
CORRECTO - Shared utils
+// shared/utils/date.utils.ts
+export function formatDate(date: Date) { ... }
+```
+
+**Por quΓ© es malo:** Cambios deben hacerse en mΓΊltiples lugares, inconsistencias.
+
+---
+
+### ARCH-003: Circular dependencies
+
+```typescript
+// β INCORRECTO
+// user.service.ts
+import { OrderService } from '../orders/order.service';
+
+// order.service.ts
+import { UserService } from '../users/user.service';
+
+// β
CORRECTO - Usar forwardRef o reestructurar
+@Injectable()
+export class UserService {
+ constructor(
+ @Inject(forwardRef(() => OrderService))
+ private orderService: OrderService,
+ ) {}
+}
+
+// O mejor: Extraer lΓ³gica compartida a un tercer servicio
+```
+
+**Por quΓ© es malo:** Errores en runtime, cΓ³digo difΓcil de entender.
+
+---
+
+## 5. ANTIPATRONES DE TESTING
+
+### TEST-001: Tests que dependen de orden
+
+```typescript
+// β INCORRECTO
+describe('UserService', () => {
+ it('should create user', () => {
+ const user = service.create({ email: 'test@test.com' });
+ // Asume que este test corre primero
+ });
+
+ it('should find user', () => {
+ const user = service.findByEmail('test@test.com');
+ // Depende del test anterior
+ });
+});
+
+// β
CORRECTO - Tests independientes
+describe('UserService', () => {
+ beforeEach(async () => {
+ // Setup limpio para cada test
+ await repository.clear();
+ });
+
+ it('should create user', () => { ... });
+
+ it('should find user', async () => {
+ // Crear datos necesarios en el test
+ await repository.save({ email: 'test@test.com' });
+ const user = await service.findByEmail('test@test.com');
+ });
+});
+```
+
+---
+
+### TEST-002: Mock incorrecto
+
+```typescript
+// β INCORRECTO - Mock parcial/inconsistente
+jest.mock('./user.service', () => ({
+ findOne: jest.fn().mockResolvedValue({ id: '1' }),
+ // Otros mΓ©todos no mockeados β undefined
+}));
+
+// β
CORRECTO - Mock completo
+const mockUserService = {
+ findOne: jest.fn(),
+ findAll: jest.fn(),
+ create: jest.fn(),
+ update: jest.fn(),
+ delete: jest.fn(),
+};
+
+beforeEach(() => {
+ jest.clearAllMocks();
+});
+```
+
+---
+
+## 6. CHECKLIST DE REVISIΓN
+
+Antes de hacer commit, verificar que NO estΓ‘s haciendo:
+
+```
+Database:
+[ ] Tabla sin schema
+[ ] NOT NULL sin DEFAULT en tabla existente
+[ ] FK sin ON DELETE
+[ ] TEXT donde deberΓa ser ENUM
+[ ] Γndices faltantes
+
+Backend:
+[ ] LΓ³gica en Controller
+[ ] Queries directas sin Repository
+[ ] ValidaciΓ³n en Service
+[ ] Catch vacΓo
+[ ] Entity desalineada con DDL
+[ ] Config hardcodeada
+[ ] N+1 queries
+
+Frontend:
+[ ] Fetch en componente
+[ ] URLs hardcodeadas
+[ ] Store global para estado local
+[ ] Props drilling excesivo
+[ ] useEffect innecesario
+[ ] Tipos desactualizados
+
+Arquitectura:
+[ ] Import de capa incorrecta
+[ ] CΓ³digo duplicado
+[ ] Dependencias circulares
+
+Testing:
+[ ] Tests dependientes
+[ ] Mocks incompletos
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** GuΓa de Antipatrones
diff --git a/core/orchestration/patrones/MAPEO-TIPOS-DDL-TYPESCRIPT.md b/core/orchestration/patrones/MAPEO-TIPOS-DDL-TYPESCRIPT.md
new file mode 100644
index 0000000..209be33
--- /dev/null
+++ b/core/orchestration/patrones/MAPEO-TIPOS-DDL-TYPESCRIPT.md
@@ -0,0 +1,499 @@
+# MAPEO DE TIPOS: PostgreSQL DDL β TypeScript/TypeORM
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Consultar antes de crear Entity
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPΓSITO
+
+Este documento define el mapeo EXACTO entre tipos de PostgreSQL y TypeScript/TypeORM para garantizar alineaciΓ³n 100% entre DDL y Entities.
+
+---
+
+## REGLA FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β DDL ES LA FUENTE DE VERDAD (DDL-First) β
+β β
+β 1. DDL define el tipo β Entity lo REFLEJA β
+β 2. NUNCA crear Entity sin DDL existente β
+β 3. Si DDL cambia β Entity DEBE cambiar β
+β 4. Si Entity no coincide β ERROR (corregir Entity, no DDL) β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## TABLA DE MAPEO COMPLETA
+
+### Tipos NumΓ©ricos
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `SMALLINT` | `number` | `@Column({ type: 'smallint' })` | -32,768 a 32,767 |
+| `INTEGER` | `number` | `@Column({ type: 'integer' })` | -2B a 2B |
+| `BIGINT` | `string` | `@Column({ type: 'bigint' })` | Usar string para precisiΓ³n |
+| `DECIMAL(p,s)` | `string` | `@Column({ type: 'decimal', precision: p, scale: s })` | Usar string para dinero |
+| `NUMERIC(p,s)` | `string` | `@Column({ type: 'numeric', precision: p, scale: s })` | Igual que DECIMAL |
+| `REAL` | `number` | `@Column({ type: 'real' })` | Punto flotante 4 bytes |
+| `DOUBLE PRECISION` | `number` | `@Column({ type: 'double precision' })` | Punto flotante 8 bytes |
+| `SERIAL` | `number` | `@PrimaryGeneratedColumn()` | Auto-increment |
+| `BIGSERIAL` | `string` | `@PrimaryGeneratedColumn('increment')` | Auto-increment grande |
+
+**Ejemplo NumΓ©ricos:**
+```sql
+-- DDL
+CREATE TABLE products (
+ id SERIAL PRIMARY KEY,
+ price DECIMAL(10,2) NOT NULL,
+ quantity INTEGER DEFAULT 0,
+ rating REAL
+);
+```
+
+```typescript
+// Entity
+@Entity({ schema: 'inventory', name: 'products' })
+export class ProductEntity {
+ @PrimaryGeneratedColumn()
+ id: number;
+
+ @Column({ type: 'decimal', precision: 10, scale: 2 })
+ price: string; // String para precisiΓ³n decimal
+
+ @Column({ type: 'integer', default: 0 })
+ quantity: number;
+
+ @Column({ type: 'real', nullable: true })
+ rating: number;
+}
+```
+
+---
+
+### Tipos de Texto
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `CHAR(n)` | `string` | `@Column({ type: 'char', length: n })` | Longitud fija |
+| `VARCHAR(n)` | `string` | `@Column({ type: 'varchar', length: n })` | Longitud variable |
+| `TEXT` | `string` | `@Column({ type: 'text' })` | Sin lΓmite |
+
+**Ejemplo Texto:**
+```sql
+-- DDL
+CREATE TABLE users (
+ code CHAR(10) NOT NULL,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ bio TEXT
+);
+```
+
+```typescript
+// Entity
+@Column({ type: 'char', length: 10 })
+code: string;
+
+@Column({ type: 'varchar', length: 255, unique: true })
+email: string;
+
+@Column({ type: 'text', nullable: true })
+bio: string;
+```
+
+---
+
+### Tipos de Fecha y Hora
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `DATE` | `Date` | `@Column({ type: 'date' })` | Solo fecha |
+| `TIME` | `string` | `@Column({ type: 'time' })` | Solo hora |
+| `TIMESTAMP` | `Date` | `@Column({ type: 'timestamp' })` | Fecha + hora sin TZ |
+| `TIMESTAMPTZ` | `Date` | `@Column({ type: 'timestamptz' })` | Fecha + hora con TZ |
+| `INTERVAL` | `string` | `@Column({ type: 'interval' })` | Intervalo de tiempo |
+
+**Ejemplo Fechas:**
+```sql
+-- DDL
+CREATE TABLE events (
+ event_date DATE NOT NULL,
+ start_time TIME,
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
+ duration INTERVAL
+);
+```
+
+```typescript
+// Entity
+@Column({ type: 'date' })
+eventDate: Date;
+
+@Column({ type: 'time', nullable: true })
+startTime: string;
+
+@CreateDateColumn({ type: 'timestamp' })
+createdAt: Date;
+
+@UpdateDateColumn({ type: 'timestamptz' })
+updatedAt: Date;
+
+@Column({ type: 'interval', nullable: true })
+duration: string;
+```
+
+---
+
+### Tipos Booleanos
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `BOOLEAN` | `boolean` | `@Column({ type: 'boolean' })` | true/false |
+
+**Ejemplo Boolean:**
+```sql
+-- DDL
+CREATE TABLE users (
+ is_active BOOLEAN DEFAULT TRUE,
+ is_verified BOOLEAN DEFAULT FALSE
+);
+```
+
+```typescript
+// Entity
+@Column({ type: 'boolean', default: true })
+isActive: boolean;
+
+@Column({ type: 'boolean', default: false })
+isVerified: boolean;
+```
+
+---
+
+### Tipos UUID
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `UUID` | `string` | `@Column({ type: 'uuid' })` | Usar con gen_random_uuid() |
+
+**Ejemplo UUID:**
+```sql
+-- DDL
+CREATE TABLE users (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES tenants(id)
+);
+```
+
+```typescript
+// Entity
+@PrimaryGeneratedColumn('uuid')
+id: string;
+
+@Column({ type: 'uuid' })
+tenantId: string;
+
+@ManyToOne(() => TenantEntity)
+@JoinColumn({ name: 'tenant_id' })
+tenant: TenantEntity;
+```
+
+---
+
+### Tipos JSON
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `JSON` | `object \| any` | `@Column({ type: 'json' })` | Sin indexaciΓ³n |
+| `JSONB` | `object \| any` | `@Column({ type: 'jsonb' })` | Con indexaciΓ³n |
+
+**Ejemplo JSON:**
+```sql
+-- DDL
+CREATE TABLE users (
+ preferences JSONB DEFAULT '{}',
+ metadata JSON
+);
+```
+
+```typescript
+// Entity - OpciΓ³n 1: any
+@Column({ type: 'jsonb', default: {} })
+preferences: any;
+
+// Entity - OpciΓ³n 2: Interface tipada (RECOMENDADO)
+interface UserPreferences {
+ theme: 'light' | 'dark';
+ notifications: boolean;
+ language: string;
+}
+
+@Column({ type: 'jsonb', default: {} })
+preferences: UserPreferences;
+
+@Column({ type: 'json', nullable: true })
+metadata: Record;
+```
+
+---
+
+### Tipos ENUM
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `CREATE TYPE ... AS ENUM` | `enum` | `@Column({ type: 'enum', enum: X })` | Definir enum TS |
+| `VARCHAR CHECK (IN ...)` | `enum \| string` | `@Column()` + validator | Alternativa sin tipo |
+
+**Ejemplo ENUM (Recomendado):**
+```sql
+-- DDL
+CREATE TYPE user_status AS ENUM ('active', 'inactive', 'suspended', 'deleted');
+
+CREATE TABLE users (
+ status user_status DEFAULT 'active'
+);
+```
+
+```typescript
+// Entity
+export enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+ SUSPENDED = 'suspended',
+ DELETED = 'deleted',
+}
+
+@Column({
+ type: 'enum',
+ enum: UserStatus,
+ default: UserStatus.ACTIVE,
+})
+status: UserStatus;
+```
+
+**Ejemplo VARCHAR con CHECK (Alternativa):**
+```sql
+-- DDL
+CREATE TABLE orders (
+ status VARCHAR(20) CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'))
+);
+```
+
+```typescript
+// Entity - Usar tipo union + validaciΓ³n en DTO
+type OrderStatus = 'pending' | 'processing' | 'completed' | 'cancelled';
+
+@Column({ type: 'varchar', length: 20 })
+status: OrderStatus;
+
+// DTO - ValidaciΓ³n obligatoria
+@IsIn(['pending', 'processing', 'completed', 'cancelled'])
+status: string;
+```
+
+---
+
+### Tipos Array
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `INTEGER[]` | `number[]` | `@Column({ type: 'integer', array: true })` | Array de enteros |
+| `VARCHAR[]` | `string[]` | `@Column({ type: 'varchar', array: true })` | Array de strings |
+| `UUID[]` | `string[]` | `@Column({ type: 'uuid', array: true })` | Array de UUIDs |
+
+**Ejemplo Arrays:**
+```sql
+-- DDL
+CREATE TABLE posts (
+ tags VARCHAR(50)[],
+ category_ids UUID[]
+);
+```
+
+```typescript
+// Entity
+@Column({ type: 'varchar', array: true, nullable: true })
+tags: string[];
+
+@Column({ type: 'uuid', array: true, nullable: true })
+categoryIds: string[];
+```
+
+---
+
+### Tipos Especiales
+
+| PostgreSQL | TypeScript | TypeORM Column | Notas |
+|------------|------------|----------------|-------|
+| `BYTEA` | `Buffer` | `@Column({ type: 'bytea' })` | Datos binarios |
+| `INET` | `string` | `@Column({ type: 'inet' })` | DirecciΓ³n IP |
+| `CIDR` | `string` | `@Column({ type: 'cidr' })` | Red IP |
+| `MACADDR` | `string` | `@Column({ type: 'macaddr' })` | DirecciΓ³n MAC |
+
+---
+
+## MAPEO DE CONSTRAINTS
+
+### NOT NULL
+
+```sql
+-- DDL
+email VARCHAR(255) NOT NULL
+```
+
+```typescript
+// Entity
+@Column({ type: 'varchar', length: 255, nullable: false })
+email: string; // Sin ? = no nullable
+```
+
+### DEFAULT
+
+```sql
+-- DDL
+created_at TIMESTAMP DEFAULT NOW()
+status VARCHAR(20) DEFAULT 'active'
+```
+
+```typescript
+// Entity
+@CreateDateColumn({ type: 'timestamp' })
+createdAt: Date;
+
+@Column({ type: 'varchar', length: 20, default: 'active' })
+status: string;
+```
+
+### UNIQUE
+
+```sql
+-- DDL
+email VARCHAR(255) UNIQUE
+```
+
+```typescript
+// Entity
+@Column({ type: 'varchar', length: 255, unique: true })
+email: string;
+```
+
+### CHECK (No soportado directamente en TypeORM)
+
+```sql
+-- DDL
+age INTEGER CHECK (age >= 0 AND age <= 150)
+```
+
+```typescript
+// Entity - Sin validaciΓ³n en Entity
+@Column({ type: 'integer' })
+age: number;
+
+// DTO - OBLIGATORIO validar aquΓ
+@IsInt()
+@Min(0)
+@Max(150)
+age: number;
+```
+
+---
+
+## MAPEO DE RELACIONES
+
+### ONE-TO-MANY / MANY-TO-ONE
+
+```sql
+-- DDL
+CREATE TABLE orders (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE
+);
+```
+
+```typescript
+// Entity Order
+@ManyToOne(() => UserEntity, user => user.orders, { onDelete: 'CASCADE' })
+@JoinColumn({ name: 'user_id' })
+user: UserEntity;
+
+@Column({ type: 'uuid' })
+userId: string;
+
+// Entity User
+@OneToMany(() => OrderEntity, order => order.user)
+orders: OrderEntity[];
+```
+
+### MANY-TO-MANY
+
+```sql
+-- DDL
+CREATE TABLE user_roles (
+ user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+ role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
+ PRIMARY KEY (user_id, role_id)
+);
+```
+
+```typescript
+// Entity User
+@ManyToMany(() => RoleEntity, role => role.users)
+@JoinTable({
+ name: 'user_roles',
+ joinColumn: { name: 'user_id', referencedColumnName: 'id' },
+ inverseJoinColumn: { name: 'role_id', referencedColumnName: 'id' },
+})
+roles: RoleEntity[];
+
+// Entity Role
+@ManyToMany(() => UserEntity, user => user.roles)
+users: UserEntity[];
+```
+
+---
+
+## CHECKLIST DE ALINEACIΓN
+
+Antes de completar Entity, verificar:
+
+```
+[ ] Cada columna DDL tiene @Column en Entity
+[ ] Tipos PostgreSQL mapeados correctamente (ver tabla)
+[ ] nullable: false para NOT NULL
+[ ] default: X para DEFAULT X
+[ ] unique: true para UNIQUE
+[ ] Relaciones (@ManyToOne, etc.) coinciden con FOREIGN KEY
+[ ] onDelete coincide con ON DELETE
+[ ] Nombre de tabla correcto en @Entity({ name: 'x' })
+[ ] Schema correcto en @Entity({ schema: 'x' })
+[ ] PK coincide (@PrimaryGeneratedColumn vs @PrimaryColumn)
+```
+
+---
+
+## ERRORES COMUNES
+
+| Error | Causa | SoluciΓ³n |
+|-------|-------|----------|
+| `bigint` retorna string inesperado | BIGINT se mapea a string | Usar `string` en TypeScript |
+| Decimales pierden precisiΓ³n | DECIMAL mapeado a number | Usar `string` para dinero |
+| Enum no reconocido | Tipo no creado en BD | Crear TYPE primero en DDL |
+| Array vacΓo falla | Array sin default | Agregar `default: []` |
+| Fecha invΓ‘lida | TIMESTAMP vs TIMESTAMPTZ | Usar TIMESTAMPTZ para TZ |
+
+---
+
+## REFERENCIAS
+
+- SIMCO-DDL.md - Crear tablas
+- SIMCO-BACKEND.md - Crear entities
+- PRINCIPIO-VALIDACION-OBLIGATORIA.md - Validar alineaciΓ³n
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** PatrΓ³n de Mapeo
diff --git a/core/orchestration/patrones/NOMENCLATURA-UNIFICADA.md b/core/orchestration/patrones/NOMENCLATURA-UNIFICADA.md
new file mode 100644
index 0000000..e3c552f
--- /dev/null
+++ b/core/orchestration/patrones/NOMENCLATURA-UNIFICADA.md
@@ -0,0 +1,539 @@
+# NOMENCLATURA UNIFICADA
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Seguir en todo el cΓ³digo
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPΓSITO
+
+Definir convenciones de nomenclatura consistentes para todas las capas del sistema.
+
+---
+
+## 1. DIRECTORIOS
+
+### Regla General
+
+```
+lowercase-kebab-case
+```
+
+### Ejemplos
+
+```
+β
CORRECTO β INCORRECTO
+βββββββββββββββββββββββββββββββββββββββ
+user-management/ UserManagement/
+auth-module/ AuthModule/
+shared-utils/ sharedUtils/
+api-v1/ API_V1/
+```
+
+### Estructura por Capa
+
+```
+DATABASE:
+db/
+βββ schemas/
+β βββ auth/
+β β βββ tables/
+β βββ core/
+β βββ {domain}/
+βββ seeds/
+β βββ dev/
+β βββ prod/
+βββ scripts/
+
+BACKEND (NestJS):
+src/
+βββ modules/
+β βββ {module-name}/
+β βββ entities/
+β βββ dto/
+β βββ services/
+β βββ controllers/
+β βββ tests/
+βββ shared/
+β βββ config/
+β βββ guards/
+β βββ decorators/
+β βββ filters/
+β βββ interceptors/
+β βββ utils/
+βββ main.ts
+
+FRONTEND (React):
+src/
+βββ apps/
+β βββ {app-name}/
+β βββ components/
+β βββ pages/
+β βββ hooks/
+βββ shared/
+β βββ components/
+β β βββ ui/ # Componentes base
+β β βββ common/ # Componentes compartidos
+β βββ hooks/
+β βββ stores/
+β βββ services/
+β βββ types/
+β βββ utils/
+βββ main.tsx
+```
+
+---
+
+## 2. ARCHIVOS
+
+### Por Capa
+
+| Capa | PatrΓ³n | Ejemplo |
+|------|--------|---------|
+| **DDL** | `{NN}-{nombre}.sql` | `01-users.sql`, `02-products.sql` |
+| **Seed** | `{NN}-{nombre}.sql` | `01-admin-user.sql` |
+| **Entity** | `{nombre}.entity.ts` | `user.entity.ts` |
+| **DTO Create** | `create-{nombre}.dto.ts` | `create-user.dto.ts` |
+| **DTO Update** | `update-{nombre}.dto.ts` | `update-user.dto.ts` |
+| **DTO Response** | `{nombre}-response.dto.ts` | `user-response.dto.ts` |
+| **DTO Query** | `{nombre}-query.dto.ts` | `user-query.dto.ts` |
+| **Service** | `{nombre}.service.ts` | `user.service.ts` |
+| **Controller** | `{nombre}.controller.ts` | `user.controller.ts` |
+| **Module** | `{nombre}.module.ts` | `user.module.ts` |
+| **Guard** | `{nombre}.guard.ts` | `jwt-auth.guard.ts` |
+| **Strategy** | `{nombre}.strategy.ts` | `jwt.strategy.ts` |
+| **Filter** | `{nombre}.filter.ts` | `http-exception.filter.ts` |
+| **Interceptor** | `{nombre}.interceptor.ts` | `logging.interceptor.ts` |
+| **Decorator** | `{nombre}.decorator.ts` | `current-user.decorator.ts` |
+| **Component** | `{Nombre}.tsx` | `UserCard.tsx` |
+| **Page** | `{Nombre}Page.tsx` | `UserProfilePage.tsx` |
+| **Hook** | `use{Nombre}.ts` | `useUser.ts`, `useAuth.ts` |
+| **Store** | `{nombre}.store.ts` | `auth.store.ts` |
+| **Service (FE)** | `{nombre}.service.ts` | `user.service.ts` |
+| **Types** | `{nombre}.types.ts` | `user.types.ts` |
+| **Test Unit** | `{nombre}.spec.ts` | `user.service.spec.ts` |
+| **Test E2E** | `{nombre}.e2e-spec.ts` | `user.e2e-spec.ts` |
+| **Test Component** | `{Nombre}.test.tsx` | `UserCard.test.tsx` |
+
+### DDL - Orden de Archivos
+
+```sql
+-- Usar prefijo numΓ©rico para orden de ejecuciΓ³n
+01-users.sql -- Tablas base primero
+02-roles.sql -- Tablas relacionadas
+03-user-roles.sql -- Junction tables despuΓ©s
+04-permissions.sql
+10-products.sql -- Otro dominio, nuevo rango
+11-categories.sql
+12-product-categories.sql
+```
+
+---
+
+## 3. CLASES Y TIPOS
+
+### TypeScript/NestJS
+
+| Tipo | PatrΓ³n | Ejemplo |
+|------|--------|---------|
+| **Entity** | `{Nombre}Entity` | `UserEntity` |
+| **DTO** | `{Accion}{Nombre}Dto` | `CreateUserDto` |
+| **Service** | `{Nombre}Service` | `UserService` |
+| **Controller** | `{Nombre}Controller` | `UserController` |
+| **Module** | `{Nombre}Module` | `UserModule` |
+| **Guard** | `{Nombre}Guard` | `JwtAuthGuard` |
+| **Strategy** | `{Nombre}Strategy` | `JwtStrategy` |
+| **Filter** | `{Nombre}Filter` | `HttpExceptionFilter` |
+| **Interceptor** | `{Nombre}Interceptor` | `LoggingInterceptor` |
+| **Enum** | `{Nombre}` | `UserStatus`, `OrderState` |
+| **Interface** | `{Nombre}` o `I{Nombre}` | `User`, `IUserService` |
+| **Type** | `{Nombre}` | `UserWithRoles`, `OrderSummary` |
+
+### Ejemplos Completos
+
+```typescript
+// Entity
+@Entity({ schema: 'auth', name: 'users' })
+export class UserEntity { ... }
+
+// DTOs
+export class CreateUserDto { ... }
+export class UpdateUserDto extends PartialType(CreateUserDto) { ... }
+export class UserResponseDto { ... }
+export class UserQueryDto { ... }
+
+// Service
+@Injectable()
+export class UserService { ... }
+
+// Controller
+@Controller('users')
+export class UserController { ... }
+
+// Module
+@Module({})
+export class UserModule { ... }
+
+// Enum
+export enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+}
+
+// Interface
+export interface User {
+ id: string;
+ email: string;
+}
+
+// Type
+export type UserWithRoles = User & { roles: Role[] };
+```
+
+---
+
+## 4. FUNCIONES Y MΓTODOS
+
+### Verbos EstΓ‘ndar
+
+| OperaciΓ³n | Verbo | Ejemplo |
+|-----------|-------|---------|
+| Obtener uno | `find`, `get` | `findById()`, `getUser()` |
+| Obtener muchos | `findAll`, `list` | `findAll()`, `listUsers()` |
+| Crear | `create` | `create()`, `createUser()` |
+| Actualizar | `update` | `update()`, `updateUser()` |
+| Eliminar | `remove`, `delete` | `remove()`, `deleteUser()` |
+| Buscar | `search` | `search()`, `searchUsers()` |
+| Verificar | `is`, `has`, `can` | `isActive()`, `hasPermission()` |
+| Contar | `count` | `count()`, `countActive()` |
+| Validar | `validate` | `validateEmail()` |
+| Formatear | `format` | `formatDate()`, `formatPrice()` |
+| Parsear | `parse` | `parseJson()`, `parseDate()` |
+| Convertir | `to`, `from` | `toDto()`, `fromEntity()` |
+
+### Ejemplos por Capa
+
+```typescript
+// Service - CRUD estΓ‘ndar
+class UserService {
+ async create(dto: CreateUserDto): Promise { ... }
+ async findAll(query: UserQueryDto): Promise { ... }
+ async findById(id: string): Promise { ... }
+ async findByEmail(email: string): Promise { ... }
+ async update(id: string, dto: UpdateUserDto): Promise { ... }
+ async remove(id: string): Promise { ... }
+
+ // MΓ©todos adicionales
+ async activate(id: string): Promise { ... }
+ async deactivate(id: string): Promise { ... }
+ async assignRole(userId: string, roleId: string): Promise { ... }
+ async hasPermission(userId: string, permission: string): Promise { ... }
+}
+
+// Controller - Endpoints REST
+class UserController {
+ @Get()
+ async findAll(@Query() query: UserQueryDto) { ... }
+
+ @Get(':id')
+ async findOne(@Param('id') id: string) { ... }
+
+ @Post()
+ async create(@Body() dto: CreateUserDto) { ... }
+
+ @Put(':id')
+ async update(@Param('id') id: string, @Body() dto: UpdateUserDto) { ... }
+
+ @Delete(':id')
+ async remove(@Param('id') id: string) { ... }
+}
+
+// Hook (Frontend)
+function useUsers() {
+ return useQuery({ ... });
+}
+
+function useUser(id: string) {
+ return useQuery({ ... });
+}
+
+function useCreateUser() {
+ return useMutation({ ... });
+}
+
+function useUpdateUser() {
+ return useMutation({ ... });
+}
+
+function useDeleteUser() {
+ return useMutation({ ... });
+}
+```
+
+---
+
+## 5. VARIABLES Y CONSTANTES
+
+### Variables
+
+```typescript
+// camelCase
+const userId = '123';
+const isActive = true;
+const userCount = 10;
+const createdAt = new Date();
+
+// Arrays en plural
+const users = [];
+const activeUsers = [];
+const userIds = ['1', '2', '3'];
+
+// Maps/Records con sufijo
+const userMap = new Map();
+const roleById = {}; // Record
+```
+
+### Constantes
+
+```typescript
+// UPPER_SNAKE_CASE para constantes
+const MAX_LOGIN_ATTEMPTS = 5;
+const DEFAULT_PAGE_SIZE = 20;
+const API_VERSION = 'v1';
+const JWT_EXPIRATION = '1d';
+
+// Constantes de configuraciΓ³n
+const CONFIG = {
+ MAX_FILE_SIZE: 10 * 1024 * 1024, // 10MB
+ ALLOWED_EXTENSIONS: ['.jpg', '.png', '.pdf'],
+ RATE_LIMIT: 100,
+};
+
+// Rutas/Paths
+const ROUTES = {
+ HOME: '/',
+ LOGIN: '/auth/login',
+ DASHBOARD: '/dashboard',
+ USER_PROFILE: '/users/:id',
+};
+```
+
+---
+
+## 6. ENUMS
+
+### DefiniciΓ³n
+
+```typescript
+// PascalCase para nombre
+// Valores en minΓΊsculas (para BD) o UPPER_CASE (para constantes)
+
+// OpciΓ³n 1: Valores string (recomendado para BD)
+export enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+ SUSPENDED = 'suspended',
+ DELETED = 'deleted',
+}
+
+// OpciΓ³n 2: Valores UPPER_CASE (para constantes internas)
+export enum HttpMethod {
+ GET = 'GET',
+ POST = 'POST',
+ PUT = 'PUT',
+ DELETE = 'DELETE',
+}
+
+// OpciΓ³n 3: NumΓ©ricos (solo si necesario)
+export enum Priority {
+ LOW = 1,
+ MEDIUM = 2,
+ HIGH = 3,
+ CRITICAL = 4,
+}
+```
+
+### Uso
+
+```typescript
+// Entity
+@Column({ type: 'enum', enum: UserStatus, default: UserStatus.ACTIVE })
+status: UserStatus;
+
+// ValidaciΓ³n DTO
+@IsEnum(UserStatus)
+status: UserStatus;
+
+// Frontend
+const statusLabel = {
+ [UserStatus.ACTIVE]: 'Activo',
+ [UserStatus.INACTIVE]: 'Inactivo',
+ [UserStatus.SUSPENDED]: 'Suspendido',
+};
+```
+
+---
+
+## 7. DATABASE (SQL)
+
+### Tablas y Columnas
+
+```sql
+-- Tablas: snake_case, plural
+CREATE TABLE users ( ... );
+CREATE TABLE product_categories ( ... );
+CREATE TABLE user_login_attempts ( ... );
+
+-- Columnas: snake_case
+CREATE TABLE users (
+ id UUID PRIMARY KEY,
+ first_name VARCHAR(100),
+ last_name VARCHAR(100),
+ email VARCHAR(255),
+ is_active BOOLEAN,
+ created_at TIMESTAMP,
+ updated_at TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- Foreign Keys: {tabla_singular}_id
+CREATE TABLE orders (
+ user_id UUID REFERENCES users(id),
+ product_id UUID REFERENCES products(id)
+);
+
+-- Junction Tables: {tabla1}_{tabla2} (orden alfabΓ©tico)
+CREATE TABLE role_users ( ... ); -- β
+CREATE TABLE user_roles ( ... ); -- β
(u antes de r)
+```
+
+### Γndices y Constraints
+
+```sql
+-- Γndices: idx_{tabla}_{columnas}
+CREATE INDEX idx_users_email ON users(email);
+CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);
+
+-- Unique: uq_{tabla}_{columnas}
+ALTER TABLE users ADD CONSTRAINT uq_users_email UNIQUE (email);
+
+-- Foreign Key: fk_{tabla}_{referencia}
+ALTER TABLE orders ADD CONSTRAINT fk_orders_user
+ FOREIGN KEY (user_id) REFERENCES users(id);
+
+-- Check: chk_{tabla}_{descripcion}
+ALTER TABLE users ADD CONSTRAINT chk_users_status
+ CHECK (status IN ('active', 'inactive'));
+```
+
+---
+
+## 8. API ENDPOINTS
+
+### Convenciones REST
+
+```
+GET /api/v1/users # Listar
+GET /api/v1/users/:id # Obtener uno
+POST /api/v1/users # Crear
+PUT /api/v1/users/:id # Actualizar completo
+PATCH /api/v1/users/:id # Actualizar parcial
+DELETE /api/v1/users/:id # Eliminar
+
+# Recursos anidados
+GET /api/v1/users/:id/orders # Γrdenes del usuario
+POST /api/v1/users/:id/orders # Crear orden para usuario
+
+# Acciones especiales
+POST /api/v1/users/:id/activate # AcciΓ³n
+POST /api/v1/users/:id/deactivate # AcciΓ³n
+POST /api/v1/auth/login # Auth
+POST /api/v1/auth/logout # Auth
+POST /api/v1/auth/refresh # Auth
+```
+
+### URL Patterns
+
+```
+β
CORRECTO β INCORRECTO
+ββββββββββββββββββββββββββββββββββββββββββ
+/users /user # Plural
+/users/:id /users/get/:id # Verbo innecesario
+/users/:id/orders /getUserOrders # Snake case, verbo
+/auth/login /doLogin # Verbo innecesario
+```
+
+---
+
+## 9. COMPONENTES REACT
+
+### Nombres
+
+```typescript
+// PascalCase para componentes
+const UserCard = () => { ... };
+const ProductList = () => { ... };
+const LoginForm = () => { ... };
+
+// Sufijos descriptivos
+const UserProfilePage = () => { ... }; // PΓ‘gina completa
+const UserEditModal = () => { ... }; // Modal
+const UserDeleteDialog = () => { ... }; // Dialog de confirmaciΓ³n
+const UserAvatarSkeleton = () => { ... }; // Loading skeleton
+```
+
+### Props
+
+```typescript
+// Interface con Props suffix
+interface UserCardProps {
+ user: User;
+ onEdit?: (user: User) => void;
+ onDelete?: (id: string) => void;
+ isLoading?: boolean;
+}
+
+const UserCard: React.FC = ({
+ user,
+ onEdit,
+ onDelete,
+ isLoading = false,
+}) => { ... };
+```
+
+---
+
+## 10. CHECKLIST DE NOMENCLATURA
+
+```
+Antes de crear archivo:
+[ ] Nombre en formato correcto para su tipo
+[ ] Directorio correcto segΓΊn capa
+[ ] Sin duplicados en nombre
+
+Antes de crear clase/tipo:
+[ ] PascalCase
+[ ] Sufijo correcto (Entity, Dto, Service, etc.)
+[ ] Nombre descriptivo
+
+Antes de crear funciΓ³n:
+[ ] camelCase
+[ ] Verbo al inicio
+[ ] Nombre describe quΓ© hace
+
+Antes de crear variable:
+[ ] camelCase
+[ ] Nombre descriptivo
+[ ] Plural para arrays
+
+Antes de crear endpoint:
+[ ] Recurso en plural
+[ ] Sin verbos en URL
+[ ] Estructura RESTful
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** GuΓa de Nomenclatura
diff --git a/core/orchestration/patrones/PATRON-CONFIGURACION.md b/core/orchestration/patrones/PATRON-CONFIGURACION.md
new file mode 100644
index 0000000..63ad0fe
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-CONFIGURACION.md
@@ -0,0 +1,745 @@
+# PATRON DE CONFIGURACION
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** RECOMENDADA - Seguir para consistencia
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Definir patrones estandarizados para manejo de configuracion en todas las capas, incluyendo variables de entorno, archivos de configuracion, y validacion de settings.
+
+---
+
+## 1. PRINCIPIOS FUNDAMENTALES
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PRINCIPIOS DE CONFIGURACION β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β 1. NUNCA hardcodear valores sensibles β
+β 2. SIEMPRE validar configuracion al iniciar β
+β 3. FALLAR RAPIDO si configuracion es invalida β
+β 4. SEPARAR configuracion por ambiente β
+β 5. CENTRALIZAR acceso a configuracion β
+β 6. DOCUMENTAR cada variable requerida β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. ESTRUCTURA DE ARCHIVOS
+
+### Estructura Recomendada
+
+```
+project/
+βββ .env.example # Template con TODAS las variables (sin valores reales)
+βββ .env # Valores locales (NUNCA en git)
+βββ .env.development # Override para desarrollo
+βββ .env.staging # Override para staging
+βββ .env.production # Override para produccion (solo en servidor)
+β
+βββ apps/backend/
+β βββ src/
+β βββ shared/
+β βββ config/
+β βββ configuration.ts # Configuracion principal
+β βββ config.validation.ts # Schema de validacion
+β βββ database.config.ts # Config de BD
+β βββ jwt.config.ts # Config de JWT
+β βββ index.ts # Export centralizado
+β
+βββ apps/frontend/
+ βββ src/
+ βββ shared/
+ βββ config/
+ βββ env.ts # Variables de entorno
+ βββ constants.ts # Constantes de app
+```
+
+### .env.example (Template)
+
+```bash
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+# CONFIGURACION DE BASE DE DATOS
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+DB_HOST=localhost
+DB_PORT=5432
+DB_NAME=myapp_development
+DB_USER=postgres
+DB_PASSWORD= # REQUERIDO: Password de BD
+DB_SSL=false
+
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+# CONFIGURACION DE JWT/AUTH
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+JWT_SECRET= # REQUERIDO: Minimo 32 caracteres
+JWT_EXPIRATION=1d
+JWT_REFRESH_EXPIRATION=7d
+
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+# CONFIGURACION DE SERVIDOR
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+NODE_ENV=development
+PORT=3000
+API_PREFIX=api
+CORS_ORIGINS=http://localhost:5173
+
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+# CONFIGURACION DE SERVICIOS EXTERNOS
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+REDIS_URL=redis://localhost:6379
+SMTP_HOST=
+SMTP_PORT=587
+SMTP_USER=
+SMTP_PASSWORD=
+
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+# CONFIGURACION DE LOGGING
+# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+LOG_LEVEL=debug # trace|debug|info|warn|error
+LOG_FORMAT=pretty # pretty|json
+```
+
+---
+
+## 3. BACKEND (NestJS)
+
+### Schema de Validacion con Joi
+
+```typescript
+// src/shared/config/config.validation.ts
+import * as Joi from 'joi';
+
+export const configValidationSchema = Joi.object({
+ // Database
+ DB_HOST: Joi.string().required(),
+ DB_PORT: Joi.number().default(5432),
+ DB_NAME: Joi.string().required(),
+ DB_USER: Joi.string().required(),
+ DB_PASSWORD: Joi.string().required(),
+ DB_SSL: Joi.boolean().default(false),
+
+ // JWT
+ JWT_SECRET: Joi.string().min(32).required(),
+ JWT_EXPIRATION: Joi.string().default('1d'),
+ JWT_REFRESH_EXPIRATION: Joi.string().default('7d'),
+
+ // Server
+ NODE_ENV: Joi.string()
+ .valid('development', 'staging', 'production', 'test')
+ .default('development'),
+ PORT: Joi.number().default(3000),
+ API_PREFIX: Joi.string().default('api'),
+ CORS_ORIGINS: Joi.string().default('*'),
+
+ // Redis (opcional)
+ REDIS_URL: Joi.string().uri().optional(),
+
+ // SMTP (opcional)
+ SMTP_HOST: Joi.string().optional(),
+ SMTP_PORT: Joi.number().optional(),
+ SMTP_USER: Joi.string().optional(),
+ SMTP_PASSWORD: Joi.string().optional(),
+
+ // Logging
+ LOG_LEVEL: Joi.string()
+ .valid('trace', 'debug', 'info', 'warn', 'error')
+ .default('info'),
+ LOG_FORMAT: Joi.string().valid('pretty', 'json').default('json'),
+});
+```
+
+### Configuracion Tipada
+
+```typescript
+// src/shared/config/configuration.ts
+export interface DatabaseConfig {
+ host: string;
+ port: number;
+ name: string;
+ user: string;
+ password: string;
+ ssl: boolean;
+}
+
+export interface JwtConfig {
+ secret: string;
+ expiration: string;
+ refreshExpiration: string;
+}
+
+export interface ServerConfig {
+ nodeEnv: string;
+ port: number;
+ apiPrefix: string;
+ corsOrigins: string[];
+}
+
+export interface AppConfig {
+ database: DatabaseConfig;
+ jwt: JwtConfig;
+ server: ServerConfig;
+ redis?: {
+ url: string;
+ };
+ smtp?: {
+ host: string;
+ port: number;
+ user: string;
+ password: string;
+ };
+ logging: {
+ level: string;
+ format: string;
+ };
+}
+
+export default (): AppConfig => ({
+ database: {
+ host: process.env.DB_HOST,
+ port: parseInt(process.env.DB_PORT, 10),
+ name: process.env.DB_NAME,
+ user: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ ssl: process.env.DB_SSL === 'true',
+ },
+ jwt: {
+ secret: process.env.JWT_SECRET,
+ expiration: process.env.JWT_EXPIRATION,
+ refreshExpiration: process.env.JWT_REFRESH_EXPIRATION,
+ },
+ server: {
+ nodeEnv: process.env.NODE_ENV,
+ port: parseInt(process.env.PORT, 10),
+ apiPrefix: process.env.API_PREFIX,
+ corsOrigins: process.env.CORS_ORIGINS?.split(',') || ['*'],
+ },
+ redis: process.env.REDIS_URL
+ ? { url: process.env.REDIS_URL }
+ : undefined,
+ smtp: process.env.SMTP_HOST
+ ? {
+ host: process.env.SMTP_HOST,
+ port: parseInt(process.env.SMTP_PORT, 10),
+ user: process.env.SMTP_USER,
+ password: process.env.SMTP_PASSWORD,
+ }
+ : undefined,
+ logging: {
+ level: process.env.LOG_LEVEL,
+ format: process.env.LOG_FORMAT,
+ },
+});
+```
+
+### Registro en AppModule
+
+```typescript
+// src/app.module.ts
+import { Module } from '@nestjs/common';
+import { ConfigModule, ConfigService } from '@nestjs/config';
+import configuration from './shared/config/configuration';
+import { configValidationSchema } from './shared/config/config.validation';
+
+@Module({
+ imports: [
+ ConfigModule.forRoot({
+ isGlobal: true,
+ load: [configuration],
+ validationSchema: configValidationSchema,
+ validationOptions: {
+ abortEarly: true, // Fallar en primer error
+ },
+ expandVariables: true, // Permitir ${VAR} en valores
+ }),
+ // ... otros modulos
+ ],
+})
+export class AppModule {}
+```
+
+### Uso en Services
+
+```typescript
+// src/modules/auth/services/auth.service.ts
+import { Injectable } from '@nestjs/common';
+import { ConfigService } from '@nestjs/config';
+import { JwtConfig } from '@/shared/config/configuration';
+
+@Injectable()
+export class AuthService {
+ private readonly jwtConfig: JwtConfig;
+
+ constructor(private readonly configService: ConfigService) {
+ // Acceso tipado a configuracion
+ this.jwtConfig = this.configService.get('jwt');
+ }
+
+ async generateToken(userId: string): Promise {
+ return this.jwtService.sign(
+ { sub: userId },
+ {
+ secret: this.jwtConfig.secret,
+ expiresIn: this.jwtConfig.expiration,
+ },
+ );
+ }
+}
+```
+
+### Configuraciones Especificas
+
+```typescript
+// src/shared/config/database.config.ts
+import { registerAs } from '@nestjs/config';
+import { TypeOrmModuleOptions } from '@nestjs/typeorm';
+
+export default registerAs('database', (): TypeOrmModuleOptions => ({
+ type: 'postgres',
+ host: process.env.DB_HOST,
+ port: parseInt(process.env.DB_PORT, 10),
+ username: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ database: process.env.DB_NAME,
+ ssl: process.env.DB_SSL === 'true'
+ ? { rejectUnauthorized: false }
+ : false,
+ autoLoadEntities: true,
+ synchronize: false, // NUNCA true en produccion
+ logging: process.env.NODE_ENV === 'development',
+}));
+```
+
+```typescript
+// src/shared/config/jwt.config.ts
+import { registerAs } from '@nestjs/config';
+import { JwtModuleOptions } from '@nestjs/jwt';
+
+export default registerAs('jwt', (): JwtModuleOptions => ({
+ secret: process.env.JWT_SECRET,
+ signOptions: {
+ expiresIn: process.env.JWT_EXPIRATION || '1d',
+ },
+}));
+```
+
+---
+
+## 4. FRONTEND (React/Vite)
+
+### Variables de Entorno
+
+```typescript
+// src/shared/config/env.ts
+
+// Vite expone variables con prefijo VITE_
+interface EnvConfig {
+ apiUrl: string;
+ apiTimeout: number;
+ environment: 'development' | 'staging' | 'production';
+ enableMockApi: boolean;
+ sentryDsn?: string;
+ gaTrackingId?: string;
+}
+
+function validateEnv(): EnvConfig {
+ const apiUrl = import.meta.env.VITE_API_URL;
+ const environment = import.meta.env.VITE_ENVIRONMENT || 'development';
+
+ // Validar variables requeridas
+ if (!apiUrl) {
+ throw new Error('VITE_API_URL is required');
+ }
+
+ return {
+ apiUrl,
+ apiTimeout: parseInt(import.meta.env.VITE_API_TIMEOUT || '30000', 10),
+ environment: environment as EnvConfig['environment'],
+ enableMockApi: import.meta.env.VITE_ENABLE_MOCK_API === 'true',
+ sentryDsn: import.meta.env.VITE_SENTRY_DSN,
+ gaTrackingId: import.meta.env.VITE_GA_TRACKING_ID,
+ };
+}
+
+export const env = validateEnv();
+
+// Helpers
+export const isDev = env.environment === 'development';
+export const isProd = env.environment === 'production';
+export const isStaging = env.environment === 'staging';
+```
+
+### Constantes de Aplicacion
+
+```typescript
+// src/shared/config/constants.ts
+import { env } from './env';
+
+export const APP_CONFIG = {
+ // API
+ API_URL: env.apiUrl,
+ API_TIMEOUT: env.apiTimeout,
+
+ // Paginacion
+ DEFAULT_PAGE_SIZE: 20,
+ MAX_PAGE_SIZE: 100,
+
+ // UI
+ TOAST_DURATION: 5000,
+ DEBOUNCE_DELAY: 300,
+
+ // Storage keys
+ STORAGE_KEYS: {
+ AUTH_TOKEN: 'auth_token',
+ REFRESH_TOKEN: 'refresh_token',
+ USER_PREFERENCES: 'user_preferences',
+ THEME: 'theme',
+ },
+
+ // Feature flags (pueden venir de API)
+ FEATURES: {
+ DARK_MODE: true,
+ NOTIFICATIONS: true,
+ BETA_FEATURES: env.environment !== 'production',
+ },
+} as const;
+
+// Rutas
+export const ROUTES = {
+ HOME: '/',
+ LOGIN: '/auth/login',
+ REGISTER: '/auth/register',
+ DASHBOARD: '/dashboard',
+ PROFILE: '/profile',
+ SETTINGS: '/settings',
+ USERS: '/users',
+ USER_DETAIL: '/users/:id',
+} as const;
+
+// API Endpoints
+export const API_ENDPOINTS = {
+ AUTH: {
+ LOGIN: '/auth/login',
+ REGISTER: '/auth/register',
+ REFRESH: '/auth/refresh',
+ LOGOUT: '/auth/logout',
+ },
+ USERS: {
+ BASE: '/users',
+ BY_ID: (id: string) => `/users/${id}`,
+ ME: '/users/me',
+ },
+ // ... otros endpoints
+} as const;
+```
+
+### Uso en Componentes
+
+```typescript
+// src/apps/web/hooks/useAuth.ts
+import { APP_CONFIG } from '@/shared/config/constants';
+
+export const useAuth = () => {
+ const login = async (credentials: LoginCredentials) => {
+ const response = await api.post(API_ENDPOINTS.AUTH.LOGIN, credentials);
+
+ // Guardar token usando key centralizada
+ localStorage.setItem(
+ APP_CONFIG.STORAGE_KEYS.AUTH_TOKEN,
+ response.data.accessToken,
+ );
+ };
+
+ return { login, /* ... */ };
+};
+```
+
+---
+
+## 5. DATABASE
+
+### Configuracion de Conexion
+
+```typescript
+// src/shared/config/typeorm.config.ts
+import { DataSource, DataSourceOptions } from 'typeorm';
+import * as dotenv from 'dotenv';
+
+dotenv.config();
+
+export const dataSourceOptions: DataSourceOptions = {
+ type: 'postgres',
+ host: process.env.DB_HOST,
+ port: parseInt(process.env.DB_PORT, 10),
+ username: process.env.DB_USER,
+ password: process.env.DB_PASSWORD,
+ database: process.env.DB_NAME,
+ ssl: process.env.DB_SSL === 'true'
+ ? { rejectUnauthorized: false }
+ : false,
+
+ // Entities
+ entities: ['dist/**/*.entity.js'],
+
+ // Migrations
+ migrations: ['dist/migrations/*.js'],
+ migrationsTableName: 'migrations',
+
+ // Logging
+ logging: process.env.DB_LOGGING === 'true',
+ maxQueryExecutionTime: 1000, // Log queries > 1s
+
+ // Pool
+ extra: {
+ max: parseInt(process.env.DB_POOL_SIZE || '10', 10),
+ idleTimeoutMillis: 30000,
+ connectionTimeoutMillis: 10000,
+ },
+};
+
+// Para CLI de TypeORM
+export default new DataSource(dataSourceOptions);
+```
+
+---
+
+## 6. PATRON POR AMBIENTE
+
+### Configuracion Condicional
+
+```typescript
+// src/shared/config/by-environment.ts
+type Environment = 'development' | 'staging' | 'production' | 'test';
+
+interface EnvironmentConfig {
+ api: {
+ rateLimit: number;
+ timeout: number;
+ };
+ cache: {
+ ttl: number;
+ enabled: boolean;
+ };
+ features: {
+ debugMode: boolean;
+ mockExternalApis: boolean;
+ };
+}
+
+const configs: Record = {
+ development: {
+ api: {
+ rateLimit: 1000, // Muy alto para desarrollo
+ timeout: 60000,
+ },
+ cache: {
+ ttl: 60,
+ enabled: false, // Deshabilitado para desarrollo
+ },
+ features: {
+ debugMode: true,
+ mockExternalApis: true,
+ },
+ },
+ staging: {
+ api: {
+ rateLimit: 100,
+ timeout: 30000,
+ },
+ cache: {
+ ttl: 300,
+ enabled: true,
+ },
+ features: {
+ debugMode: true,
+ mockExternalApis: false,
+ },
+ },
+ production: {
+ api: {
+ rateLimit: 60,
+ timeout: 15000,
+ },
+ cache: {
+ ttl: 3600,
+ enabled: true,
+ },
+ features: {
+ debugMode: false,
+ mockExternalApis: false,
+ },
+ },
+ test: {
+ api: {
+ rateLimit: 10000,
+ timeout: 5000,
+ },
+ cache: {
+ ttl: 0,
+ enabled: false,
+ },
+ features: {
+ debugMode: true,
+ mockExternalApis: true,
+ },
+ },
+};
+
+export function getEnvironmentConfig(): EnvironmentConfig {
+ const env = (process.env.NODE_ENV || 'development') as Environment;
+ return configs[env];
+}
+```
+
+---
+
+## 7. SECRETOS Y SEGURIDAD
+
+### Nunca en Codigo
+
+```typescript
+// β INCORRECTO: Secretos hardcodeados
+const JWT_SECRET = 'my-super-secret-key-12345';
+const DB_PASSWORD = 'password123';
+
+// β
CORRECTO: Desde variables de entorno
+const JWT_SECRET = process.env.JWT_SECRET;
+const DB_PASSWORD = process.env.DB_PASSWORD;
+```
+
+### Validar Secretos Requeridos
+
+```typescript
+// src/shared/config/secrets.validation.ts
+const REQUIRED_SECRETS = [
+ 'JWT_SECRET',
+ 'DB_PASSWORD',
+];
+
+const OPTIONAL_SECRETS = [
+ 'SMTP_PASSWORD',
+ 'STRIPE_SECRET_KEY',
+];
+
+export function validateSecrets(): void {
+ const missing: string[] = [];
+
+ for (const secret of REQUIRED_SECRETS) {
+ if (!process.env[secret]) {
+ missing.push(secret);
+ }
+ }
+
+ if (missing.length > 0) {
+ throw new Error(
+ `Missing required secrets: ${missing.join(', ')}\n` +
+ 'Please check your .env file or environment variables.',
+ );
+ }
+
+ // Validar formato de secretos
+ if (process.env.JWT_SECRET && process.env.JWT_SECRET.length < 32) {
+ throw new Error('JWT_SECRET must be at least 32 characters');
+ }
+}
+```
+
+### Rotacion de Secretos
+
+```typescript
+// Soportar multiples secretos para rotacion
+const JWT_SECRETS = (process.env.JWT_SECRETS || process.env.JWT_SECRET).split(',');
+
+// Verificar token con cualquier secreto valido
+async function verifyToken(token: string): Promise {
+ for (const secret of JWT_SECRETS) {
+ try {
+ return jwt.verify(token, secret.trim()) as TokenPayload;
+ } catch {
+ continue; // Probar siguiente secreto
+ }
+ }
+ throw new UnauthorizedException('Invalid token');
+}
+
+// Firmar siempre con el primer secreto (mas reciente)
+function signToken(payload: TokenPayload): string {
+ return jwt.sign(payload, JWT_SECRETS[0].trim());
+}
+```
+
+---
+
+## 8. CHECKLIST DE CONFIGURACION
+
+```
+Setup inicial:
+[ ] .env.example creado con TODAS las variables
+[ ] .env en .gitignore
+[ ] Schema de validacion implementado
+[ ] App falla si configuracion invalida
+[ ] Tipos definidos para configuracion
+
+Seguridad:
+[ ] Ningun secreto en codigo fuente
+[ ] Ningun secreto en logs
+[ ] Secretos rotables (multiples valores soportados)
+[ ] Variables sensibles marcadas en documentacion
+
+Por ambiente:
+[ ] Configuracion diferenciada por ambiente
+[ ] Defaults seguros para produccion
+[ ] Modo debug deshabilitado en produccion
+[ ] Rate limiting apropiado por ambiente
+
+Documentacion:
+[ ] Cada variable documentada en .env.example
+[ ] README explica como configurar
+[ ] Variables opcionales vs requeridas claras
+```
+
+---
+
+## 9. ANTI-PATRONES
+
+```typescript
+// β ANTI-PATRON 1: Configuracion dispersa
+// archivo1.ts
+const API_URL = 'http://api.com';
+// archivo2.ts
+const apiUrl = process.env.API_URL || 'http://api.com';
+
+// β
CORRECTO: Centralizado
+// config/constants.ts
+export const API_URL = process.env.API_URL;
+```
+
+```typescript
+// β ANTI-PATRON 2: No validar
+const port = process.env.PORT; // Puede ser undefined o string invalido
+server.listen(port); // Error en runtime
+
+// β
CORRECTO: Validar y convertir
+const port = parseInt(process.env.PORT, 10);
+if (isNaN(port)) {
+ throw new Error('PORT must be a valid number');
+}
+```
+
+```typescript
+// β ANTI-PATRON 3: Defaults inseguros
+const DEBUG = process.env.DEBUG || true; // Debug activo por default
+
+// β
CORRECTO: Defaults seguros
+const DEBUG = process.env.DEBUG === 'true'; // False por default
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Patron de Codigo
diff --git a/core/orchestration/patrones/PATRON-EXCEPTION-HANDLING.md b/core/orchestration/patrones/PATRON-EXCEPTION-HANDLING.md
new file mode 100644
index 0000000..9ed9cee
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-EXCEPTION-HANDLING.md
@@ -0,0 +1,534 @@
+# PATRΓN: MANEJO DE EXCEPCIONES
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Aplica a:** Backend (NestJS/Express)
+**Prioridad:** OBLIGATORIA
+
+---
+
+## PROPΓSITO
+
+Definir patrones estΓ‘ndar de manejo de errores para garantizar respuestas consistentes y debugging efectivo.
+
+---
+
+## PRINCIPIO FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β EXCEPCIONES CLARAS Y CONSISTENTES β
+β β
+β 1. Usar HttpException estΓ‘ndar de NestJS β
+β 2. Mensajes claros para el usuario β
+β 3. Detalles tΓ©cnicos en logs (no en response) β
+β 4. CΓ³digos HTTP semΓ‘nticos β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 1. EXCEPCIONES HTTP ESTΓNDAR
+
+### Matriz de DecisiΓ³n
+
+| SituaciΓ³n | Exception | HTTP Code | CuΓ‘ndo Usar |
+|-----------|-----------|-----------|-------------|
+| Recurso no existe | `NotFoundException` | 404 | `findOne` retorna null |
+| Ya existe (duplicado) | `ConflictException` | 409 | ViolaciΓ³n de unique |
+| Datos invΓ‘lidos | `BadRequestException` | 400 | ValidaciΓ³n de negocio falla |
+| Sin autenticaciΓ³n | `UnauthorizedException` | 401 | Token falta o invΓ‘lido |
+| Sin permiso | `ForbiddenException` | 403 | Autenticado pero sin permiso |
+| MΓ©todo no permitido | `MethodNotAllowedException` | 405 | HTTP method incorrecto |
+| Payload muy grande | `PayloadTooLargeException` | 413 | Archivo/body excede lΓmite |
+| Rate limit | `TooManyRequestsException` | 429 | Muchas peticiones |
+| Error interno | `InternalServerErrorException` | 500 | Error inesperado |
+| Servicio no disponible | `ServiceUnavailableException` | 503 | DB/API externa caΓda |
+
+---
+
+## 2. PATRONES POR CASO
+
+### Not Found (404)
+
+```typescript
+// PATRΓN: Recurso no encontrado
+async findOne(id: string): Promise {
+ const user = await this.repository.findOne({ where: { id } });
+
+ if (!user) {
+ throw new NotFoundException(`Usuario con ID ${id} no encontrado`);
+ }
+
+ return user;
+}
+
+// PATRΓN: Recurso relacionado no encontrado
+async assignRole(userId: string, roleId: string): Promise {
+ const user = await this.userRepository.findOne({ where: { id: userId } });
+ if (!user) {
+ throw new NotFoundException(`Usuario ${userId} no encontrado`);
+ }
+
+ const role = await this.roleRepository.findOne({ where: { id: roleId } });
+ if (!role) {
+ throw new NotFoundException(`Rol ${roleId} no encontrado`);
+ }
+
+ // Proceder...
+}
+```
+
+### Conflict (409)
+
+```typescript
+// PATRΓN: Duplicado por campo ΓΊnico
+async create(dto: CreateUserDto): Promise {
+ const existing = await this.repository.findOne({
+ where: { email: dto.email },
+ });
+
+ if (existing) {
+ throw new ConflictException('El email ya estΓ‘ registrado');
+ }
+
+ return this.repository.save(this.repository.create(dto));
+}
+
+// PATRΓN: Duplicado con mΓΊltiples campos
+async createProduct(dto: CreateProductDto): Promise {
+ const existing = await this.repository.findOne({
+ where: {
+ sku: dto.sku,
+ tenantId: dto.tenantId,
+ },
+ });
+
+ if (existing) {
+ throw new ConflictException(
+ `Ya existe un producto con SKU ${dto.sku} en este tenant`
+ );
+ }
+
+ return this.repository.save(this.repository.create(dto));
+}
+```
+
+### Bad Request (400)
+
+```typescript
+// PATRΓN: ValidaciΓ³n de negocio
+async transfer(dto: TransferDto): Promise {
+ if (dto.fromAccountId === dto.toAccountId) {
+ throw new BadRequestException(
+ 'La cuenta origen y destino no pueden ser iguales'
+ );
+ }
+
+ const fromAccount = await this.findAccount(dto.fromAccountId);
+
+ if (fromAccount.balance < dto.amount) {
+ throw new BadRequestException('Saldo insuficiente para la transferencia');
+ }
+
+ // Proceder...
+}
+
+// PATRΓN: Estado invΓ‘lido para operaciΓ³n
+async cancelOrder(orderId: string): Promise {
+ const order = await this.findOne(orderId);
+
+ if (order.status === 'delivered') {
+ throw new BadRequestException(
+ 'No se puede cancelar un pedido ya entregado'
+ );
+ }
+
+ if (order.status === 'cancelled') {
+ throw new BadRequestException('El pedido ya estΓ‘ cancelado');
+ }
+
+ // Proceder...
+}
+```
+
+### Forbidden (403)
+
+```typescript
+// PATRΓN: Sin permiso sobre recurso
+async update(userId: string, dto: UpdateUserDto, currentUser: User): Promise {
+ const user = await this.findOne(userId);
+
+ // Solo el usuario mismo o admin puede editar
+ if (user.id !== currentUser.id && !currentUser.roles.includes('admin')) {
+ throw new ForbiddenException('No tienes permiso para editar este usuario');
+ }
+
+ return this.repository.save({ ...user, ...dto });
+}
+
+// PATRΓN: LΓmite de plan/tenant
+async createProject(dto: CreateProjectDto, tenant: Tenant): Promise {
+ const projectCount = await this.repository.count({
+ where: { tenantId: tenant.id },
+ });
+
+ if (projectCount >= tenant.plan.maxProjects) {
+ throw new ForbiddenException(
+ `Tu plan permite mΓ‘ximo ${tenant.plan.maxProjects} proyectos. ` +
+ 'Actualiza tu plan para crear mΓ‘s.'
+ );
+ }
+
+ // Proceder...
+}
+```
+
+### Unauthorized (401)
+
+```typescript
+// PATRΓN: Token invΓ‘lido (en Guard)
+@Injectable()
+export class JwtAuthGuard extends AuthGuard('jwt') {
+ handleRequest(err: any, user: any, info: any) {
+ if (err || !user) {
+ if (info?.name === 'TokenExpiredError') {
+ throw new UnauthorizedException('Tu sesiΓ³n ha expirado');
+ }
+ if (info?.name === 'JsonWebTokenError') {
+ throw new UnauthorizedException('Token invΓ‘lido');
+ }
+ throw new UnauthorizedException('No autenticado');
+ }
+ return user;
+ }
+}
+
+// PATRΓN: Credenciales incorrectas
+async login(dto: LoginDto): Promise {
+ const user = await this.userRepository.findOne({
+ where: { email: dto.email },
+ });
+
+ if (!user || !(await bcrypt.compare(dto.password, user.password))) {
+ throw new UnauthorizedException('Credenciales incorrectas');
+ }
+
+ // Generar token...
+}
+```
+
+### Internal Server Error (500)
+
+```typescript
+// PATRΓN: Error inesperado con logging
+async processPayment(dto: PaymentDto): Promise {
+ try {
+ const result = await this.paymentGateway.charge(dto);
+ return result;
+ } catch (error) {
+ // Log detallado para debugging
+ this.logger.error('Error procesando pago', {
+ dto,
+ error: error.message,
+ stack: error.stack,
+ gatewayResponse: error.response?.data,
+ });
+
+ // Respuesta genΓ©rica al usuario
+ throw new InternalServerErrorException(
+ 'Error procesando el pago. Por favor intenta de nuevo.'
+ );
+ }
+}
+```
+
+---
+
+## 3. ESTRUCTURA DE RESPUESTA DE ERROR
+
+### Formato EstΓ‘ndar
+
+```typescript
+// Respuesta de error estΓ‘ndar
+interface ErrorResponse {
+ statusCode: number;
+ message: string | string[];
+ error: string;
+ timestamp: string;
+ path: string;
+}
+
+// Ejemplo de respuesta
+{
+ "statusCode": 404,
+ "message": "Usuario con ID abc-123 no encontrado",
+ "error": "Not Found",
+ "timestamp": "2024-01-15T10:30:00.000Z",
+ "path": "/api/v1/users/abc-123"
+}
+```
+
+### Exception Filter Global
+
+```typescript
+// filters/http-exception.filter.ts
+import {
+ ExceptionFilter,
+ Catch,
+ ArgumentsHost,
+ HttpException,
+ HttpStatus,
+ Logger,
+} from '@nestjs/common';
+import { Request, Response } from 'express';
+
+@Catch()
+export class GlobalExceptionFilter implements ExceptionFilter {
+ private readonly logger = new Logger(GlobalExceptionFilter.name);
+
+ catch(exception: unknown, host: ArgumentsHost) {
+ const ctx = host.switchToHttp();
+ const response = ctx.getResponse();
+ const request = ctx.getRequest();
+
+ let status = HttpStatus.INTERNAL_SERVER_ERROR;
+ let message: string | string[] = 'Error interno del servidor';
+ let error = 'Internal Server Error';
+
+ if (exception instanceof HttpException) {
+ status = exception.getStatus();
+ const exceptionResponse = exception.getResponse();
+
+ if (typeof exceptionResponse === 'object') {
+ message = (exceptionResponse as any).message || exception.message;
+ error = (exceptionResponse as any).error || exception.name;
+ } else {
+ message = exceptionResponse;
+ }
+ } else if (exception instanceof Error) {
+ // Log error interno completo
+ this.logger.error('Unhandled exception', {
+ message: exception.message,
+ stack: exception.stack,
+ path: request.url,
+ method: request.method,
+ body: request.body,
+ user: (request as any).user?.id,
+ });
+ }
+
+ response.status(status).json({
+ statusCode: status,
+ message,
+ error,
+ timestamp: new Date().toISOString(),
+ path: request.url,
+ });
+ }
+}
+```
+
+---
+
+## 4. EXCEPCIONES PERSONALIZADAS
+
+### CuΓ‘ndo Crear ExcepciΓ³n Custom
+
+```typescript
+// CREAR excepciΓ³n custom cuando:
+// 1. Necesitas informaciΓ³n adicional estructurada
+// 2. El error es especΓfico del dominio
+// 3. Quieres diferenciar en handling
+
+// NO crear custom para errores HTTP estΓ‘ndar
+// β class UserNotFoundException extends HttpException {} // Usar NotFoundException
+```
+
+### Ejemplo ExcepciΓ³n Custom
+
+```typescript
+// exceptions/business.exception.ts
+export class InsufficientBalanceException extends BadRequestException {
+ constructor(
+ public readonly currentBalance: number,
+ public readonly requiredAmount: number,
+ ) {
+ super({
+ message: `Saldo insuficiente. Tienes $${currentBalance}, necesitas $${requiredAmount}`,
+ error: 'Insufficient Balance',
+ currentBalance,
+ requiredAmount,
+ deficit: requiredAmount - currentBalance,
+ });
+ }
+}
+
+// Uso
+if (account.balance < amount) {
+ throw new InsufficientBalanceException(account.balance, amount);
+}
+```
+
+### ExcepciΓ³n para Errores de IntegraciΓ³n
+
+```typescript
+// exceptions/integration.exception.ts
+export class PaymentGatewayException extends ServiceUnavailableException {
+ constructor(
+ public readonly gateway: string,
+ public readonly originalError: string,
+ ) {
+ super({
+ message: 'Error de conexiΓ³n con el servicio de pagos',
+ error: 'Payment Gateway Error',
+ gateway,
+ });
+ }
+}
+
+// Uso
+try {
+ await stripe.charges.create(params);
+} catch (error) {
+ throw new PaymentGatewayException('Stripe', error.message);
+}
+```
+
+---
+
+## 5. LOGGING DE ERRORES
+
+### Niveles de Log
+
+```typescript
+// logger.service.ts
+@Injectable()
+export class AppLogger {
+ private readonly logger = new Logger();
+
+ // ERROR: Errores que requieren atenciΓ³n
+ error(message: string, context: object) {
+ this.logger.error(message, { ...context, timestamp: new Date() });
+ }
+
+ // WARN: Situaciones anΓ³malas pero manejadas
+ warn(message: string, context: object) {
+ this.logger.warn(message, { ...context, timestamp: new Date() });
+ }
+
+ // INFO: Eventos importantes del negocio
+ info(message: string, context: object) {
+ this.logger.log(message, { ...context, timestamp: new Date() });
+ }
+
+ // DEBUG: InformaciΓ³n para desarrollo
+ debug(message: string, context: object) {
+ this.logger.debug(message, { ...context, timestamp: new Date() });
+ }
+}
+```
+
+### QuΓ© Loggear
+
+```typescript
+// SIEMPRE loggear en ERROR:
+{
+ message: 'DescripciΓ³n del error',
+ stack: error.stack, // Stack trace
+ userId: currentUser?.id, // QuiΓ©n causΓ³ el error
+ tenantId: currentUser?.tenant, // Contexto de tenant
+ requestId: request.id, // Para tracing
+ path: request.url, // Endpoint
+ method: request.method, // HTTP method
+ body: sanitize(request.body), // Body (sin passwords)
+ query: request.query, // Query params
+ timestamp: new Date(), // CuΓ‘ndo
+}
+
+// NUNCA loggear:
+// - Passwords
+// - Tokens
+// - Tarjetas de crΓ©dito
+// - Datos sensibles (CURP, RFC, etc.)
+```
+
+---
+
+## 6. DOCUMENTACIΓN SWAGGER
+
+```typescript
+// Documentar posibles errores en controller
+@Post()
+@ApiOperation({ summary: 'Crear usuario' })
+@ApiResponse({ status: 201, description: 'Usuario creado', type: UserEntity })
+@ApiResponse({ status: 400, description: 'Datos invΓ‘lidos' })
+@ApiResponse({ status: 409, description: 'Email ya registrado' })
+@ApiResponse({ status: 401, description: 'No autenticado' })
+@ApiResponse({ status: 403, description: 'Sin permisos' })
+async create(@Body() dto: CreateUserDto): Promise {
+ return this.service.create(dto);
+}
+```
+
+---
+
+## 7. CHECKLIST DE MANEJO DE ERRORES
+
+```
+Service:
+[ ] Cada mΓ©todo que busca por ID usa NotFoundException si no existe
+[ ] Operaciones de creaciΓ³n verifican duplicados β ConflictException
+[ ] Validaciones de negocio usan BadRequestException
+[ ] Verificaciones de permisos usan ForbiddenException
+[ ] Errores de integraciones externas tienen try/catch
+[ ] Errores inesperados se loggean con contexto completo
+[ ] Mensajes de error son claros para el usuario
+
+Controller:
+[ ] Swagger documenta posibles errores
+[ ] @ApiResponse para cada cΓ³digo de error posible
+
+Global:
+[ ] GlobalExceptionFilter configurado
+[ ] Logger configurado para errores
+[ ] Errores no exponen detalles tΓ©cnicos en producciΓ³n
+```
+
+---
+
+## ANTI-PATRONES
+
+```typescript
+// β NUNCA: Mensaje genΓ©rico sin contexto
+throw new BadRequestException('Error');
+
+// β
SIEMPRE: Mensaje descriptivo
+throw new BadRequestException('El email ya estΓ‘ registrado');
+
+// β NUNCA: Exponer stack trace en response
+throw new Error(error.stack);
+
+// β
SIEMPRE: Log interno, mensaje limpio al usuario
+this.logger.error('Error detallado', { stack: error.stack });
+throw new InternalServerErrorException('Error procesando solicitud');
+
+// β NUNCA: Catch vacΓo
+try { ... } catch (e) { }
+
+// β
SIEMPRE: Manejar o re-lanzar
+try { ... } catch (e) {
+ this.logger.error('Context', { error: e });
+ throw new InternalServerErrorException('Mensaje usuario');
+}
+
+// β NUNCA: 500 para errores de validaciΓ³n
+throw new InternalServerErrorException('Email invΓ‘lido');
+
+// β
SIEMPRE: CΓ³digo HTTP semΓ‘ntico
+throw new BadRequestException('Email invΓ‘lido');
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** PatrΓ³n de Excepciones
diff --git a/core/orchestration/patrones/PATRON-LOGGING.md b/core/orchestration/patrones/PATRON-LOGGING.md
new file mode 100644
index 0000000..d5fc9c5
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-LOGGING.md
@@ -0,0 +1,663 @@
+# PATRON DE LOGGING
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** RECOMENDADA - Seguir para consistencia
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Definir patrones estandarizados de logging para todas las capas del sistema, asegurando trazabilidad, debugging efectivo y monitoreo en produccion.
+
+---
+
+## 1. NIVELES DE LOG
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β NIVELES DE LOG (de menor a mayor severidad) β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β TRACE β Detalle extremo (solo desarrollo) β
+β DEBUG β Informacion de debugging β
+β INFO β Eventos normales del sistema β
+β WARN β Situaciones anormales pero manejables β
+β ERROR β Errores que afectan funcionalidad β
+β FATAL β Errores criticos que detienen el sistema β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+### Cuando Usar Cada Nivel
+
+| Nivel | Uso | Ejemplo |
+|-------|-----|---------|
+| **TRACE** | Flujo detallado de ejecucion | `Entering method findById with id=123` |
+| **DEBUG** | Variables, estados internos | `User cache hit: userId=123` |
+| **INFO** | Eventos de negocio normales | `Order created: orderId=456` |
+| **WARN** | Situaciones inesperadas no criticas | `Retry attempt 2/3 for external API` |
+| **ERROR** | Errores que necesitan atencion | `Failed to process payment: timeout` |
+| **FATAL** | Sistema no puede continuar | `Database connection lost` |
+
+---
+
+## 2. ESTRUCTURA DE LOG
+
+### Formato Estandar
+
+```typescript
+{
+ timestamp: "2025-12-08T10:30:45.123Z", // ISO 8601
+ level: "INFO", // Nivel
+ context: "UserService", // Clase/modulo origen
+ message: "User created successfully", // Mensaje descriptivo
+ correlationId: "req-abc123", // ID de request/transaccion
+ userId: "user-456", // Usuario (si aplica)
+ data: { // Datos adicionales
+ email: "user@example.com",
+ action: "create"
+ },
+ duration: 45 // Duracion en ms (si aplica)
+}
+```
+
+### Campos Obligatorios
+
+| Campo | Descripcion | Siempre |
+|-------|-------------|---------|
+| `timestamp` | Fecha/hora ISO 8601 | SI |
+| `level` | Nivel del log | SI |
+| `context` | Origen del log | SI |
+| `message` | Descripcion del evento | SI |
+| `correlationId` | ID para trazar request | EN PRODUCCION |
+
+### Campos Opcionales Recomendados
+
+| Campo | Cuando Usar |
+|-------|-------------|
+| `userId` | Cuando hay usuario autenticado |
+| `data` | Datos relevantes al evento |
+| `duration` | Para operaciones medibles |
+| `error` | Cuando es log de error |
+| `stack` | Stack trace en errores |
+
+---
+
+## 3. BACKEND (NestJS)
+
+### Configuracion del Logger
+
+```typescript
+// src/shared/logger/logger.service.ts
+import { Injectable, LoggerService, Scope } from '@nestjs/common';
+import { Logger } from 'winston';
+
+@Injectable({ scope: Scope.TRANSIENT })
+export class AppLogger implements LoggerService {
+ private context: string;
+ private correlationId: string;
+
+ constructor(private readonly logger: Logger) {}
+
+ setContext(context: string) {
+ this.context = context;
+ }
+
+ setCorrelationId(correlationId: string) {
+ this.correlationId = correlationId;
+ }
+
+ log(message: string, data?: Record) {
+ this.logger.info(message, {
+ context: this.context,
+ correlationId: this.correlationId,
+ ...data,
+ });
+ }
+
+ error(message: string, trace?: string, data?: Record) {
+ this.logger.error(message, {
+ context: this.context,
+ correlationId: this.correlationId,
+ stack: trace,
+ ...data,
+ });
+ }
+
+ warn(message: string, data?: Record) {
+ this.logger.warn(message, {
+ context: this.context,
+ correlationId: this.correlationId,
+ ...data,
+ });
+ }
+
+ debug(message: string, data?: Record) {
+ this.logger.debug(message, {
+ context: this.context,
+ correlationId: this.correlationId,
+ ...data,
+ });
+ }
+}
+```
+
+### Configuracion Winston
+
+```typescript
+// src/shared/logger/winston.config.ts
+import * as winston from 'winston';
+
+const { combine, timestamp, json, printf, colorize } = winston.format;
+
+// Formato para desarrollo
+const devFormat = combine(
+ colorize(),
+ timestamp(),
+ printf(({ timestamp, level, message, context, ...meta }) => {
+ return `${timestamp} [${context}] ${level}: ${message} ${
+ Object.keys(meta).length ? JSON.stringify(meta) : ''
+ }`;
+ }),
+);
+
+// Formato para produccion (JSON estructurado)
+const prodFormat = combine(
+ timestamp(),
+ json(),
+);
+
+export const winstonConfig: winston.LoggerOptions = {
+ level: process.env.LOG_LEVEL || 'info',
+ format: process.env.NODE_ENV === 'production' ? prodFormat : devFormat,
+ transports: [
+ new winston.transports.Console(),
+ // En produccion: agregar transports adicionales
+ // new winston.transports.File({ filename: 'error.log', level: 'error' }),
+ ],
+};
+```
+
+### Uso en Service
+
+```typescript
+// src/modules/user/services/user.service.ts
+@Injectable()
+export class UserService {
+ constructor(
+ private readonly logger: AppLogger,
+ private readonly repository: Repository,
+ ) {
+ this.logger.setContext(UserService.name);
+ }
+
+ async create(dto: CreateUserDto): Promise {
+ this.logger.log('Creating new user', { email: dto.email });
+
+ try {
+ const user = await this.repository.save(dto);
+
+ this.logger.log('User created successfully', {
+ userId: user.id,
+ email: user.email,
+ });
+
+ return user;
+ } catch (error) {
+ this.logger.error('Failed to create user', error.stack, {
+ email: dto.email,
+ errorCode: error.code,
+ });
+ throw error;
+ }
+ }
+
+ async findById(id: string): Promise {
+ this.logger.debug('Finding user by ID', { userId: id });
+
+ const startTime = Date.now();
+ const user = await this.repository.findOne({ where: { id } });
+ const duration = Date.now() - startTime;
+
+ if (!user) {
+ this.logger.warn('User not found', { userId: id, duration });
+ throw new NotFoundException(`User ${id} not found`);
+ }
+
+ this.logger.debug('User found', { userId: id, duration });
+ return user;
+ }
+}
+```
+
+### Interceptor para Correlation ID
+
+```typescript
+// src/shared/interceptors/correlation.interceptor.ts
+import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
+import { Observable } from 'rxjs';
+import { v4 as uuidv4 } from 'uuid';
+
+@Injectable()
+export class CorrelationInterceptor implements NestInterceptor {
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ const request = context.switchToHttp().getRequest();
+
+ // Usar header existente o generar nuevo
+ const correlationId = request.headers['x-correlation-id'] || uuidv4();
+
+ // Guardar en request para uso posterior
+ request.correlationId = correlationId;
+
+ // Agregar a response headers
+ const response = context.switchToHttp().getResponse();
+ response.setHeader('x-correlation-id', correlationId);
+
+ return next.handle();
+ }
+}
+```
+
+### Interceptor de Logging de Requests
+
+```typescript
+// src/shared/interceptors/logging.interceptor.ts
+import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
+import { Observable } from 'rxjs';
+import { tap } from 'rxjs/operators';
+
+@Injectable()
+export class LoggingInterceptor implements NestInterceptor {
+ constructor(private readonly logger: AppLogger) {
+ this.logger.setContext('HTTP');
+ }
+
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ const request = context.switchToHttp().getRequest();
+ const { method, url, correlationId, user } = request;
+ const startTime = Date.now();
+
+ this.logger.log('Incoming request', {
+ method,
+ url,
+ correlationId,
+ userId: user?.id,
+ });
+
+ return next.handle().pipe(
+ tap({
+ next: () => {
+ const duration = Date.now() - startTime;
+ this.logger.log('Request completed', {
+ method,
+ url,
+ correlationId,
+ duration,
+ statusCode: context.switchToHttp().getResponse().statusCode,
+ });
+ },
+ error: (error) => {
+ const duration = Date.now() - startTime;
+ this.logger.error('Request failed', error.stack, {
+ method,
+ url,
+ correlationId,
+ duration,
+ errorMessage: error.message,
+ });
+ },
+ }),
+ );
+ }
+}
+```
+
+---
+
+## 4. FRONTEND (React)
+
+### Logger Service
+
+```typescript
+// src/shared/services/logger.service.ts
+type LogLevel = 'debug' | 'info' | 'warn' | 'error';
+
+interface LogEntry {
+ timestamp: string;
+ level: LogLevel;
+ message: string;
+ context?: string;
+ data?: Record;
+ userId?: string;
+}
+
+class LoggerService {
+ private isDev = process.env.NODE_ENV === 'development';
+ private userId: string | null = null;
+
+ setUserId(userId: string | null) {
+ this.userId = userId;
+ }
+
+ private log(level: LogLevel, message: string, context?: string, data?: Record) {
+ const entry: LogEntry = {
+ timestamp: new Date().toISOString(),
+ level,
+ message,
+ context,
+ data,
+ userId: this.userId || undefined,
+ };
+
+ // En desarrollo: console
+ if (this.isDev) {
+ const consoleMethod = level === 'error' ? console.error :
+ level === 'warn' ? console.warn :
+ level === 'debug' ? console.debug : console.log;
+ consoleMethod(`[${entry.context}] ${message}`, data || '');
+ }
+
+ // En produccion: enviar a servicio de logging
+ if (!this.isDev && (level === 'error' || level === 'warn')) {
+ this.sendToServer(entry);
+ }
+ }
+
+ private async sendToServer(entry: LogEntry) {
+ try {
+ await fetch('/api/logs', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(entry),
+ });
+ } catch {
+ // Silently fail - don't cause more errors
+ }
+ }
+
+ debug(message: string, context?: string, data?: Record) {
+ this.log('debug', message, context, data);
+ }
+
+ info(message: string, context?: string, data?: Record) {
+ this.log('info', message, context, data);
+ }
+
+ warn(message: string, context?: string, data?: Record) {
+ this.log('warn', message, context, data);
+ }
+
+ error(message: string, context?: string, data?: Record) {
+ this.log('error', message, context, data);
+ }
+}
+
+export const logger = new LoggerService();
+```
+
+### Uso en Componentes
+
+```typescript
+// src/apps/web/pages/UsersPage.tsx
+import { logger } from '@/shared/services/logger.service';
+
+export const UsersPage = () => {
+ const { data, error, isLoading } = useUsers();
+
+ useEffect(() => {
+ logger.info('Users page mounted', 'UsersPage');
+ }, []);
+
+ useEffect(() => {
+ if (error) {
+ logger.error('Failed to load users', 'UsersPage', {
+ errorMessage: error.message,
+ });
+ }
+ }, [error]);
+
+ const handleDelete = async (userId: string) => {
+ logger.info('Deleting user', 'UsersPage', { userId });
+
+ try {
+ await deleteUser(userId);
+ logger.info('User deleted successfully', 'UsersPage', { userId });
+ } catch (err) {
+ logger.error('Failed to delete user', 'UsersPage', {
+ userId,
+ error: err.message,
+ });
+ }
+ };
+
+ return (/* ... */);
+};
+```
+
+### Error Boundary con Logging
+
+```typescript
+// src/shared/components/ErrorBoundary.tsx
+import { Component, ErrorInfo, ReactNode } from 'react';
+import { logger } from '@/shared/services/logger.service';
+
+interface Props {
+ children: ReactNode;
+ fallback?: ReactNode;
+}
+
+interface State {
+ hasError: boolean;
+}
+
+export class ErrorBoundary extends Component {
+ state = { hasError: false };
+
+ static getDerivedStateFromError(): State {
+ return { hasError: true };
+ }
+
+ componentDidCatch(error: Error, errorInfo: ErrorInfo) {
+ logger.error('React error boundary caught error', 'ErrorBoundary', {
+ error: error.message,
+ stack: error.stack,
+ componentStack: errorInfo.componentStack,
+ });
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return this.props.fallback || Something went wrong
;
+ }
+ return this.props.children;
+ }
+}
+```
+
+---
+
+## 5. DATABASE
+
+### Logging de Queries (TypeORM)
+
+```typescript
+// src/shared/config/typeorm.config.ts
+import { TypeOrmModuleOptions } from '@nestjs/typeorm';
+
+export const typeOrmConfig: TypeOrmModuleOptions = {
+ // ... otras opciones
+ logging: process.env.NODE_ENV === 'development'
+ ? ['query', 'error', 'warn']
+ : ['error'],
+ logger: 'advanced-console', // o custom logger
+ maxQueryExecutionTime: 1000, // Log queries > 1s
+};
+```
+
+### Custom Query Logger
+
+```typescript
+// src/shared/logger/typeorm.logger.ts
+import { Logger as TypeOrmLogger } from 'typeorm';
+import { AppLogger } from './logger.service';
+
+export class CustomTypeOrmLogger implements TypeOrmLogger {
+ constructor(private readonly logger: AppLogger) {
+ this.logger.setContext('TypeORM');
+ }
+
+ logQuery(query: string, parameters?: any[]) {
+ this.logger.debug('Query executed', {
+ query: query.substring(0, 500), // Truncar queries largas
+ parameters,
+ });
+ }
+
+ logQueryError(error: string, query: string, parameters?: any[]) {
+ this.logger.error('Query failed', undefined, {
+ error,
+ query: query.substring(0, 500),
+ parameters,
+ });
+ }
+
+ logQuerySlow(time: number, query: string, parameters?: any[]) {
+ this.logger.warn('Slow query detected', {
+ duration: time,
+ query: query.substring(0, 500),
+ parameters,
+ });
+ }
+
+ logSchemaBuild(message: string) {
+ this.logger.info(message);
+ }
+
+ logMigration(message: string) {
+ this.logger.info(message);
+ }
+
+ log(level: 'log' | 'info' | 'warn', message: any) {
+ if (level === 'warn') {
+ this.logger.warn(message);
+ } else {
+ this.logger.log(message);
+ }
+ }
+}
+```
+
+---
+
+## 6. QUE LOGUEAR Y QUE NO
+
+### SI Loguear
+
+```
+β
Inicio/fin de operaciones importantes
+β
Errores y excepciones (con contexto)
+β
Eventos de autenticacion (login, logout, failed attempts)
+β
Operaciones de negocio criticas (pagos, cambios de estado)
+β
Llamadas a APIs externas (request/response resumido)
+β
Queries lentas (>1s)
+β
Warnings de recursos (memoria, conexiones)
+β
Cambios de configuracion en runtime
+```
+
+### NO Loguear
+
+```
+β Datos sensibles (passwords, tokens, tarjetas)
+β PII sin necesidad (emails completos, nombres)
+β Cada iteracion de loops
+β Contenido completo de requests/responses grandes
+β Logs de debug en produccion
+β Informacion redundante
+β Stack traces en logs INFO/DEBUG
+```
+
+### Sanitizacion de Datos Sensibles
+
+```typescript
+// src/shared/utils/log-sanitizer.ts
+const SENSITIVE_FIELDS = ['password', 'token', 'secret', 'authorization', 'credit_card'];
+
+export function sanitizeForLogging(data: Record): Record {
+ const sanitized = { ...data };
+
+ for (const key of Object.keys(sanitized)) {
+ if (SENSITIVE_FIELDS.some(field => key.toLowerCase().includes(field))) {
+ sanitized[key] = '[REDACTED]';
+ } else if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
+ sanitized[key] = sanitizeForLogging(sanitized[key]);
+ }
+ }
+
+ return sanitized;
+}
+
+// Uso
+this.logger.log('User login attempt', sanitizeForLogging({
+ email: dto.email,
+ password: dto.password, // Se convierte en [REDACTED]
+}));
+```
+
+---
+
+## 7. CONFIGURACION POR AMBIENTE
+
+```typescript
+// src/shared/config/logger.config.ts
+export const loggerConfig = {
+ development: {
+ level: 'debug',
+ format: 'pretty',
+ includeTimestamp: true,
+ colorize: true,
+ },
+ staging: {
+ level: 'info',
+ format: 'json',
+ includeTimestamp: true,
+ colorize: false,
+ },
+ production: {
+ level: 'warn',
+ format: 'json',
+ includeTimestamp: true,
+ colorize: false,
+ // Enviar a servicio externo
+ externalService: {
+ enabled: true,
+ endpoint: process.env.LOG_ENDPOINT,
+ },
+ },
+};
+```
+
+---
+
+## 8. CHECKLIST DE LOGGING
+
+```
+Antes de hacer deploy:
+[ ] Logs no contienen datos sensibles
+[ ] Nivel de log apropiado para ambiente
+[ ] Errores tienen contexto suficiente para debug
+[ ] Correlation ID implementado
+[ ] Queries lentas se detectan
+[ ] Error boundary implementado en frontend
+
+En cada Service nuevo:
+[ ] Logger inyectado y contexto configurado
+[ ] Operaciones principales logueadas
+[ ] Errores logueados con stack trace
+[ ] Tiempos de operaciones criticas medidos
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Patron de Codigo
diff --git a/core/orchestration/patrones/PATRON-PERFORMANCE.md b/core/orchestration/patrones/PATRON-PERFORMANCE.md
new file mode 100644
index 0000000..4ed84f4
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-PERFORMANCE.md
@@ -0,0 +1,657 @@
+# PATRON DE PERFORMANCE
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** RECOMENDADA - Seguir para optimizacion
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Definir patrones de optimizacion de rendimiento para todas las capas del sistema, asegurando tiempos de respuesta aceptables y uso eficiente de recursos.
+
+---
+
+## 1. METRICAS OBJETIVO
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β OBJETIVOS DE PERFORMANCE β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β API Response Time: β
+β β’ P50: < 100ms β
+β β’ P95: < 500ms β
+β β’ P99: < 1000ms β
+β β
+β Database Queries: β
+β β’ Simple query: < 10ms β
+β β’ Complex query: < 100ms β
+β β’ Report query: < 1000ms β
+β β
+β Frontend: β
+β β’ First Contentful Paint: < 1.5s β
+β β’ Time to Interactive: < 3s β
+β β’ Largest Contentful Paint: < 2.5s β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. DATABASE PERFORMANCE
+
+### 2.1 Indices Efectivos
+
+```sql
+-- Indices para columnas frecuentemente filtradas
+CREATE INDEX idx_users_email ON auth.users(email);
+CREATE INDEX idx_users_status ON auth.users(status);
+
+-- Indice compuesto para queries frecuentes
+CREATE INDEX idx_orders_user_created
+ON core.orders(user_id, created_at DESC);
+
+-- Indice parcial para datos activos
+CREATE INDEX idx_users_active
+ON auth.users(email)
+WHERE status = 'active';
+
+-- Indice para busqueda de texto
+CREATE INDEX idx_products_name_gin
+ON core.products USING gin(to_tsvector('spanish', name));
+```
+
+### 2.2 Analisis de Queries
+
+```sql
+-- Ver plan de ejecucion
+EXPLAIN ANALYZE
+SELECT * FROM orders
+WHERE user_id = 'uuid-123'
+ AND created_at > NOW() - INTERVAL '30 days';
+
+-- Identificar queries lentas
+SELECT query, calls, mean_time, total_time
+FROM pg_stat_statements
+ORDER BY mean_time DESC
+LIMIT 10;
+```
+
+### 2.3 Evitar N+1 Queries
+
+```typescript
+// β INCORRECTO: N+1 queries
+async findAllWithOrders(): Promise {
+ const users = await this.userRepository.find();
+ // N queries adicionales para cargar orders
+ for (const user of users) {
+ user.orders = await this.orderRepository.find({
+ where: { userId: user.id }
+ });
+ }
+ return users;
+}
+
+// β
CORRECTO: Join en una query
+async findAllWithOrders(): Promise {
+ return this.userRepository.find({
+ relations: ['orders'], // TypeORM hace JOIN
+ });
+}
+
+// β
CORRECTO: QueryBuilder con control
+async findAllWithOrders(): Promise {
+ return this.userRepository
+ .createQueryBuilder('user')
+ .leftJoinAndSelect('user.orders', 'order')
+ .where('user.status = :status', { status: 'active' })
+ .orderBy('user.createdAt', 'DESC')
+ .getMany();
+}
+```
+
+### 2.4 Paginacion Eficiente
+
+```typescript
+// β INCORRECTO: OFFSET para paginas grandes
+async findPaginated(page: number, limit: number) {
+ return this.repository.find({
+ skip: (page - 1) * limit, // Lento en paginas grandes
+ take: limit,
+ });
+}
+
+// β
CORRECTO: Cursor-based pagination
+async findPaginatedByCursor(cursor?: string, limit: number = 20) {
+ const qb = this.repository
+ .createQueryBuilder('item')
+ .orderBy('item.createdAt', 'DESC')
+ .take(limit + 1); // +1 para saber si hay mas
+
+ if (cursor) {
+ const decodedCursor = this.decodeCursor(cursor);
+ qb.where('item.createdAt < :cursor', { cursor: decodedCursor });
+ }
+
+ const items = await qb.getMany();
+ const hasMore = items.length > limit;
+
+ if (hasMore) {
+ items.pop(); // Remover el extra
+ }
+
+ return {
+ data: items,
+ nextCursor: hasMore ? this.encodeCursor(items[items.length - 1]) : null,
+ hasMore,
+ };
+}
+```
+
+### 2.5 Select Solo Campos Necesarios
+
+```typescript
+// β INCORRECTO: Traer toda la entidad
+const users = await this.userRepository.find();
+
+// β
CORRECTO: Solo campos necesarios
+const users = await this.userRepository.find({
+ select: ['id', 'email', 'firstName'],
+});
+
+// β
CORRECTO: Con QueryBuilder
+const users = await this.userRepository
+ .createQueryBuilder('user')
+ .select(['user.id', 'user.email', 'user.firstName'])
+ .getMany();
+```
+
+---
+
+## 3. BACKEND PERFORMANCE
+
+### 3.1 Caching con Redis
+
+```typescript
+// src/shared/cache/cache.service.ts
+import { Injectable, Inject } from '@nestjs/common';
+import { CACHE_MANAGER } from '@nestjs/cache-manager';
+import { Cache } from 'cache-manager';
+
+@Injectable()
+export class CacheService {
+ constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
+
+ async get(key: string): Promise {
+ return this.cacheManager.get(key);
+ }
+
+ async set(key: string, value: T, ttlSeconds: number): Promise {
+ await this.cacheManager.set(key, value, ttlSeconds * 1000);
+ }
+
+ async del(key: string): Promise {
+ await this.cacheManager.del(key);
+ }
+
+ async delByPattern(pattern: string): Promise {
+ const keys = await this.cacheManager.store.keys(pattern);
+ await Promise.all(keys.map(key => this.cacheManager.del(key)));
+ }
+}
+```
+
+### 3.2 Cache Decorator
+
+```typescript
+// src/shared/decorators/cached.decorator.ts
+import { SetMetadata } from '@nestjs/common';
+
+export const CACHE_KEY = 'cache_key';
+export const CACHE_TTL = 'cache_ttl';
+
+export const Cached = (key: string, ttlSeconds: number = 300) => {
+ return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
+ SetMetadata(CACHE_KEY, key)(target, propertyKey, descriptor);
+ SetMetadata(CACHE_TTL, ttlSeconds)(target, propertyKey, descriptor);
+ };
+};
+
+// Interceptor que implementa el caching
+@Injectable()
+export class CacheInterceptor implements NestInterceptor {
+ constructor(
+ private readonly cacheService: CacheService,
+ private readonly reflector: Reflector,
+ ) {}
+
+ async intercept(context: ExecutionContext, next: CallHandler): Promise> {
+ const cacheKey = this.reflector.get(CACHE_KEY, context.getHandler());
+ if (!cacheKey) {
+ return next.handle();
+ }
+
+ const cacheTtl = this.reflector.get(CACHE_TTL, context.getHandler()) || 300;
+ const request = context.switchToHttp().getRequest();
+ const fullKey = `${cacheKey}:${JSON.stringify(request.query)}`;
+
+ const cached = await this.cacheService.get(fullKey);
+ if (cached) {
+ return of(cached);
+ }
+
+ return next.handle().pipe(
+ tap(async (data) => {
+ await this.cacheService.set(fullKey, data, cacheTtl);
+ }),
+ );
+ }
+}
+```
+
+### 3.3 Uso de Cache en Service
+
+```typescript
+// src/modules/product/services/product.service.ts
+@Injectable()
+export class ProductService {
+ constructor(
+ private readonly repository: Repository,
+ private readonly cacheService: CacheService,
+ ) {}
+
+ async findAll(query: ProductQueryDto): Promise {
+ const cacheKey = `products:list:${JSON.stringify(query)}`;
+
+ // Intentar obtener de cache
+ const cached = await this.cacheService.get(cacheKey);
+ if (cached) {
+ return cached;
+ }
+
+ // Query a BD
+ const products = await this.repository.find({
+ where: this.buildWhereClause(query),
+ take: query.limit,
+ });
+
+ // Guardar en cache (5 minutos)
+ await this.cacheService.set(cacheKey, products, 300);
+
+ return products;
+ }
+
+ async update(id: string, dto: UpdateProductDto): Promise {
+ const product = await this.repository.save({ id, ...dto });
+
+ // Invalidar cache relacionado
+ await this.cacheService.delByPattern('products:*');
+
+ return product;
+ }
+}
+```
+
+### 3.4 Compresion de Responses
+
+```typescript
+// src/main.ts
+import * as compression from 'compression';
+
+async function bootstrap() {
+ const app = await NestFactory.create(AppModule);
+
+ // Comprimir responses > 1kb
+ app.use(compression({
+ threshold: 1024,
+ level: 6, // Balance entre compresion y CPU
+ }));
+
+ await app.listen(3000);
+}
+```
+
+### 3.5 Lazy Loading de Modulos
+
+```typescript
+// Cargar modulo pesado solo cuando se necesita
+@Module({
+ imports: [
+ // Modulo de reportes cargado lazy
+ RouterModule.register([
+ {
+ path: 'reports',
+ module: ReportsModule,
+ },
+ ]),
+ ],
+})
+export class AppModule {}
+```
+
+---
+
+## 4. FRONTEND PERFORMANCE
+
+### 4.1 Code Splitting
+
+```typescript
+// β INCORRECTO: Importar todo
+import { HeavyComponent } from './HeavyComponent';
+
+// β
CORRECTO: Lazy loading
+const HeavyComponent = lazy(() => import('./HeavyComponent'));
+
+// Uso con Suspense
+}>
+
+
+```
+
+### 4.2 Memoizacion
+
+```typescript
+// React.memo para componentes puros
+const UserCard = memo(({ user }: { user: User }) => {
+ return (
+
+
{user.name}
+
{user.email}
+
+ );
+});
+
+// useMemo para calculos costosos
+const ExpensiveList = ({ items, filter }: Props) => {
+ const filteredItems = useMemo(
+ () => items.filter(item => complexFilter(item, filter)),
+ [items, filter], // Solo recalcular si cambian
+ );
+
+ return {filteredItems.map(/* ... */)}
;
+};
+
+// useCallback para funciones estables
+const ParentComponent = () => {
+ const [count, setCount] = useState(0);
+
+ const handleClick = useCallback(() => {
+ console.log('clicked');
+ }, []); // Funcion estable
+
+ return ;
+};
+```
+
+### 4.3 Virtualizacion de Listas
+
+```typescript
+// Para listas largas, usar virtualizacion
+import { useVirtualizer } from '@tanstack/react-virtual';
+
+const VirtualList = ({ items }: { items: Item[] }) => {
+ const parentRef = useRef(null);
+
+ const virtualizer = useVirtualizer({
+ count: items.length,
+ getScrollElement: () => parentRef.current,
+ estimateSize: () => 50, // Altura estimada de cada item
+ });
+
+ return (
+
+
+ {virtualizer.getVirtualItems().map(virtualItem => (
+
+
+
+ ))}
+
+
+ );
+};
+```
+
+### 4.4 Optimizacion de Imagenes
+
+```typescript
+// Componente de imagen optimizada
+const OptimizedImage = ({
+ src,
+ alt,
+ width,
+ height,
+}: ImageProps) => {
+ return (
+
+ );
+};
+
+// Con srcset para responsive
+const ResponsiveImage = ({ src, alt }: Props) => {
+ return (
+
+ );
+};
+```
+
+### 4.5 Debounce y Throttle
+
+```typescript
+// src/shared/hooks/useDebounce.ts
+import { useState, useEffect } from 'react';
+
+export function useDebounce(value: T, delay: number): T {
+ const [debouncedValue, setDebouncedValue] = useState(value);
+
+ useEffect(() => {
+ const timer = setTimeout(() => setDebouncedValue(value), delay);
+ return () => clearTimeout(timer);
+ }, [value, delay]);
+
+ return debouncedValue;
+}
+
+// Uso en busqueda
+const SearchInput = () => {
+ const [search, setSearch] = useState('');
+ const debouncedSearch = useDebounce(search, 300);
+
+ // Query solo se ejecuta cuando debouncedSearch cambia
+ const { data } = useQuery({
+ queryKey: ['search', debouncedSearch],
+ queryFn: () => api.search(debouncedSearch),
+ enabled: debouncedSearch.length > 2,
+ });
+
+ return setSearch(e.target.value)} />;
+};
+```
+
+### 4.6 React Query - Cache y Stale Time
+
+```typescript
+// src/shared/hooks/useProducts.ts
+export const useProducts = (filters: ProductFilters) => {
+ return useQuery({
+ queryKey: ['products', filters],
+ queryFn: () => productService.getAll(filters),
+ staleTime: 5 * 60 * 1000, // 5 minutos antes de refetch
+ gcTime: 30 * 60 * 1000, // 30 minutos en cache
+ placeholderData: keepPreviousData, // Mostrar datos anteriores mientras carga
+ });
+};
+
+// Prefetch para navegacion anticipada
+const ProductList = () => {
+ const queryClient = useQueryClient();
+
+ const handleMouseEnter = (productId: string) => {
+ // Prefetch detalle del producto
+ queryClient.prefetchQuery({
+ queryKey: ['product', productId],
+ queryFn: () => productService.getById(productId),
+ });
+ };
+
+ return (/* ... */);
+};
+```
+
+---
+
+## 5. API DESIGN PARA PERFORMANCE
+
+### 5.1 Campos Seleccionables
+
+```typescript
+// Permitir al cliente elegir campos
+@Get()
+async findAll(
+ @Query('fields') fields?: string, // ?fields=id,name,price
+): Promise[]> {
+ const select = fields?.split(',') || undefined;
+ return this.productService.findAll({ select });
+}
+```
+
+### 5.2 Expansion de Relaciones
+
+```typescript
+// Permitir expansion opcional de relaciones
+@Get(':id')
+async findOne(
+ @Param('id') id: string,
+ @Query('expand') expand?: string, // ?expand=category,reviews
+): Promise {
+ const relations = expand?.split(',') || [];
+ return this.productService.findOne(id, { relations });
+}
+```
+
+### 5.3 Batch Endpoints
+
+```typescript
+// Endpoint para multiples operaciones
+@Post('batch')
+async batchCreate(@Body() dtos: CreateProductDto[]): Promise {
+ // Una transaccion en lugar de N requests
+ return this.productService.createMany(dtos);
+}
+
+// Endpoint para multiples IDs
+@Get('batch')
+async batchGet(@Query('ids') ids: string): Promise {
+ const idArray = ids.split(',');
+ return this.productService.findByIds(idArray);
+}
+```
+
+---
+
+## 6. MONITORING Y PROFILING
+
+### 6.1 Metricas de API
+
+```typescript
+// src/shared/interceptors/metrics.interceptor.ts
+@Injectable()
+export class MetricsInterceptor implements NestInterceptor {
+ constructor(private readonly metricsService: MetricsService) {}
+
+ intercept(context: ExecutionContext, next: CallHandler): Observable {
+ const request = context.switchToHttp().getRequest();
+ const { method, url } = request;
+ const startTime = Date.now();
+
+ return next.handle().pipe(
+ tap({
+ next: () => {
+ const duration = Date.now() - startTime;
+ this.metricsService.recordRequest(method, url, 200, duration);
+ },
+ error: (error) => {
+ const duration = Date.now() - startTime;
+ this.metricsService.recordRequest(method, url, error.status || 500, duration);
+ },
+ }),
+ );
+ }
+}
+```
+
+### 6.2 Query Logging Condicional
+
+```typescript
+// Solo loguear queries lentas en produccion
+const typeOrmConfig: TypeOrmModuleOptions = {
+ logging: process.env.NODE_ENV === 'production' ? ['error', 'warn'] : true,
+ maxQueryExecutionTime: 1000, // Loguear queries > 1s
+};
+```
+
+---
+
+## 7. CHECKLIST DE PERFORMANCE
+
+```
+Database:
+[ ] Indices en columnas de WHERE frecuentes
+[ ] Indices compuestos para queries comunes
+[ ] No N+1 queries (usar JOIN/relations)
+[ ] Paginacion cursor-based para datasets grandes
+[ ] SELECT solo campos necesarios
+[ ] EXPLAIN ANALYZE en queries criticas
+
+Backend:
+[ ] Cache implementado para datos frecuentes
+[ ] Invalidacion de cache correcta
+[ ] Compresion habilitada
+[ ] Connection pooling configurado
+[ ] Timeouts apropiados
+
+Frontend:
+[ ] Code splitting / lazy loading
+[ ] Memoizacion donde corresponde
+[ ] Virtualizacion para listas largas
+[ ] Imagenes optimizadas y lazy loaded
+[ ] Debounce en inputs de busqueda
+[ ] React Query con staleTime apropiado
+
+API:
+[ ] Paginacion en endpoints de listas
+[ ] Campos seleccionables (opcional)
+[ ] Batch endpoints para operaciones multiples
+[ ] Rate limiting para proteger recursos
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Patron de Performance
diff --git a/core/orchestration/patrones/PATRON-SEGURIDAD.md b/core/orchestration/patrones/PATRON-SEGURIDAD.md
new file mode 100644
index 0000000..e7d99be
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-SEGURIDAD.md
@@ -0,0 +1,778 @@
+# PATRON DE SEGURIDAD
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Seguir en todo el codigo
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Definir patrones de seguridad obligatorios para prevenir vulnerabilidades comunes (OWASP Top 10) y proteger datos sensibles.
+
+---
+
+## 1. OWASP TOP 10 - RESUMEN
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β OWASP TOP 10 - 2021 β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β A01 - Broken Access Control β
+β A02 - Cryptographic Failures β
+β A03 - Injection β
+β A04 - Insecure Design β
+β A05 - Security Misconfiguration β
+β A06 - Vulnerable Components β
+β A07 - Authentication Failures β
+β A08 - Software Integrity Failures β
+β A09 - Logging & Monitoring Failures β
+β A10 - Server-Side Request Forgery (SSRF) β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. SANITIZACION DE INPUT
+
+### Backend - Validacion con class-validator
+
+```typescript
+// src/modules/user/dto/create-user.dto.ts
+import {
+ IsEmail,
+ IsString,
+ MinLength,
+ MaxLength,
+ Matches,
+ IsNotEmpty,
+} from 'class-validator';
+import { Transform } from 'class-transformer';
+import { ApiProperty } from '@nestjs/swagger';
+
+export class CreateUserDto {
+ @ApiProperty({ example: 'user@example.com' })
+ @IsEmail({}, { message: 'Email invalido' })
+ @MaxLength(255)
+ @Transform(({ value }) => value?.toLowerCase().trim()) // Sanitizar
+ email: string;
+
+ @ApiProperty({ example: 'John' })
+ @IsString()
+ @IsNotEmpty()
+ @MinLength(2)
+ @MaxLength(100)
+ @Matches(/^[a-zA-ZΓ-ΓΏ\s'-]+$/, {
+ message: 'Nombre solo puede contener letras',
+ })
+ @Transform(({ value }) => value?.trim()) // Sanitizar espacios
+ firstName: string;
+
+ @ApiProperty()
+ @IsString()
+ @MinLength(8)
+ @MaxLength(128)
+ @Matches(
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/,
+ { message: 'Password debe tener mayuscula, minuscula, numero y simbolo' },
+ )
+ password: string;
+}
+```
+
+### Sanitizacion de HTML (Prevenir XSS)
+
+```typescript
+// src/shared/utils/sanitizer.ts
+import DOMPurify from 'isomorphic-dompurify';
+
+export function sanitizeHtml(dirty: string): string {
+ return DOMPurify.sanitize(dirty, {
+ ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],
+ ALLOWED_ATTR: [],
+ });
+}
+
+export function stripHtml(dirty: string): string {
+ return DOMPurify.sanitize(dirty, {
+ ALLOWED_TAGS: [],
+ ALLOWED_ATTR: [],
+ });
+}
+
+// Uso en DTO
+@Transform(({ value }) => stripHtml(value))
+@IsString()
+comment: string;
+```
+
+### Prevenir SQL Injection
+
+```typescript
+// β INCORRECTO: SQL Injection vulnerable
+async findByName(name: string) {
+ return this.repository.query(
+ `SELECT * FROM users WHERE name = '${name}'` // VULNERABLE
+ );
+}
+
+// β
CORRECTO: Usar parametros
+async findByName(name: string) {
+ return this.repository.query(
+ 'SELECT * FROM users WHERE name = $1',
+ [name], // Parametrizado
+ );
+}
+
+// β
MEJOR: Usar QueryBuilder de TypeORM
+async findByName(name: string) {
+ return this.repository
+ .createQueryBuilder('user')
+ .where('user.name = :name', { name }) // Automaticamente seguro
+ .getMany();
+}
+```
+
+---
+
+## 3. AUTENTICACION
+
+### Password Hashing
+
+```typescript
+// src/shared/utils/password.util.ts
+import * as bcrypt from 'bcrypt';
+
+const SALT_ROUNDS = 12; // Minimo 10 para produccion
+
+export async function hashPassword(password: string): Promise {
+ return bcrypt.hash(password, SALT_ROUNDS);
+}
+
+export async function verifyPassword(
+ password: string,
+ hash: string,
+): Promise {
+ return bcrypt.compare(password, hash);
+}
+```
+
+### JWT con Refresh Tokens
+
+```typescript
+// src/modules/auth/services/auth.service.ts
+@Injectable()
+export class AuthService {
+ constructor(
+ private readonly jwtService: JwtService,
+ private readonly configService: ConfigService,
+ private readonly userService: UserService,
+ private readonly tokenService: RefreshTokenService,
+ ) {}
+
+ async login(dto: LoginDto): Promise {
+ const user = await this.validateUser(dto.email, dto.password);
+ if (!user) {
+ // Mensaje generico para no revelar si email existe
+ throw new UnauthorizedException('Credenciales invalidas');
+ }
+
+ const tokens = await this.generateTokens(user);
+
+ // Guardar refresh token hasheado en BD
+ await this.tokenService.saveRefreshToken(
+ user.id,
+ await hashPassword(tokens.refreshToken),
+ );
+
+ return tokens;
+ }
+
+ private async generateTokens(user: UserEntity): Promise {
+ const payload: JwtPayload = {
+ sub: user.id,
+ email: user.email,
+ roles: user.roles.map(r => r.name),
+ };
+
+ const [accessToken, refreshToken] = await Promise.all([
+ this.jwtService.signAsync(payload, {
+ secret: this.configService.get('JWT_SECRET'),
+ expiresIn: '15m', // Corta duracion
+ }),
+ this.jwtService.signAsync(
+ { sub: user.id, type: 'refresh' },
+ {
+ secret: this.configService.get('JWT_REFRESH_SECRET'),
+ expiresIn: '7d',
+ },
+ ),
+ ]);
+
+ return { accessToken, refreshToken };
+ }
+
+ async refresh(refreshToken: string): Promise {
+ try {
+ const payload = await this.jwtService.verifyAsync(refreshToken, {
+ secret: this.configService.get('JWT_REFRESH_SECRET'),
+ });
+
+ // Verificar que token existe en BD y no fue revocado
+ const storedToken = await this.tokenService.findByUserId(payload.sub);
+ if (!storedToken || !await verifyPassword(refreshToken, storedToken.hash)) {
+ throw new UnauthorizedException('Token invalido');
+ }
+
+ const user = await this.userService.findById(payload.sub);
+ return this.generateTokens(user);
+ } catch {
+ throw new UnauthorizedException('Token invalido o expirado');
+ }
+ }
+
+ async logout(userId: string): Promise {
+ // Revocar todos los refresh tokens del usuario
+ await this.tokenService.revokeAllUserTokens(userId);
+ }
+}
+```
+
+### Guard de Autenticacion
+
+```typescript
+// src/shared/guards/jwt-auth.guard.ts
+import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common';
+import { AuthGuard } from '@nestjs/passport';
+import { Reflector } from '@nestjs/core';
+import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
+
+@Injectable()
+export class JwtAuthGuard extends AuthGuard('jwt') {
+ constructor(private reflector: Reflector) {
+ super();
+ }
+
+ canActivate(context: ExecutionContext) {
+ // Verificar si es ruta publica
+ const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [
+ context.getHandler(),
+ context.getClass(),
+ ]);
+
+ if (isPublic) {
+ return true;
+ }
+
+ return super.canActivate(context);
+ }
+
+ handleRequest(err: any, user: any, info: any) {
+ if (err || !user) {
+ throw err || new UnauthorizedException('No autorizado');
+ }
+ return user;
+ }
+}
+```
+
+---
+
+## 4. AUTORIZACION (RBAC)
+
+### Roles y Permisos
+
+```typescript
+// src/shared/enums/roles.enum.ts
+export enum Role {
+ SUPER_ADMIN = 'super_admin',
+ ADMIN = 'admin',
+ MANAGER = 'manager',
+ USER = 'user',
+ GUEST = 'guest',
+}
+
+export enum Permission {
+ // Users
+ USER_CREATE = 'user:create',
+ USER_READ = 'user:read',
+ USER_UPDATE = 'user:update',
+ USER_DELETE = 'user:delete',
+
+ // Products
+ PRODUCT_CREATE = 'product:create',
+ PRODUCT_READ = 'product:read',
+ PRODUCT_UPDATE = 'product:update',
+ PRODUCT_DELETE = 'product:delete',
+}
+
+// Mapeo de roles a permisos
+export const ROLE_PERMISSIONS: Record = {
+ [Role.SUPER_ADMIN]: Object.values(Permission),
+ [Role.ADMIN]: [
+ Permission.USER_CREATE,
+ Permission.USER_READ,
+ Permission.USER_UPDATE,
+ Permission.PRODUCT_CREATE,
+ Permission.PRODUCT_READ,
+ Permission.PRODUCT_UPDATE,
+ Permission.PRODUCT_DELETE,
+ ],
+ [Role.MANAGER]: [
+ Permission.USER_READ,
+ Permission.PRODUCT_CREATE,
+ Permission.PRODUCT_READ,
+ Permission.PRODUCT_UPDATE,
+ ],
+ [Role.USER]: [
+ Permission.PRODUCT_READ,
+ ],
+ [Role.GUEST]: [],
+};
+```
+
+### Guard de Roles
+
+```typescript
+// src/shared/guards/roles.guard.ts
+import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
+import { Reflector } from '@nestjs/core';
+import { Role, Permission, ROLE_PERMISSIONS } from '../enums/roles.enum';
+
+@Injectable()
+export class RolesGuard implements CanActivate {
+ constructor(private reflector: Reflector) {}
+
+ canActivate(context: ExecutionContext): boolean {
+ const requiredRoles = this.reflector.getAllAndOverride('roles', [
+ context.getHandler(),
+ context.getClass(),
+ ]);
+
+ const requiredPermissions = this.reflector.getAllAndOverride(
+ 'permissions',
+ [context.getHandler(), context.getClass()],
+ );
+
+ if (!requiredRoles && !requiredPermissions) {
+ return true; // Sin restricciones
+ }
+
+ const { user } = context.switchToHttp().getRequest();
+
+ if (!user) {
+ throw new ForbiddenException('Usuario no autenticado');
+ }
+
+ // Verificar roles
+ if (requiredRoles?.length > 0) {
+ const hasRole = requiredRoles.some(role => user.roles?.includes(role));
+ if (!hasRole) {
+ throw new ForbiddenException('Rol insuficiente');
+ }
+ }
+
+ // Verificar permisos
+ if (requiredPermissions?.length > 0) {
+ const userPermissions = this.getUserPermissions(user.roles);
+ const hasPermission = requiredPermissions.every(
+ permission => userPermissions.includes(permission),
+ );
+ if (!hasPermission) {
+ throw new ForbiddenException('Permiso insuficiente');
+ }
+ }
+
+ return true;
+ }
+
+ private getUserPermissions(roles: Role[]): Permission[] {
+ const permissions = new Set();
+ for (const role of roles) {
+ for (const permission of ROLE_PERMISSIONS[role] || []) {
+ permissions.add(permission);
+ }
+ }
+ return Array.from(permissions);
+ }
+}
+```
+
+### Decoradores
+
+```typescript
+// src/shared/decorators/roles.decorator.ts
+import { SetMetadata } from '@nestjs/common';
+import { Role, Permission } from '../enums/roles.enum';
+
+export const Roles = (...roles: Role[]) => SetMetadata('roles', roles);
+export const Permissions = (...permissions: Permission[]) =>
+ SetMetadata('permissions', permissions);
+```
+
+### Uso en Controller
+
+```typescript
+// src/modules/user/controllers/user.controller.ts
+@Controller('users')
+@UseGuards(JwtAuthGuard, RolesGuard)
+export class UserController {
+ @Get()
+ @Roles(Role.ADMIN, Role.MANAGER)
+ findAll() {
+ return this.userService.findAll();
+ }
+
+ @Post()
+ @Permissions(Permission.USER_CREATE)
+ create(@Body() dto: CreateUserDto) {
+ return this.userService.create(dto);
+ }
+
+ @Delete(':id')
+ @Roles(Role.SUPER_ADMIN) // Solo super admin puede eliminar
+ remove(@Param('id') id: string) {
+ return this.userService.remove(id);
+ }
+}
+```
+
+---
+
+## 5. PROTECCION DE DATOS
+
+### Encriptacion de Datos Sensibles
+
+```typescript
+// src/shared/utils/encryption.util.ts
+import * as crypto from 'crypto';
+
+const ALGORITHM = 'aes-256-gcm';
+const IV_LENGTH = 16;
+const AUTH_TAG_LENGTH = 16;
+
+export function encrypt(text: string, key: string): string {
+ const iv = crypto.randomBytes(IV_LENGTH);
+ const cipher = crypto.createCipheriv(
+ ALGORITHM,
+ Buffer.from(key, 'hex'),
+ iv,
+ );
+
+ let encrypted = cipher.update(text, 'utf8', 'hex');
+ encrypted += cipher.final('hex');
+
+ const authTag = cipher.getAuthTag();
+
+ // IV + AuthTag + Encrypted
+ return iv.toString('hex') + authTag.toString('hex') + encrypted;
+}
+
+export function decrypt(encryptedText: string, key: string): string {
+ const iv = Buffer.from(encryptedText.slice(0, IV_LENGTH * 2), 'hex');
+ const authTag = Buffer.from(
+ encryptedText.slice(IV_LENGTH * 2, (IV_LENGTH + AUTH_TAG_LENGTH) * 2),
+ 'hex',
+ );
+ const encrypted = encryptedText.slice((IV_LENGTH + AUTH_TAG_LENGTH) * 2);
+
+ const decipher = crypto.createDecipheriv(
+ ALGORITHM,
+ Buffer.from(key, 'hex'),
+ iv,
+ );
+ decipher.setAuthTag(authTag);
+
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
+ decrypted += decipher.final('utf8');
+
+ return decrypted;
+}
+```
+
+### Columnas Encriptadas en Entity
+
+```typescript
+// src/shared/transformers/encrypted.transformer.ts
+import { ValueTransformer } from 'typeorm';
+import { encrypt, decrypt } from '../utils/encryption.util';
+
+export class EncryptedTransformer implements ValueTransformer {
+ constructor(private readonly key: string) {}
+
+ to(value: string | null): string | null {
+ if (!value) return null;
+ return encrypt(value, this.key);
+ }
+
+ from(value: string | null): string | null {
+ if (!value) return null;
+ return decrypt(value, this.key);
+ }
+}
+
+// Uso en Entity
+@Column({
+ type: 'text',
+ transformer: new EncryptedTransformer(process.env.ENCRYPTION_KEY),
+})
+ssn: string; // Se guarda encriptado en BD
+```
+
+### Nunca Exponer Datos Sensibles
+
+```typescript
+// β INCORRECTO: Exponer password en response
+@Get(':id')
+async findOne(@Param('id') id: string) {
+ return this.userRepository.findOne({ where: { id } });
+ // Retorna { id, email, password, ... } - PASSWORD EXPUESTO!
+}
+
+// β
CORRECTO: Usar ResponseDto que excluye campos sensibles
+@Get(':id')
+async findOne(@Param('id') id: string): Promise {
+ const user = await this.userService.findOne(id);
+ return plainToClass(UserResponseDto, user, {
+ excludeExtraneousValues: true,
+ });
+}
+
+// ResponseDto solo expone campos seguros
+export class UserResponseDto {
+ @Expose() id: string;
+ @Expose() email: string;
+ @Expose() firstName: string;
+ // password NO esta expuesto
+}
+```
+
+---
+
+## 6. RATE LIMITING
+
+### Implementacion con Throttler
+
+```typescript
+// src/app.module.ts
+import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
+
+@Module({
+ imports: [
+ ThrottlerModule.forRoot([
+ {
+ name: 'short',
+ ttl: 1000, // 1 segundo
+ limit: 3, // 3 requests por segundo
+ },
+ {
+ name: 'medium',
+ ttl: 10000, // 10 segundos
+ limit: 20, // 20 requests por 10 segundos
+ },
+ {
+ name: 'long',
+ ttl: 60000, // 1 minuto
+ limit: 100, // 100 requests por minuto
+ },
+ ]),
+ ],
+ providers: [
+ {
+ provide: APP_GUARD,
+ useClass: ThrottlerGuard,
+ },
+ ],
+})
+export class AppModule {}
+```
+
+### Rate Limiting por Endpoint
+
+```typescript
+// Rate limit especifico para login (prevenir brute force)
+@Post('login')
+@Throttle({ default: { limit: 5, ttl: 60000 } }) // 5 intentos por minuto
+async login(@Body() dto: LoginDto) {
+ return this.authService.login(dto);
+}
+
+// Endpoint sin rate limit
+@Get('health')
+@SkipThrottle()
+healthCheck() {
+ return { status: 'ok' };
+}
+```
+
+---
+
+## 7. HEADERS DE SEGURIDAD
+
+### Helmet Middleware
+
+```typescript
+// src/main.ts
+import helmet from 'helmet';
+
+async function bootstrap() {
+ const app = await NestFactory.create(AppModule);
+
+ // Headers de seguridad
+ app.use(helmet({
+ contentSecurityPolicy: {
+ directives: {
+ defaultSrc: ["'self'"],
+ styleSrc: ["'self'", "'unsafe-inline'"],
+ scriptSrc: ["'self'"],
+ imgSrc: ["'self'", 'data:', 'https:'],
+ },
+ },
+ hsts: {
+ maxAge: 31536000, // 1 aΓ±o
+ includeSubDomains: true,
+ },
+ }));
+
+ // CORS configurado
+ app.enableCors({
+ origin: process.env.CORS_ORIGINS?.split(',') || false,
+ methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
+ credentials: true,
+ });
+
+ await app.listen(3000);
+}
+```
+
+---
+
+## 8. FRONTEND - SEGURIDAD
+
+### Almacenamiento de Tokens
+
+```typescript
+// β INCORRECTO: Token en localStorage (vulnerable a XSS)
+localStorage.setItem('token', accessToken);
+
+// β
MEJOR: HttpOnly cookies (configurado desde backend)
+// El token se maneja automaticamente por el navegador
+
+// β
ALTERNATIVA: Si debe estar en JS, usar memoria
+class TokenStore {
+ private accessToken: string | null = null;
+
+ setToken(token: string) {
+ this.accessToken = token;
+ }
+
+ getToken(): string | null {
+ return this.accessToken;
+ }
+
+ clearToken() {
+ this.accessToken = null;
+ }
+}
+
+export const tokenStore = new TokenStore();
+```
+
+### Prevenir XSS en React
+
+```typescript
+// β INCORRECTO: dangerouslySetInnerHTML sin sanitizar
+
+
+// β
CORRECTO: Sanitizar primero
+import DOMPurify from 'dompurify';
+
+
+
+// β
MEJOR: Evitar dangerouslySetInnerHTML cuando sea posible
+{userInput}
// React escapa automaticamente
+```
+
+### Validacion en Frontend (Defense in Depth)
+
+```typescript
+// src/shared/schemas/user.schema.ts
+import { z } from 'zod';
+
+export const createUserSchema = z.object({
+ email: z.string()
+ .email('Email invalido')
+ .max(255)
+ .transform(v => v.toLowerCase().trim()),
+
+ firstName: z.string()
+ .min(2, 'Minimo 2 caracteres')
+ .max(100)
+ .regex(/^[a-zA-ZΓ-ΓΏ\s'-]+$/, 'Solo letras permitidas')
+ .transform(v => v.trim()),
+
+ password: z.string()
+ .min(8, 'Minimo 8 caracteres')
+ .max(128)
+ .regex(
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/,
+ 'Debe incluir mayuscula, minuscula, numero y simbolo',
+ ),
+});
+```
+
+---
+
+## 9. CHECKLIST DE SEGURIDAD
+
+```
+Input/Output:
+[ ] Todos los inputs validados con class-validator
+[ ] HTML sanitizado antes de renderizar
+[ ] SQL usa queries parametrizadas
+[ ] Datos sensibles nunca en logs
+[ ] ResponseDto excluye campos sensibles
+
+Autenticacion:
+[ ] Passwords hasheados con bcrypt (rounds >= 10)
+[ ] JWT con expiracion corta (< 15min)
+[ ] Refresh tokens almacenados hasheados
+[ ] Logout revoca tokens
+[ ] Mensajes de error genericos (no revelar info)
+
+Autorizacion:
+[ ] Guards en todos los endpoints protegidos
+[ ] Verificacion de ownership en recursos
+[ ] Roles y permisos implementados
+[ ] Principio de minimo privilegio
+
+Infraestructura:
+[ ] HTTPS obligatorio
+[ ] Headers de seguridad (Helmet)
+[ ] CORS configurado correctamente
+[ ] Rate limiting implementado
+[ ] Secrets en variables de entorno
+
+Frontend:
+[ ] No localStorage para tokens sensibles
+[ ] CSP configurado
+[ ] Validacion client-side (defense in depth)
+[ ] No exponer errores detallados a usuarios
+```
+
+---
+
+## 10. RECURSOS ADICIONALES
+
+- OWASP Cheat Sheets: https://cheatsheetseries.owasp.org/
+- NestJS Security: https://docs.nestjs.com/security/helmet
+- React Security: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Patron de Seguridad
diff --git a/core/orchestration/patrones/PATRON-TESTING.md b/core/orchestration/patrones/PATRON-TESTING.md
new file mode 100644
index 0000000..84812a6
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-TESTING.md
@@ -0,0 +1,727 @@
+# PATRΓN: TESTING
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Aplica a:** Backend (NestJS), Frontend (React)
+**Prioridad:** RECOMENDADA
+
+---
+
+## PROPΓSITO
+
+Definir patrones estΓ‘ndar de testing para garantizar cΓ³digo de calidad.
+
+---
+
+## 1. TIPOS DE TESTS
+
+| Tipo | QuΓ© Testea | Herramienta | Cobertura Objetivo |
+|------|------------|-------------|-------------------|
+| **Unit** | Funciones/Clases aisladas | Jest | 70%+ |
+| **Integration** | MΓ³dulos integrados | Jest + Supertest | 50%+ |
+| **E2E** | Flujos completos | Jest + Supertest | CrΓticos |
+| **Component** | Componentes React | React Testing Library | 60%+ |
+
+---
+
+## 2. BACKEND: TEST DE SERVICE
+
+### Template
+
+```typescript
+// user.service.spec.ts
+import { Test, TestingModule } from '@nestjs/testing';
+import { getRepositoryToken } from '@nestjs/typeorm';
+import { Repository } from 'typeorm';
+import { UserService } from './user.service';
+import { UserEntity } from '../entities/user.entity';
+import { CreateUserDto } from '../dto/create-user.dto';
+import { NotFoundException, ConflictException } from '@nestjs/common';
+
+describe('UserService', () => {
+ let service: UserService;
+ let repository: jest.Mocked>;
+
+ // Mock del repositorio
+ const mockRepository = {
+ find: jest.fn(),
+ findOne: jest.fn(),
+ create: jest.fn(),
+ save: jest.fn(),
+ remove: jest.fn(),
+ count: jest.fn(),
+ };
+
+ // Fixtures
+ const mockUser: UserEntity = {
+ id: '550e8400-e29b-41d4-a716-446655440000',
+ email: 'test@example.com',
+ name: 'Test User',
+ status: 'active',
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+
+ const createUserDto: CreateUserDto = {
+ email: 'new@example.com',
+ name: 'New User',
+ password: 'SecurePass123!',
+ };
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ providers: [
+ UserService,
+ {
+ provide: getRepositoryToken(UserEntity),
+ useValue: mockRepository,
+ },
+ ],
+ }).compile();
+
+ service = module.get(UserService);
+ repository = module.get(getRepositoryToken(UserEntity));
+
+ // Reset mocks
+ jest.clearAllMocks();
+ });
+
+ describe('findOne', () => {
+ it('should return user when found', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(mockUser);
+
+ // Act
+ const result = await service.findOne(mockUser.id);
+
+ // Assert
+ expect(result).toEqual(mockUser);
+ expect(mockRepository.findOne).toHaveBeenCalledWith({
+ where: { id: mockUser.id },
+ });
+ });
+
+ it('should throw NotFoundException when user not found', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(null);
+
+ // Act & Assert
+ await expect(service.findOne('non-existent-id'))
+ .rejects
+ .toThrow(NotFoundException);
+ });
+ });
+
+ describe('create', () => {
+ it('should create user successfully', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(null); // No existe
+ mockRepository.create.mockReturnValue(mockUser);
+ mockRepository.save.mockResolvedValue(mockUser);
+
+ // Act
+ const result = await service.create(createUserDto);
+
+ // Assert
+ expect(result).toEqual(mockUser);
+ expect(mockRepository.findOne).toHaveBeenCalled();
+ expect(mockRepository.create).toHaveBeenCalledWith(
+ expect.objectContaining({
+ email: createUserDto.email,
+ name: createUserDto.name,
+ })
+ );
+ expect(mockRepository.save).toHaveBeenCalled();
+ });
+
+ it('should throw ConflictException when email exists', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(mockUser); // Ya existe
+
+ // Act & Assert
+ await expect(service.create(createUserDto))
+ .rejects
+ .toThrow(ConflictException);
+
+ expect(mockRepository.save).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('findAll', () => {
+ it('should return array of users', async () => {
+ // Arrange
+ const users = [mockUser, { ...mockUser, id: '2' }];
+ mockRepository.find.mockResolvedValue(users);
+
+ // Act
+ const result = await service.findAll();
+
+ // Assert
+ expect(result).toHaveLength(2);
+ expect(mockRepository.find).toHaveBeenCalled();
+ });
+
+ it('should return empty array when no users', async () => {
+ // Arrange
+ mockRepository.find.mockResolvedValue([]);
+
+ // Act
+ const result = await service.findAll();
+
+ // Assert
+ expect(result).toHaveLength(0);
+ });
+ });
+
+ describe('update', () => {
+ it('should update user successfully', async () => {
+ // Arrange
+ const updateDto = { name: 'Updated Name' };
+ const updatedUser = { ...mockUser, ...updateDto };
+
+ mockRepository.findOne.mockResolvedValue(mockUser);
+ mockRepository.save.mockResolvedValue(updatedUser);
+
+ // Act
+ const result = await service.update(mockUser.id, updateDto);
+
+ // Assert
+ expect(result.name).toBe('Updated Name');
+ expect(mockRepository.save).toHaveBeenCalled();
+ });
+
+ it('should throw NotFoundException when user not found', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(null);
+
+ // Act & Assert
+ await expect(service.update('non-existent', { name: 'Test' }))
+ .rejects
+ .toThrow(NotFoundException);
+ });
+ });
+
+ describe('remove', () => {
+ it('should remove user successfully', async () => {
+ // Arrange
+ mockRepository.findOne.mockResolvedValue(mockUser);
+ mockRepository.remove.mockResolvedValue(mockUser);
+
+ // Act
+ await service.remove(mockUser.id);
+
+ // Assert
+ expect(mockRepository.remove).toHaveBeenCalledWith(mockUser);
+ });
+ });
+});
+```
+
+---
+
+## 3. BACKEND: TEST DE CONTROLLER
+
+### Template
+
+```typescript
+// user.controller.spec.ts
+import { Test, TestingModule } from '@nestjs/testing';
+import { UserController } from './user.controller';
+import { UserService } from '../services/user.service';
+import { CreateUserDto } from '../dto/create-user.dto';
+import { UserEntity } from '../entities/user.entity';
+import { NotFoundException } from '@nestjs/common';
+
+describe('UserController', () => {
+ let controller: UserController;
+ let service: jest.Mocked;
+
+ const mockService = {
+ findAll: jest.fn(),
+ findOne: jest.fn(),
+ create: jest.fn(),
+ update: jest.fn(),
+ remove: jest.fn(),
+ };
+
+ const mockUser: UserEntity = {
+ id: '550e8400-e29b-41d4-a716-446655440000',
+ email: 'test@example.com',
+ name: 'Test User',
+ status: 'active',
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+
+ beforeEach(async () => {
+ const module: TestingModule = await Test.createTestingModule({
+ controllers: [UserController],
+ providers: [
+ {
+ provide: UserService,
+ useValue: mockService,
+ },
+ ],
+ }).compile();
+
+ controller = module.get(UserController);
+ service = module.get(UserService);
+
+ jest.clearAllMocks();
+ });
+
+ describe('findAll', () => {
+ it('should return array of users', async () => {
+ // Arrange
+ mockService.findAll.mockResolvedValue([mockUser]);
+
+ // Act
+ const result = await controller.findAll();
+
+ // Assert
+ expect(result).toHaveLength(1);
+ expect(service.findAll).toHaveBeenCalled();
+ });
+ });
+
+ describe('findOne', () => {
+ it('should return user by id', async () => {
+ // Arrange
+ mockService.findOne.mockResolvedValue(mockUser);
+
+ // Act
+ const result = await controller.findOne(mockUser.id);
+
+ // Assert
+ expect(result).toEqual(mockUser);
+ expect(service.findOne).toHaveBeenCalledWith(mockUser.id);
+ });
+
+ it('should propagate NotFoundException', async () => {
+ // Arrange
+ mockService.findOne.mockRejectedValue(new NotFoundException());
+
+ // Act & Assert
+ await expect(controller.findOne('non-existent'))
+ .rejects
+ .toThrow(NotFoundException);
+ });
+ });
+
+ describe('create', () => {
+ it('should create and return user', async () => {
+ // Arrange
+ const createDto: CreateUserDto = {
+ email: 'new@example.com',
+ name: 'New User',
+ password: 'Pass123!',
+ };
+ mockService.create.mockResolvedValue(mockUser);
+
+ // Act
+ const result = await controller.create(createDto);
+
+ // Assert
+ expect(result).toEqual(mockUser);
+ expect(service.create).toHaveBeenCalledWith(createDto);
+ });
+ });
+
+ describe('update', () => {
+ it('should update and return user', async () => {
+ // Arrange
+ const updateDto = { name: 'Updated' };
+ const updated = { ...mockUser, ...updateDto };
+ mockService.update.mockResolvedValue(updated);
+
+ // Act
+ const result = await controller.update(mockUser.id, updateDto);
+
+ // Assert
+ expect(result.name).toBe('Updated');
+ expect(service.update).toHaveBeenCalledWith(mockUser.id, updateDto);
+ });
+ });
+
+ describe('remove', () => {
+ it('should remove user', async () => {
+ // Arrange
+ mockService.remove.mockResolvedValue(undefined);
+
+ // Act
+ await controller.remove(mockUser.id);
+
+ // Assert
+ expect(service.remove).toHaveBeenCalledWith(mockUser.id);
+ });
+ });
+});
+```
+
+---
+
+## 4. BACKEND: TEST E2E
+
+### Template
+
+```typescript
+// user.e2e-spec.ts
+import { Test, TestingModule } from '@nestjs/testing';
+import { INestApplication, ValidationPipe } from '@nestjs/common';
+import * as request from 'supertest';
+import { AppModule } from '../src/app.module';
+
+describe('UserController (e2e)', () => {
+ let app: INestApplication;
+ let createdUserId: string;
+
+ beforeAll(async () => {
+ const moduleFixture: TestingModule = await Test.createTestingModule({
+ imports: [AppModule],
+ }).compile();
+
+ app = moduleFixture.createNestApplication();
+ app.useGlobalPipes(new ValidationPipe());
+ await app.init();
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+
+ describe('/users (POST)', () => {
+ it('should create user', () => {
+ return request(app.getHttpServer())
+ .post('/users')
+ .send({
+ email: 'e2e@test.com',
+ name: 'E2E User',
+ password: 'SecurePass123!',
+ })
+ .expect(201)
+ .expect((res) => {
+ expect(res.body.id).toBeDefined();
+ expect(res.body.email).toBe('e2e@test.com');
+ createdUserId = res.body.id;
+ });
+ });
+
+ it('should reject invalid email', () => {
+ return request(app.getHttpServer())
+ .post('/users')
+ .send({
+ email: 'invalid-email',
+ name: 'Test',
+ password: 'Pass123!',
+ })
+ .expect(400);
+ });
+
+ it('should reject duplicate email', () => {
+ return request(app.getHttpServer())
+ .post('/users')
+ .send({
+ email: 'e2e@test.com', // Ya existe
+ name: 'Duplicate',
+ password: 'Pass123!',
+ })
+ .expect(409);
+ });
+ });
+
+ describe('/users (GET)', () => {
+ it('should return users list', () => {
+ return request(app.getHttpServer())
+ .get('/users')
+ .expect(200)
+ .expect((res) => {
+ expect(Array.isArray(res.body)).toBe(true);
+ });
+ });
+ });
+
+ describe('/users/:id (GET)', () => {
+ it('should return user by id', () => {
+ return request(app.getHttpServer())
+ .get(`/users/${createdUserId}`)
+ .expect(200)
+ .expect((res) => {
+ expect(res.body.id).toBe(createdUserId);
+ });
+ });
+
+ it('should return 404 for non-existent user', () => {
+ return request(app.getHttpServer())
+ .get('/users/550e8400-e29b-41d4-a716-446655440000')
+ .expect(404);
+ });
+ });
+
+ describe('/users/:id (PUT)', () => {
+ it('should update user', () => {
+ return request(app.getHttpServer())
+ .put(`/users/${createdUserId}`)
+ .send({ name: 'Updated Name' })
+ .expect(200)
+ .expect((res) => {
+ expect(res.body.name).toBe('Updated Name');
+ });
+ });
+ });
+
+ describe('/users/:id (DELETE)', () => {
+ it('should delete user', () => {
+ return request(app.getHttpServer())
+ .delete(`/users/${createdUserId}`)
+ .expect(204);
+ });
+ });
+});
+```
+
+---
+
+## 5. FRONTEND: TEST DE COMPONENTE
+
+### Template con React Testing Library
+
+```typescript
+// UserCard.test.tsx
+import { render, screen, fireEvent } from '@testing-library/react';
+import { UserCard } from './UserCard';
+import { User } from '@/types/user.types';
+
+describe('UserCard', () => {
+ const mockUser: User = {
+ id: '1',
+ email: 'test@example.com',
+ name: 'Test User',
+ status: 'active',
+ };
+
+ const mockOnEdit = jest.fn();
+ const mockOnDelete = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('should render user information', () => {
+ render();
+
+ expect(screen.getByText('Test User')).toBeInTheDocument();
+ expect(screen.getByText('test@example.com')).toBeInTheDocument();
+ });
+
+ it('should call onEdit when edit button clicked', () => {
+ render(
+
+ );
+
+ fireEvent.click(screen.getByRole('button', { name: /edit/i }));
+
+ expect(mockOnEdit).toHaveBeenCalledWith(mockUser);
+ });
+
+ it('should call onDelete when delete button clicked', () => {
+ render(
+
+ );
+
+ fireEvent.click(screen.getByRole('button', { name: /delete/i }));
+
+ expect(mockOnDelete).toHaveBeenCalledWith(mockUser.id);
+ });
+
+ it('should show loading state', () => {
+ render();
+
+ expect(screen.getByTestId('loading-skeleton')).toBeInTheDocument();
+ });
+
+ it('should hide actions when not provided', () => {
+ render();
+
+ expect(screen.queryByRole('button', { name: /edit/i })).not.toBeInTheDocument();
+ });
+});
+```
+
+---
+
+## 6. FRONTEND: TEST DE HOOK
+
+### Template
+
+```typescript
+// useUsers.test.tsx
+import { renderHook, waitFor } from '@testing-library/react';
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { useUsers, useCreateUser } from './useUsers';
+import { userService } from '@/services/user.service';
+
+// Mock del servicio
+jest.mock('@/services/user.service');
+const mockUserService = userService as jest.Mocked;
+
+describe('useUsers', () => {
+ const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: false,
+ },
+ },
+ });
+
+ const wrapper = ({ children }) => (
+
+ {children}
+
+ );
+
+ beforeEach(() => {
+ queryClient.clear();
+ jest.clearAllMocks();
+ });
+
+ describe('useUsers', () => {
+ it('should fetch users', async () => {
+ // Arrange
+ const mockUsers = [
+ { id: '1', name: 'User 1', email: 'u1@test.com' },
+ { id: '2', name: 'User 2', email: 'u2@test.com' },
+ ];
+ mockUserService.getAll.mockResolvedValue(mockUsers);
+
+ // Act
+ const { result } = renderHook(() => useUsers(), { wrapper });
+
+ // Assert - Initially loading
+ expect(result.current.isLoading).toBe(true);
+
+ // Wait for data
+ await waitFor(() => {
+ expect(result.current.isLoading).toBe(false);
+ });
+
+ expect(result.current.data).toEqual(mockUsers);
+ });
+
+ it('should handle error', async () => {
+ // Arrange
+ mockUserService.getAll.mockRejectedValue(new Error('Network error'));
+
+ // Act
+ const { result } = renderHook(() => useUsers(), { wrapper });
+
+ await waitFor(() => {
+ expect(result.current.isError).toBe(true);
+ });
+
+ expect(result.current.error).toBeDefined();
+ });
+ });
+
+ describe('useCreateUser', () => {
+ it('should create user and invalidate cache', async () => {
+ // Arrange
+ const newUser = { id: '3', name: 'New', email: 'new@test.com' };
+ mockUserService.create.mockResolvedValue(newUser);
+
+ // Act
+ const { result } = renderHook(() => useCreateUser(), { wrapper });
+
+ await result.current.mutateAsync({
+ name: 'New',
+ email: 'new@test.com',
+ password: 'Pass123!',
+ });
+
+ // Assert
+ expect(mockUserService.create).toHaveBeenCalled();
+ });
+ });
+});
+```
+
+---
+
+## 7. CONVENCIONES DE NOMBRES
+
+```typescript
+// Archivos de test
+user.service.spec.ts // Unit test backend
+user.controller.spec.ts // Unit test controller
+user.e2e-spec.ts // E2E test
+UserCard.test.tsx // Component test
+useUsers.test.tsx // Hook test
+
+// Describe blocks
+describe('UserService', () => { ... });
+describe('findOne', () => { ... });
+
+// Test cases
+it('should return user when found', () => { ... });
+it('should throw NotFoundException when user not found', () => { ... });
+```
+
+---
+
+## 8. CHECKLIST DE TESTING
+
+```
+Por Service:
+[ ] Test de cada mΓ©todo pΓΊblico
+[ ] Test de casos de Γ©xito
+[ ] Test de casos de error (NotFoundException, etc.)
+[ ] Test de validaciones de negocio
+
+Por Controller:
+[ ] Test de cada endpoint
+[ ] Test de status codes correctos
+[ ] Test de propagaciΓ³n de errores
+
+Por Componente:
+[ ] Test de render correcto
+[ ] Test de eventos (click, change)
+[ ] Test de estados (loading, error)
+[ ] Test de props opcionales
+
+Por Hook:
+[ ] Test de fetch exitoso
+[ ] Test de manejo de error
+[ ] Test de mutaciones
+
+Cobertura:
+[ ] npm run test:cov muestra 70%+ en services
+[ ] npm run test:cov muestra 60%+ en components
+[ ] Tests crΓticos e2e pasan
+```
+
+---
+
+## 9. COMANDOS
+
+```bash
+# Backend
+npm run test # Unit tests
+npm run test:watch # Watch mode
+npm run test:cov # Con cobertura
+npm run test:e2e # E2E tests
+
+# Frontend
+npm run test # All tests
+npm run test -- --watch # Watch mode
+npm run test -- --coverage # Con cobertura
+npm run test -- UserCard # Test especΓfico
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** PatrΓ³n de Testing
diff --git a/core/orchestration/patrones/PATRON-TRANSACCIONES.md b/core/orchestration/patrones/PATRON-TRANSACCIONES.md
new file mode 100644
index 0000000..b2838ba
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-TRANSACCIONES.md
@@ -0,0 +1,678 @@
+# PATRON DE TRANSACCIONES
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - Seguir para integridad de datos
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPOSITO
+
+Definir patrones de manejo de transacciones de base de datos para garantizar integridad de datos, consistencia y correcta recuperacion de errores.
+
+---
+
+## 1. PRINCIPIOS ACID
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PROPIEDADES ACID β
+β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
+β β
+β A - Atomicity (Atomicidad) β
+β Todo o nada. Si una parte falla, se revierte todo. β
+β β
+β C - Consistency (Consistencia) β
+β La BD pasa de un estado valido a otro estado valido. β
+β β
+β I - Isolation (Aislamiento) β
+β Transacciones concurrentes no interfieren entre si. β
+β β
+β D - Durability (Durabilidad) β
+β Una vez confirmada, la transaccion persiste. β
+β β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. CUANDO USAR TRANSACCIONES
+
+### SI Usar Transaccion
+
+```
+β
Multiples operaciones que deben ser atomicas
+β
Operaciones que afectan multiples tablas relacionadas
+β
Operaciones financieras o criticas
+β
Creacion de entidades con relaciones obligatorias
+β
Actualizaciones que requieren consistencia
+```
+
+### NO Necesitas Transaccion
+
+```
+β Una sola query simple (SELECT, INSERT, UPDATE)
+β Operaciones de solo lectura
+β Operaciones independientes sin relacion
+```
+
+---
+
+## 3. TYPEORM - METODOS DE TRANSACCION
+
+### 3.1 QueryRunner (Recomendado para control total)
+
+```typescript
+// src/modules/order/services/order.service.ts
+import { Injectable } from '@nestjs/common';
+import { DataSource, QueryRunner } from 'typeorm';
+
+@Injectable()
+export class OrderService {
+ constructor(private readonly dataSource: DataSource) {}
+
+ async createOrder(dto: CreateOrderDto): Promise {
+ // Crear QueryRunner
+ const queryRunner = this.dataSource.createQueryRunner();
+
+ // Conectar y comenzar transaccion
+ await queryRunner.connect();
+ await queryRunner.startTransaction();
+
+ try {
+ // 1. Crear la orden
+ const order = queryRunner.manager.create(OrderEntity, {
+ userId: dto.userId,
+ status: OrderStatus.PENDING,
+ total: 0,
+ });
+ await queryRunner.manager.save(order);
+
+ // 2. Crear items y calcular total
+ let total = 0;
+ for (const item of dto.items) {
+ // Verificar stock
+ const product = await queryRunner.manager.findOne(ProductEntity, {
+ where: { id: item.productId },
+ lock: { mode: 'pessimistic_write' }, // Lock para evitar race condition
+ });
+
+ if (!product || product.stock < item.quantity) {
+ throw new BadRequestException(
+ `Stock insuficiente para producto ${item.productId}`,
+ );
+ }
+
+ // Crear item
+ const orderItem = queryRunner.manager.create(OrderItemEntity, {
+ orderId: order.id,
+ productId: item.productId,
+ quantity: item.quantity,
+ price: product.price,
+ });
+ await queryRunner.manager.save(orderItem);
+
+ // Actualizar stock
+ product.stock -= item.quantity;
+ await queryRunner.manager.save(product);
+
+ total += product.price * item.quantity;
+ }
+
+ // 3. Actualizar total de la orden
+ order.total = total;
+ await queryRunner.manager.save(order);
+
+ // 4. Confirmar transaccion
+ await queryRunner.commitTransaction();
+
+ return order;
+
+ } catch (error) {
+ // Revertir en caso de error
+ await queryRunner.rollbackTransaction();
+ throw error;
+
+ } finally {
+ // Liberar QueryRunner
+ await queryRunner.release();
+ }
+ }
+}
+```
+
+### 3.2 DataSource.transaction() (Mas simple)
+
+```typescript
+// Para casos mas simples
+async createUserWithProfile(dto: CreateUserWithProfileDto): Promise {
+ return this.dataSource.transaction(async (manager) => {
+ // Crear usuario
+ const user = manager.create(UserEntity, {
+ email: dto.email,
+ password: await hashPassword(dto.password),
+ });
+ await manager.save(user);
+
+ // Crear perfil
+ const profile = manager.create(ProfileEntity, {
+ userId: user.id,
+ firstName: dto.firstName,
+ lastName: dto.lastName,
+ });
+ await manager.save(profile);
+
+ return user;
+ });
+}
+```
+
+### 3.3 @Transaction Decorator (NestJS)
+
+```typescript
+// src/shared/decorators/transactional.decorator.ts
+import { DataSource } from 'typeorm';
+
+export function Transactional() {
+ return function (
+ target: any,
+ propertyKey: string,
+ descriptor: PropertyDescriptor,
+ ) {
+ const originalMethod = descriptor.value;
+
+ descriptor.value = async function (...args: any[]) {
+ const dataSource: DataSource = this.dataSource;
+
+ return dataSource.transaction(async (manager) => {
+ // Inyectar manager temporal
+ const originalManager = this.manager;
+ this.manager = manager;
+
+ try {
+ return await originalMethod.apply(this, args);
+ } finally {
+ this.manager = originalManager;
+ }
+ });
+ };
+
+ return descriptor;
+ };
+}
+
+// Uso
+@Injectable()
+export class OrderService {
+ constructor(
+ private readonly dataSource: DataSource,
+ @InjectRepository(OrderEntity)
+ private readonly orderRepository: Repository,
+ ) {}
+
+ private manager: EntityManager;
+
+ @Transactional()
+ async createOrder(dto: CreateOrderDto): Promise {
+ // this.manager es el manager transaccional
+ const order = this.manager.create(OrderEntity, dto);
+ return this.manager.save(order);
+ }
+}
+```
+
+---
+
+## 4. NIVELES DE AISLAMIENTO
+
+### Niveles Disponibles
+
+| Nivel | Dirty Reads | Non-Repeatable Reads | Phantom Reads |
+|-------|-------------|---------------------|---------------|
+| READ UNCOMMITTED | Posible | Posible | Posible |
+| READ COMMITTED | No | Posible | Posible |
+| REPEATABLE READ | No | No | Posible |
+| SERIALIZABLE | No | No | No |
+
+### Configurar Nivel de Aislamiento
+
+```typescript
+// Por defecto PostgreSQL usa READ COMMITTED
+// Para operaciones criticas, usar SERIALIZABLE
+
+async processPayment(orderId: string): Promise {
+ const queryRunner = this.dataSource.createQueryRunner();
+ await queryRunner.connect();
+
+ // Configurar nivel de aislamiento
+ await queryRunner.startTransaction('SERIALIZABLE');
+
+ try {
+ // Operaciones criticas aqui
+ await queryRunner.commitTransaction();
+ } catch (error) {
+ await queryRunner.rollbackTransaction();
+
+ // SERIALIZABLE puede fallar por conflictos
+ if (error.code === '40001') { // Serialization failure
+ // Reintentar la transaccion
+ return this.processPayment(orderId);
+ }
+ throw error;
+ } finally {
+ await queryRunner.release();
+ }
+}
+```
+
+---
+
+## 5. LOCKS (BLOQUEOS)
+
+### 5.1 Pessimistic Locking
+
+```typescript
+// Bloquear fila para escritura (otros esperan)
+async updateStock(productId: string, quantity: number): Promise {
+ return this.dataSource.transaction(async (manager) => {
+ // Obtener producto con lock exclusivo
+ const product = await manager.findOne(ProductEntity, {
+ where: { id: productId },
+ lock: { mode: 'pessimistic_write' },
+ });
+
+ if (product.stock < quantity) {
+ throw new BadRequestException('Stock insuficiente');
+ }
+
+ product.stock -= quantity;
+ await manager.save(product);
+ });
+}
+```
+
+### 5.2 Optimistic Locking (Version)
+
+```typescript
+// Entity con columna de version
+@Entity()
+export class ProductEntity {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column()
+ stock: number;
+
+ @VersionColumn() // Auto-incrementa en cada update
+ version: number;
+}
+
+// El update falla si version cambio (alguien mas modifico)
+async updateStock(productId: string, quantity: number): Promise {
+ const product = await this.productRepository.findOne({
+ where: { id: productId },
+ });
+
+ product.stock -= quantity;
+
+ try {
+ await this.productRepository.save(product);
+ } catch (error) {
+ if (error instanceof OptimisticLockVersionMismatchError) {
+ // Reintentar o notificar conflicto
+ throw new ConflictException('El producto fue modificado. Reintente.');
+ }
+ throw error;
+ }
+}
+```
+
+### Cuando Usar Cada Tipo
+
+| Scenario | Lock Recomendado |
+|----------|------------------|
+| Alta concurrencia, conflictos raros | Optimistic |
+| Operaciones financieras criticas | Pessimistic |
+| Updates frecuentes al mismo registro | Pessimistic |
+| Lecturas frecuentes, updates raros | Optimistic |
+
+---
+
+## 6. PATRONES COMUNES
+
+### 6.1 Unit of Work Pattern
+
+```typescript
+// src/shared/database/unit-of-work.ts
+@Injectable()
+export class UnitOfWork {
+ private queryRunner: QueryRunner;
+
+ constructor(private readonly dataSource: DataSource) {}
+
+ async begin(): Promise {
+ this.queryRunner = this.dataSource.createQueryRunner();
+ await this.queryRunner.connect();
+ await this.queryRunner.startTransaction();
+ }
+
+ getRepository(entity: EntityTarget): Repository {
+ return this.queryRunner.manager.getRepository(entity);
+ }
+
+ async commit(): Promise {
+ await this.queryRunner.commitTransaction();
+ await this.queryRunner.release();
+ }
+
+ async rollback(): Promise {
+ await this.queryRunner.rollbackTransaction();
+ await this.queryRunner.release();
+ }
+}
+
+// Uso
+@Injectable()
+export class OrderService {
+ constructor(private readonly uow: UnitOfWork) {}
+
+ async createOrder(dto: CreateOrderDto): Promise {
+ await this.uow.begin();
+
+ try {
+ const orderRepo = this.uow.getRepository(OrderEntity);
+ const productRepo = this.uow.getRepository(ProductEntity);
+
+ // Operaciones...
+
+ await this.uow.commit();
+ return order;
+ } catch (error) {
+ await this.uow.rollback();
+ throw error;
+ }
+ }
+}
+```
+
+### 6.2 Saga Pattern (Para transacciones distribuidas)
+
+```typescript
+// Cuando no puedes usar transaccion de BD (microservicios)
+interface SagaStep {
+ execute(): Promise;
+ compensate(): Promise; // Revertir si falla
+}
+
+class CreateOrderSaga {
+ private executedSteps: SagaStep[] = [];
+
+ async execute(steps: SagaStep[]): Promise {
+ try {
+ for (const step of steps) {
+ await step.execute();
+ this.executedSteps.push(step);
+ }
+ } catch (error) {
+ // Compensar en orden inverso
+ for (const step of this.executedSteps.reverse()) {
+ await step.compensate();
+ }
+ throw error;
+ }
+ }
+}
+
+// Uso
+const saga = new CreateOrderSaga();
+await saga.execute([
+ {
+ execute: () => this.orderService.create(orderDto),
+ compensate: () => this.orderService.delete(orderId),
+ },
+ {
+ execute: () => this.inventoryService.reserve(items),
+ compensate: () => this.inventoryService.release(items),
+ },
+ {
+ execute: () => this.paymentService.charge(payment),
+ compensate: () => this.paymentService.refund(payment),
+ },
+]);
+```
+
+### 6.3 Retry con Backoff
+
+```typescript
+// Para manejar deadlocks y conflictos
+async withRetry(
+ operation: () => Promise,
+ maxRetries: number = 3,
+ baseDelay: number = 100,
+): Promise {
+ let lastError: Error;
+
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
+ try {
+ return await operation();
+ } catch (error) {
+ lastError = error;
+
+ // Solo reintentar errores transitorios
+ const isRetryable =
+ error.code === '40001' || // Serialization failure
+ error.code === '40P01' || // Deadlock
+ error.code === '55P03'; // Lock not available
+
+ if (!isRetryable || attempt === maxRetries) {
+ throw error;
+ }
+
+ // Exponential backoff con jitter
+ const delay = baseDelay * Math.pow(2, attempt - 1) * (0.5 + Math.random());
+ await new Promise(resolve => setTimeout(resolve, delay));
+ }
+ }
+
+ throw lastError;
+}
+
+// Uso
+async createOrder(dto: CreateOrderDto): Promise {
+ return this.withRetry(() => this.createOrderTransaction(dto));
+}
+```
+
+---
+
+## 7. ERRORES COMUNES Y SOLUCIONES
+
+### 7.1 Deadlock
+
+```typescript
+// β PROBLEMA: Deadlock por orden inconsistente de locks
+// Transaction 1: Lock A, then B
+// Transaction 2: Lock B, then A
+
+// β
SOLUCION: Siempre lockear en el mismo orden
+async transferFunds(fromId: string, toId: string, amount: number): Promise {
+ // Ordenar IDs para lockear siempre en el mismo orden
+ const [firstId, secondId] = [fromId, toId].sort();
+
+ return this.dataSource.transaction(async (manager) => {
+ const firstAccount = await manager.findOne(AccountEntity, {
+ where: { id: firstId },
+ lock: { mode: 'pessimistic_write' },
+ });
+
+ const secondAccount = await manager.findOne(AccountEntity, {
+ where: { id: secondId },
+ lock: { mode: 'pessimistic_write' },
+ });
+
+ // Ahora operar
+ const from = firstId === fromId ? firstAccount : secondAccount;
+ const to = firstId === toId ? firstAccount : secondAccount;
+
+ from.balance -= amount;
+ to.balance += amount;
+
+ await manager.save([from, to]);
+ });
+}
+```
+
+### 7.2 Connection Leak
+
+```typescript
+// β PROBLEMA: QueryRunner no liberado
+async badMethod(): Promise {
+ const queryRunner = this.dataSource.createQueryRunner();
+ await queryRunner.connect();
+ await queryRunner.startTransaction();
+
+ const data = await queryRunner.manager.find(Entity);
+ // Si hay error aqui, queryRunner nunca se libera!
+
+ await queryRunner.commitTransaction();
+ await queryRunner.release();
+}
+
+// β
SOLUCION: Siempre usar try/finally
+async goodMethod(): Promise {
+ const queryRunner = this.dataSource.createQueryRunner();
+ await queryRunner.connect();
+ await queryRunner.startTransaction();
+
+ try {
+ const data = await queryRunner.manager.find(Entity);
+ await queryRunner.commitTransaction();
+ } catch (error) {
+ await queryRunner.rollbackTransaction();
+ throw error;
+ } finally {
+ await queryRunner.release(); // SIEMPRE se ejecuta
+ }
+}
+```
+
+### 7.3 Long-Running Transactions
+
+```typescript
+// β PROBLEMA: Transaccion muy larga
+async processAllOrders(): Promise {
+ return this.dataSource.transaction(async (manager) => {
+ const orders = await manager.find(OrderEntity); // Puede ser miles
+ for (const order of orders) {
+ await this.processOrder(order); // Minutos de bloqueo
+ }
+ });
+}
+
+// β
SOLUCION: Procesar en batches con transacciones cortas
+async processAllOrders(): Promise {
+ const BATCH_SIZE = 100;
+ let processed = 0;
+
+ while (true) {
+ const orders = await this.orderRepository.find({
+ where: { status: OrderStatus.PENDING },
+ take: BATCH_SIZE,
+ });
+
+ if (orders.length === 0) break;
+
+ // Transaccion corta por batch
+ await this.dataSource.transaction(async (manager) => {
+ for (const order of orders) {
+ await this.processOrderInTransaction(manager, order);
+ }
+ });
+
+ processed += orders.length;
+ }
+}
+```
+
+---
+
+## 8. TESTING DE TRANSACCIONES
+
+```typescript
+// src/modules/order/order.service.spec.ts
+describe('OrderService', () => {
+ let service: OrderService;
+ let dataSource: DataSource;
+
+ beforeEach(async () => {
+ const module = await Test.createTestingModule({
+ imports: [TypeOrmModule.forRoot(testConfig)],
+ providers: [OrderService],
+ }).compile();
+
+ service = module.get(OrderService);
+ dataSource = module.get(DataSource);
+ });
+
+ afterEach(async () => {
+ // Limpiar despues de cada test
+ await dataSource.synchronize(true);
+ });
+
+ describe('createOrder', () => {
+ it('should rollback if stock is insufficient', async () => {
+ // Arrange
+ const product = await productRepo.save({
+ name: 'Test',
+ stock: 5,
+ price: 100,
+ });
+
+ // Act & Assert
+ await expect(
+ service.createOrder({
+ items: [{ productId: product.id, quantity: 10 }],
+ }),
+ ).rejects.toThrow('Stock insuficiente');
+
+ // Verificar que stock no cambio (rollback funciono)
+ const updatedProduct = await productRepo.findOne({
+ where: { id: product.id },
+ });
+ expect(updatedProduct.stock).toBe(5);
+ });
+
+ it('should commit successfully with valid data', async () => {
+ // ...
+ });
+ });
+});
+```
+
+---
+
+## 9. CHECKLIST DE TRANSACCIONES
+
+```
+Antes de implementar:
+[ ] ΒΏNecesito atomicidad? (multiples operaciones)
+[ ] ΒΏQue nivel de aislamiento necesito?
+[ ] ΒΏNecesito locks? ΒΏPesimista u optimista?
+
+Durante implementacion:
+[ ] QueryRunner siempre liberado (finally)
+[ ] Rollback en catch
+[ ] Manejo de errores transitorios (retry)
+[ ] Transacciones lo mas cortas posible
+[ ] Orden consistente de locks (evitar deadlocks)
+
+Testing:
+[ ] Test de rollback en error
+[ ] Test de commit exitoso
+[ ] Test de concurrencia (si aplica)
+```
+
+---
+
+**Version:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** Patron de Codigo
diff --git a/core/orchestration/patrones/PATRON-VALIDACION.md b/core/orchestration/patrones/PATRON-VALIDACION.md
new file mode 100644
index 0000000..9a5f9e8
--- /dev/null
+++ b/core/orchestration/patrones/PATRON-VALIDACION.md
@@ -0,0 +1,619 @@
+# PATRΓN: VALIDACIΓN DE DATOS
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Aplica a:** Backend (NestJS/Express), Frontend (React)
+**Prioridad:** OBLIGATORIA
+
+---
+
+## PROPΓSITO
+
+Definir patrones estΓ‘ndar de validaciΓ³n de datos para garantizar consistencia en toda la aplicaciΓ³n.
+
+---
+
+## PRINCIPIO FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β VALIDACIΓN EN CAPAS β
+β β
+β 1. Frontend: UX inmediata (opcional pero recomendada) β
+β 2. DTO: ValidaciΓ³n de entrada (OBLIGATORIA) β
+β 3. Service: ValidaciΓ³n de negocio (cuando aplica) β
+β 4. Database: Constraints (ΓΊltima lΓnea de defensa) β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 1. VALIDACIΓN EN DTO (NestJS - class-validator)
+
+### Decoradores BΓ‘sicos
+
+```typescript
+import {
+ IsString,
+ IsEmail,
+ IsNotEmpty,
+ IsOptional,
+ IsUUID,
+ IsInt,
+ IsNumber,
+ IsBoolean,
+ IsDate,
+ IsArray,
+ IsEnum,
+ IsUrl,
+ IsPhoneNumber,
+} from 'class-validator';
+```
+
+### Decoradores de Longitud
+
+```typescript
+import {
+ Length,
+ MinLength,
+ MaxLength,
+ Min,
+ Max,
+ ArrayMinSize,
+ ArrayMaxSize,
+} from 'class-validator';
+```
+
+### Decoradores de Formato
+
+```typescript
+import {
+ Matches,
+ IsAlpha,
+ IsAlphanumeric,
+ IsAscii,
+ Contains,
+ IsISO8601,
+ IsCreditCard,
+ IsHexColor,
+ IsJSON,
+} from 'class-validator';
+```
+
+---
+
+## 2. PATRONES POR TIPO DE DATO
+
+### Email
+
+```typescript
+// PATRΓN ESTΓNDAR
+@ApiProperty({
+ description: 'Correo electrΓ³nico del usuario',
+ example: 'usuario@empresa.com',
+})
+@IsEmail({}, { message: 'El correo electrΓ³nico no es vΓ‘lido' })
+@IsNotEmpty({ message: 'El correo electrΓ³nico es requerido' })
+@MaxLength(255, { message: 'El correo no puede exceder 255 caracteres' })
+@Transform(({ value }) => value?.toLowerCase().trim())
+email: string;
+```
+
+### Password
+
+```typescript
+// PATRΓN ESTΓNDAR - ContraseΓ±a segura
+@ApiProperty({
+ description: 'ContraseΓ±a (mΓn 8 caracteres, 1 mayΓΊscula, 1 nΓΊmero, 1 especial)',
+ example: 'MiPassword123!',
+})
+@IsString()
+@IsNotEmpty({ message: 'La contraseΓ±a es requerida' })
+@MinLength(8, { message: 'La contraseΓ±a debe tener al menos 8 caracteres' })
+@MaxLength(100, { message: 'La contraseΓ±a no puede exceder 100 caracteres' })
+@Matches(
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/,
+ { message: 'La contraseΓ±a debe contener mayΓΊscula, minΓΊscula, nΓΊmero y carΓ‘cter especial' }
+)
+password: string;
+```
+
+### UUID
+
+```typescript
+// PATRΓN ESTΓNDAR
+@ApiProperty({
+ description: 'ID ΓΊnico del recurso',
+ example: '550e8400-e29b-41d4-a716-446655440000',
+})
+@IsUUID('4', { message: 'El ID debe ser un UUID vΓ‘lido' })
+@IsNotEmpty({ message: 'El ID es requerido' })
+id: string;
+
+// UUID Opcional (para referencias)
+@ApiPropertyOptional({
+ description: 'ID del usuario relacionado',
+})
+@IsOptional()
+@IsUUID('4', { message: 'El ID de usuario debe ser un UUID vΓ‘lido' })
+userId?: string;
+```
+
+### Nombre/Texto Simple
+
+```typescript
+// PATRΓN ESTΓNDAR
+@ApiProperty({
+ description: 'Nombre del usuario',
+ example: 'Juan PΓ©rez',
+ minLength: 2,
+ maxLength: 100,
+})
+@IsString({ message: 'El nombre debe ser texto' })
+@IsNotEmpty({ message: 'El nombre es requerido' })
+@MinLength(2, { message: 'El nombre debe tener al menos 2 caracteres' })
+@MaxLength(100, { message: 'El nombre no puede exceder 100 caracteres' })
+@Transform(({ value }) => value?.trim())
+name: string;
+```
+
+### NΓΊmero Entero
+
+```typescript
+// PATRΓN ESTΓNDAR - Entero positivo
+@ApiProperty({
+ description: 'Cantidad de items',
+ example: 10,
+ minimum: 1,
+})
+@IsInt({ message: 'La cantidad debe ser un nΓΊmero entero' })
+@Min(1, { message: 'La cantidad mΓnima es 1' })
+@Max(10000, { message: 'La cantidad mΓ‘xima es 10,000' })
+quantity: number;
+
+// Entero con valor por defecto
+@ApiPropertyOptional({
+ description: 'PΓ‘gina actual',
+ default: 1,
+})
+@IsOptional()
+@IsInt()
+@Min(1)
+@Transform(({ value }) => parseInt(value) || 1)
+page?: number = 1;
+```
+
+### NΓΊmero Decimal (Dinero)
+
+```typescript
+// PATRΓN ESTΓNDAR - Precio/Dinero
+@ApiProperty({
+ description: 'Precio del producto',
+ example: 99.99,
+ minimum: 0,
+})
+@IsNumber(
+ { maxDecimalPlaces: 2 },
+ { message: 'El precio debe tener mΓ‘ximo 2 decimales' }
+)
+@Min(0, { message: 'El precio no puede ser negativo' })
+@Max(999999.99, { message: 'El precio mΓ‘ximo es 999,999.99' })
+price: number;
+```
+
+### Boolean
+
+```typescript
+// PATRΓN ESTΓNDAR
+@ApiProperty({
+ description: 'Estado activo del usuario',
+ example: true,
+})
+@IsBoolean({ message: 'El valor debe ser verdadero o falso' })
+@IsNotEmpty()
+isActive: boolean;
+
+// Boolean opcional con default
+@ApiPropertyOptional({
+ description: 'Enviar notificaciΓ³n',
+ default: false,
+})
+@IsOptional()
+@IsBoolean()
+@Transform(({ value }) => value === 'true' || value === true)
+sendNotification?: boolean = false;
+```
+
+### Enum
+
+```typescript
+// PATRΓN ESTΓNDAR
+export enum UserStatus {
+ ACTIVE = 'active',
+ INACTIVE = 'inactive',
+ SUSPENDED = 'suspended',
+}
+
+@ApiProperty({
+ description: 'Estado del usuario',
+ enum: UserStatus,
+ example: UserStatus.ACTIVE,
+})
+@IsEnum(UserStatus, { message: 'El estado debe ser: active, inactive o suspended' })
+@IsNotEmpty()
+status: UserStatus;
+```
+
+### Fecha
+
+```typescript
+// PATRΓN ESTΓNDAR - Fecha ISO
+@ApiProperty({
+ description: 'Fecha de nacimiento',
+ example: '1990-05-15',
+})
+@IsISO8601({}, { message: 'La fecha debe estar en formato ISO 8601' })
+@IsNotEmpty()
+birthDate: string;
+
+// Fecha como Date object
+@ApiProperty({
+ description: 'Fecha de inicio',
+ example: '2024-01-15T10:30:00Z',
+})
+@IsDate({ message: 'Debe ser una fecha vΓ‘lida' })
+@Type(() => Date)
+@IsNotEmpty()
+startDate: Date;
+```
+
+### URL
+
+```typescript
+// PATRΓN ESTΓNDAR
+@ApiPropertyOptional({
+ description: 'URL del avatar',
+ example: 'https://example.com/avatar.jpg',
+})
+@IsOptional()
+@IsUrl({}, { message: 'La URL no es vΓ‘lida' })
+@MaxLength(500)
+avatarUrl?: string;
+```
+
+### TelΓ©fono
+
+```typescript
+// PATRΓN ESTΓNDAR - MΓ©xico
+@ApiPropertyOptional({
+ description: 'NΓΊmero de telΓ©fono',
+ example: '+521234567890',
+})
+@IsOptional()
+@IsPhoneNumber('MX', { message: 'El nΓΊmero de telΓ©fono no es vΓ‘lido' })
+phone?: string;
+
+// Alternativa con Regex
+@IsOptional()
+@Matches(/^\+?[1-9]\d{1,14}$/, { message: 'Formato de telΓ©fono invΓ‘lido' })
+phone?: string;
+```
+
+### Array
+
+```typescript
+// PATRΓN ESTΓNDAR - Array de strings
+@ApiProperty({
+ description: 'Etiquetas del producto',
+ example: ['electrΓ³nica', 'ofertas'],
+ type: [String],
+})
+@IsArray({ message: 'Las etiquetas deben ser un arreglo' })
+@IsString({ each: true, message: 'Cada etiqueta debe ser texto' })
+@ArrayMinSize(1, { message: 'Debe haber al menos una etiqueta' })
+@ArrayMaxSize(10, { message: 'MΓ‘ximo 10 etiquetas permitidas' })
+tags: string[];
+
+// Array de UUIDs
+@ApiProperty({
+ description: 'IDs de categorΓas',
+ type: [String],
+})
+@IsArray()
+@IsUUID('4', { each: true, message: 'Cada ID debe ser un UUID vΓ‘lido' })
+@ArrayMinSize(1)
+categoryIds: string[];
+```
+
+### JSON/Object
+
+```typescript
+// PATRΓN ESTΓNDAR - Objeto flexible
+@ApiPropertyOptional({
+ description: 'Metadatos adicionales',
+ example: { key: 'value' },
+})
+@IsOptional()
+@IsObject({ message: 'Los metadatos deben ser un objeto' })
+metadata?: Record;
+
+// Objeto con estructura definida (usar class anidada)
+class AddressDto {
+ @IsString()
+ @IsNotEmpty()
+ street: string;
+
+ @IsString()
+ @IsNotEmpty()
+ city: string;
+
+ @IsString()
+ @Length(5, 5)
+ zipCode: string;
+}
+
+@ApiProperty({ type: AddressDto })
+@ValidateNested()
+@Type(() => AddressDto)
+address: AddressDto;
+```
+
+---
+
+## 3. DTOs ESTΓNDAR
+
+### CreateDto Pattern
+
+```typescript
+/**
+ * DTO para crear usuario
+ *
+ * @example
+ * {
+ * "email": "user@example.com",
+ * "password": "SecurePass123!",
+ * "name": "Juan PΓ©rez"
+ * }
+ */
+export class CreateUserDto {
+ @ApiProperty({ description: 'Email del usuario', example: 'user@example.com' })
+ @IsEmail()
+ @IsNotEmpty()
+ @MaxLength(255)
+ @Transform(({ value }) => value?.toLowerCase().trim())
+ email: string;
+
+ @ApiProperty({ description: 'ContraseΓ±a', example: 'SecurePass123!' })
+ @IsString()
+ @IsNotEmpty()
+ @MinLength(8)
+ @Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/)
+ password: string;
+
+ @ApiProperty({ description: 'Nombre completo', example: 'Juan PΓ©rez' })
+ @IsString()
+ @IsNotEmpty()
+ @MinLength(2)
+ @MaxLength(100)
+ @Transform(({ value }) => value?.trim())
+ name: string;
+
+ @ApiPropertyOptional({ description: 'TelΓ©fono', example: '+521234567890' })
+ @IsOptional()
+ @IsPhoneNumber('MX')
+ phone?: string;
+}
+```
+
+### UpdateDto Pattern
+
+```typescript
+import { PartialType, OmitType } from '@nestjs/swagger';
+
+/**
+ * DTO para actualizar usuario
+ *
+ * Todos los campos son opcionales.
+ * Email y password NO se pueden actualizar aquΓ.
+ */
+export class UpdateUserDto extends PartialType(
+ OmitType(CreateUserDto, ['email', 'password'] as const)
+) {}
+```
+
+### QueryDto Pattern (Filtros y PaginaciΓ³n)
+
+```typescript
+/**
+ * DTO para bΓΊsqueda y paginaciΓ³n de usuarios
+ */
+export class QueryUsersDto {
+ @ApiPropertyOptional({ description: 'PΓ‘gina', default: 1 })
+ @IsOptional()
+ @Type(() => Number)
+ @IsInt()
+ @Min(1)
+ page?: number = 1;
+
+ @ApiPropertyOptional({ description: 'Items por pΓ‘gina', default: 20 })
+ @IsOptional()
+ @Type(() => Number)
+ @IsInt()
+ @Min(1)
+ @Max(100)
+ limit?: number = 20;
+
+ @ApiPropertyOptional({ description: 'Buscar por nombre o email' })
+ @IsOptional()
+ @IsString()
+ @MaxLength(100)
+ search?: string;
+
+ @ApiPropertyOptional({ description: 'Filtrar por estado', enum: UserStatus })
+ @IsOptional()
+ @IsEnum(UserStatus)
+ status?: UserStatus;
+
+ @ApiPropertyOptional({ description: 'Ordenar por campo' })
+ @IsOptional()
+ @IsIn(['name', 'email', 'createdAt'])
+ sortBy?: string = 'createdAt';
+
+ @ApiPropertyOptional({ description: 'DirecciΓ³n de orden', enum: ['asc', 'desc'] })
+ @IsOptional()
+ @IsIn(['asc', 'desc'])
+ sortOrder?: 'asc' | 'desc' = 'desc';
+}
+```
+
+---
+
+## 4. VALIDACIΓN EN SERVICE (LΓ³gica de Negocio)
+
+```typescript
+@Injectable()
+export class UserService {
+ async create(dto: CreateUserDto): Promise {
+ // ValidaciΓ³n de negocio (despuΓ©s de DTO)
+
+ // 1. Verificar unicidad
+ const existing = await this.repository.findOne({
+ where: { email: dto.email },
+ });
+ if (existing) {
+ throw new ConflictException('El email ya estΓ‘ registrado');
+ }
+
+ // 2. Validar reglas de negocio
+ if (await this.isEmailDomainBlocked(dto.email)) {
+ throw new BadRequestException('Dominio de email no permitido');
+ }
+
+ // 3. Validar lΓmites
+ const userCount = await this.repository.count({
+ where: { tenantId: dto.tenantId },
+ });
+ if (userCount >= this.MAX_USERS_PER_TENANT) {
+ throw new ForbiddenException('LΓmite de usuarios alcanzado');
+ }
+
+ // Proceder con creaciΓ³n
+ const user = this.repository.create(dto);
+ return this.repository.save(user);
+ }
+}
+```
+
+---
+
+## 5. VALIDACIΓN EN FRONTEND (React)
+
+### Con React Hook Form + Zod
+
+```typescript
+import { z } from 'zod';
+import { useForm } from 'react-hook-form';
+import { zodResolver } from '@hookform/resolvers/zod';
+
+// Schema de validaciΓ³n (espejo del DTO backend)
+const createUserSchema = z.object({
+ email: z
+ .string()
+ .min(1, 'El email es requerido')
+ .email('Email invΓ‘lido')
+ .max(255),
+ password: z
+ .string()
+ .min(8, 'MΓnimo 8 caracteres')
+ .regex(
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/,
+ 'Debe contener mayΓΊscula, minΓΊscula, nΓΊmero y carΓ‘cter especial'
+ ),
+ name: z
+ .string()
+ .min(2, 'MΓnimo 2 caracteres')
+ .max(100, 'MΓ‘ximo 100 caracteres'),
+ phone: z
+ .string()
+ .regex(/^\+?[1-9]\d{1,14}$/, 'TelΓ©fono invΓ‘lido')
+ .optional(),
+});
+
+type CreateUserForm = z.infer;
+
+// Uso en componente
+const UserForm = () => {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors },
+ } = useForm({
+ resolver: zodResolver(createUserSchema),
+ });
+
+ const onSubmit = async (data: CreateUserForm) => {
+ // data ya estΓ‘ validado
+ await userService.create(data);
+ };
+
+ return (
+
+ );
+};
+```
+
+---
+
+## 6. MENSAJES DE ERROR ESTΓNDAR
+
+```typescript
+// Mensajes consistentes en espaΓ±ol
+const VALIDATION_MESSAGES = {
+ required: (field: string) => `${field} es requerido`,
+ minLength: (field: string, min: number) => `${field} debe tener al menos ${min} caracteres`,
+ maxLength: (field: string, max: number) => `${field} no puede exceder ${max} caracteres`,
+ email: 'El correo electrΓ³nico no es vΓ‘lido',
+ uuid: 'El ID no es vΓ‘lido',
+ enum: (values: string[]) => `El valor debe ser uno de: ${values.join(', ')}`,
+ min: (field: string, min: number) => `${field} debe ser mayor o igual a ${min}`,
+ max: (field: string, max: number) => `${field} debe ser menor o igual a ${max}`,
+ pattern: (field: string) => `${field} tiene un formato invΓ‘lido`,
+ unique: (field: string) => `${field} ya existe`,
+};
+```
+
+---
+
+## CHECKLIST DE VALIDACIΓN
+
+```
+DTO:
+[ ] Cada campo tiene @ApiProperty o @ApiPropertyOptional
+[ ] Campos requeridos tienen @IsNotEmpty
+[ ] Campos opcionales tienen @IsOptional
+[ ] Tipos validados (@IsString, @IsNumber, etc.)
+[ ] Longitudes validadas (@MinLength, @MaxLength)
+[ ] Formatos validados (@IsEmail, @IsUUID, etc.)
+[ ] Transformaciones aplicadas (@Transform)
+[ ] Mensajes de error en espaΓ±ol
+
+Service:
+[ ] ValidaciΓ³n de unicidad
+[ ] ValidaciΓ³n de existencia (referencias)
+[ ] ValidaciΓ³n de reglas de negocio
+[ ] ValidaciΓ³n de permisos
+
+Frontend:
+[ ] Schema Zod espeja DTO backend
+[ ] Mensajes de error visibles
+[ ] ValidaciΓ³n en submit
+[ ] ValidaciΓ³n en blur (opcional)
+```
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** PatrΓ³n de ValidaciΓ³n
diff --git a/core/orchestration/procesos/ORDEN-IMPLEMENTACION.md b/core/orchestration/procesos/ORDEN-IMPLEMENTACION.md
new file mode 100644
index 0000000..108e436
--- /dev/null
+++ b/core/orchestration/procesos/ORDEN-IMPLEMENTACION.md
@@ -0,0 +1,413 @@
+# ORDEN DE IMPLEMENTACIΓN
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Prioridad:** OBLIGATORIA - DDL-First
+**Sistema:** SIMCO + CAPVED
+
+---
+
+## PROPΓSITO
+
+Definir el orden correcto de implementaciΓ³n cuando una tarea toca mΓΊltiples capas.
+
+---
+
+## PRINCIPIO FUNDAMENTAL
+
+```
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β DDL-FIRST: La Base de Datos es la Fuente de Verdad β
+β β
+β ORDEN OBLIGATORIO: β
+β β
+β 1. DATABASE β Tablas existen β
+β 2. BACKEND β Entity refleja DDL β
+β 3. FRONTEND β Types reflejan DTOs β
+β β
+β β οΈ NUNCA invertir este orden β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 1. FLUJO COMPLETO DE IMPLEMENTACIΓN
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β FASE 1: BASE DE DATOS β
+β (Database-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β [ ] 1.1 Crear/modificar archivo DDL β
+β [ ] 1.2 Definir columnas con tipos correctos β
+β [ ] 1.3 Definir PK, FK, constraints β
+β [ ] 1.4 Crear Γndices necesarios β
+β [ ] 1.5 Ejecutar carga limpia (recreate-database.sh) β
+β [ ] 1.6 Verificar con \dt, \d {tabla} β
+β [ ] 1.7 Actualizar DATABASE_INVENTORY.yml β
+β [ ] 1.8 Registrar en TRAZA-TAREAS-DATABASE.md β
+β β
+β GATE: Carga limpia exitosa antes de continuar β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β FASE 2: BACKEND β
+β (Backend-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β [ ] 2.1 Crear Entity alineada con DDL (ver MAPEO-TIPOS.md) β
+β [ ] 2.2 Crear CreateDto con validaciones β
+β [ ] 2.3 Crear UpdateDto (extends PartialType) β
+β [ ] 2.4 Crear ResponseDto β
+β [ ] 2.5 Crear Service con lΓ³gica de negocio β
+β [ ] 2.6 Crear Controller con Swagger decorators β
+β [ ] 2.7 Registrar en Module β
+β [ ] 2.8 Ejecutar: npm run build β
+β [ ] 2.9 Ejecutar: npm run lint β
+β [ ] 2.10 Ejecutar: npm run test (si hay tests) β
+β [ ] 2.11 Actualizar BACKEND_INVENTORY.yml β
+β [ ] 2.12 Registrar en TRAZA-TAREAS-BACKEND.md β
+β β
+β GATE: Build y lint pasan antes de continuar β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β FASE 3: FRONTEND β
+β (Frontend-Agent) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β [ ] 3.1 Crear types/interfaces (alineados con ResponseDto) β
+β [ ] 3.2 Crear Zod schema (alineado con CreateDto) β
+β [ ] 3.3 Crear API service β
+β [ ] 3.4 Crear custom hook (useQuery/useMutation) β
+β [ ] 3.5 Crear componentes necesarios β
+β [ ] 3.6 Crear pΓ‘gina/formulario β
+β [ ] 3.7 Ejecutar: npm run build β
+β [ ] 3.8 Ejecutar: npm run lint β
+β [ ] 3.9 Ejecutar: npm run typecheck β
+β [ ] 3.10 Actualizar FRONTEND_INVENTORY.yml β
+β [ ] 3.11 Registrar en TRAZA-TAREAS-FRONTEND.md β
+β β
+β GATE: Build, lint y typecheck pasan β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β FASE 4: INTEGRACIΓN β
+β (Orquestador) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β [ ] 4.1 Verificar flujo completo funciona β
+β [ ] 4.2 Verificar Swagger documenta correctamente β
+β [ ] 4.3 Tests e2e (si existen) β
+β [ ] 4.4 Actualizar MASTER_INVENTORY.yml β
+β [ ] 4.5 Actualizar PROXIMA-ACCION.md β
+β [ ] 4.6 Propagar a niveles superiores (SIMCO-PROPAGACION.md) β
+β β
+β GATE: Todo funciona end-to-end β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## 2. POR QUΓ DDL-FIRST
+
+### Problema: Backend-First
+
+```typescript
+// Alguien crea Entity primero sin DDL...
+@Entity()
+export class ProductEntity {
+ @Column()
+ price: number; // β Asume que existe en BD
+}
+
+// Resultado:
+// - TypeORM syncronize: Crea tabla con tipos incorrectos
+// - Sin syncronize: Error en runtime "column not found"
+// - Nadie sabe quΓ© tipo deberΓa ser price (DECIMAL? NUMERIC? INTEGER?)
+```
+
+### SoluciΓ³n: DDL-First
+
+```sql
+-- 1. DDL define la verdad
+CREATE TABLE products (
+ price DECIMAL(10,2) NOT NULL -- ExplΓcito: 10 dΓgitos, 2 decimales
+);
+```
+
+```typescript
+// 2. Entity REFLEJA la verdad
+@Column({ type: 'decimal', precision: 10, scale: 2 })
+price: string; // String para precisiΓ³n decimal
+
+// 3. DTO documenta para Swagger
+@ApiProperty({ example: 99.99 })
+@IsNumber({ maxDecimalPlaces: 2 })
+price: number;
+```
+
+---
+
+## 3. DEPENDENCIAS ENTRE CAPAS
+
+### Diagrama de Dependencias
+
+```
+ ββββββββββββββββ
+ β DATABASE β
+ β (DDL) β
+ ββββββββ¬ββββββββ
+ β
+ β Entity refleja DDL
+ βΌ
+ ββββββββββββββββ
+ β BACKEND β
+ β (Entity,DTO) β
+ ββββββββ¬ββββββββ
+ β
+ β Types reflejan DTOs
+ βΌ
+ ββββββββββββββββ
+ β FRONTEND β
+ β(Types,Forms) β
+ ββββββββββββββββ
+```
+
+### Reglas de Dependencia
+
+| Si cambias... | Debes actualizar... | En ese orden |
+|---------------|---------------------|--------------|
+| DDL columna | Entity β DTO β Types | DDL β BE β FE |
+| Entity campo | DTO β Types | BE β FE |
+| DTO campo | Types | BE β FE |
+| Types | - | FE solo |
+
+---
+
+## 4. ANTI-PATRONES DE ORDEN
+
+### Anti-PatrΓ³n 1: Frontend First
+
+```
+β INCORRECTO:
+1. Frontend-Agent crea formulario
+2. Backend-Agent crea endpoint
+3. Database-Agent... ΒΏquΓ© campos necesita?
+
+RESULTADO:
+- Frontend asume campos que no existen
+- Backend inventa estructura
+- Database no sabe quΓ© crear
+- Retrabajos mΓΊltiples
+```
+
+### Anti-PatrΓ³n 2: Parallel sin CoordinaciΓ³n
+
+```
+β INCORRECTO:
+1. Database-Agent crea tabla (en paralelo)
+2. Backend-Agent crea entity (en paralelo)
+3. Frontend-Agent crea types (en paralelo)
+
+RESULTADO:
+- Cada uno asume diferente
+- Tipos no coinciden
+- Errores en integraciΓ³n
+```
+
+### Anti-PatrΓ³n 3: Saltar ValidaciΓ³n
+
+```
+β INCORRECTO:
+1. Database-Agent crea tabla (OK)
+2. Backend-Agent crea entity (sin build)
+3. Frontend-Agent crea types (sin typecheck)
+
+RESULTADO:
+- Errores no detectados hasta runtime
+- Bugs en producciΓ³n
+- Debug difΓcil
+```
+
+---
+
+## 5. TEMPLATES POR CASO
+
+### Caso A: Feature Nueva Completa
+
+```
+TAREA: Crear sistema de comentarios
+
+FASE 1: DATABASE (Database-Agent)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+Crear: schemas/core/tables/05-comments.sql
+
+CREATE TABLE core.comments (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ content TEXT NOT NULL,
+ user_id UUID NOT NULL REFERENCES auth.users(id),
+ post_id UUID NOT NULL REFERENCES core.posts(id),
+ parent_id UUID REFERENCES core.comments(id),
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE INDEX idx_comments_post ON core.comments(post_id);
+CREATE INDEX idx_comments_user ON core.comments(user_id);
+
+Validar: ./recreate-database.sh && psql -c "\d core.comments"
+
+FASE 2: BACKEND (Backend-Agent)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+Crear:
+- modules/comment/entities/comment.entity.ts
+- modules/comment/dto/create-comment.dto.ts
+- modules/comment/dto/update-comment.dto.ts
+- modules/comment/dto/comment-response.dto.ts
+- modules/comment/services/comment.service.ts
+- modules/comment/controllers/comment.controller.ts
+- modules/comment/comment.module.ts
+
+Validar: npm run build && npm run lint
+
+FASE 3: FRONTEND (Frontend-Agent)
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+Crear:
+- shared/types/comment.types.ts
+- shared/services/comment.service.ts
+- apps/web/hooks/useComments.ts
+- apps/web/components/comments/CommentCard.tsx
+- apps/web/components/comments/CommentForm.tsx
+- apps/web/components/comments/CommentList.tsx
+
+Validar: npm run build && npm run lint && npm run typecheck
+
+FASE 4: INTEGRACIΓN
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- Test flujo completo
+- Verificar Swagger
+- Actualizar inventarios
+```
+
+### Caso B: Agregar Campo a Feature Existente
+
+```
+TAREA: Agregar campo "rating" a comments
+
+FASE 1: DATABASE
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ALTER TABLE core.comments ADD COLUMN rating INTEGER CHECK (rating BETWEEN 1 AND 5);
+
+Validar: Carga limpia
+
+FASE 2: BACKEND
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- Agregar @Column en CommentEntity
+- Agregar campo en CreateCommentDto con @IsInt @Min(1) @Max(5)
+- Agregar en ResponseDto
+
+Validar: npm run build
+
+FASE 3: FRONTEND
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- Agregar rating en Comment interface
+- Agregar input en CommentForm
+- Mostrar en CommentCard
+
+Validar: npm run build && npm run typecheck
+```
+
+### Caso C: Cambio Solo en Backend (Nueva LΓ³gica)
+
+```
+TAREA: Agregar validaciΓ³n de spam en comentarios
+
+FASE 1: DATABASE
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- SIN CAMBIOS (lΓ³gica no afecta schema)
+
+FASE 2: BACKEND
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- Agregar SpamService
+- Modificar CommentService.create() para validar
+
+Validar: npm run build && npm run test
+
+FASE 3: FRONTEND
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+- SIN CAMBIOS (endpoint sigue igual)
+- Posible: Mostrar error si spam detectado
+```
+
+---
+
+## 6. CHECKLIST RΓPIDO
+
+```
+Antes de empezar implementaciΓ³n:
+[ ] ΒΏLa tabla existe en DDL? Si no β DATABASE primero
+[ ] ΒΏEntity refleja DDL actual? Si no β Actualizar Entity
+[ ] ΒΏDTOs coinciden con Entity? Si no β Actualizar DTOs
+[ ] ΒΏTypes coinciden con DTOs? Si no β Actualizar Types
+
+Durante implementaciΓ³n:
+[ ] No crear Entity sin DDL
+[ ] No crear Types sin DTOs
+[ ] No modificar DDL sin actualizar Entity
+[ ] No modificar DTO sin actualizar Types
+
+DespuΓ©s de cada capa:
+[ ] Build pasa
+[ ] Lint pasa
+[ ] Tests pasan (si existen)
+[ ] Inventario actualizado
+```
+
+---
+
+## 7. COMANDOS DE VALIDACIΓN
+
+```bash
+# FASE 1: Validar Database
+cd {DB_SCRIPTS_PATH}
+./recreate-database.sh
+psql -d {DB_NAME} -c "\dt {schema}.*"
+psql -d {DB_NAME} -c "\d {schema}.{tabla}"
+
+# FASE 2: Validar Backend
+cd {BACKEND_ROOT}
+npm run build
+npm run lint
+npm run test
+
+# FASE 3: Validar Frontend
+cd {FRONTEND_ROOT}
+npm run build
+npm run lint
+npm run typecheck
+
+# FASE 4: Validar IntegraciΓ³n
+curl http://localhost:3000/api/{endpoint}
+# Verificar respuesta correcta
+```
+
+---
+
+## 8. MATRIZ DE DELEGACIΓN
+
+| Tarea | Database-Agent | Backend-Agent | Frontend-Agent | Orquestador |
+|-------|----------------|---------------|----------------|-------------|
+| Crear tabla | β
| β | β | Coordina |
+| Modificar DDL | β
| β | β | Coordina |
+| Crear Entity | β | β
| β | Verifica |
+| Crear DTO | β | β
| β | Verifica |
+| Crear Service | β | β
| β | Verifica |
+| Crear Controller | β | β
| β | Verifica |
+| Crear Types | β | β | β
| Verifica |
+| Crear Component | β | β | β
| Verifica |
+| IntegraciΓ³n | β | β | β | β
|
+
+---
+
+**VersiΓ³n:** 1.0.0 | **Sistema:** SIMCO | **Tipo:** GuΓa de Proceso
diff --git a/core/orchestration/referencias/ALIASES.yml b/core/orchestration/referencias/ALIASES.yml
index 3d85cc1..65295a5 100644
--- a/core/orchestration/referencias/ALIASES.yml
+++ b/core/orchestration/referencias/ALIASES.yml
@@ -79,6 +79,38 @@ global:
"@CHK_API": "core/orchestration/checklists/CHECKLIST-CODE-REVIEW-API.md"
"@CHK_REFACTOR": "core/orchestration/checklists/CHECKLIST-REFACTORIZACION.md"
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ # PATRONES DE CΓDIGO (CONSULTAR ANTES DE IMPLEMENTAR)
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ "@PATRONES": "core/orchestration/patrones/"
+ "@MAPEO_TIPOS": "core/orchestration/patrones/MAPEO-TIPOS-DDL-TYPESCRIPT.md"
+ "@PATRON_VALIDACION": "core/orchestration/patrones/PATRON-VALIDACION.md"
+ "@PATRON_EXCEPTIONS": "core/orchestration/patrones/PATRON-EXCEPTION-HANDLING.md"
+ "@PATRON_TESTING": "core/orchestration/patrones/PATRON-TESTING.md"
+ "@PATRON_LOGGING": "core/orchestration/patrones/PATRON-LOGGING.md"
+ "@PATRON_CONFIG": "core/orchestration/patrones/PATRON-CONFIGURACION.md"
+ "@PATRON_SEGURIDAD": "core/orchestration/patrones/PATRON-SEGURIDAD.md"
+ "@PATRON_PERFORMANCE": "core/orchestration/patrones/PATRON-PERFORMANCE.md"
+ "@PATRON_TRANSACCIONES": "core/orchestration/patrones/PATRON-TRANSACCIONES.md"
+ "@ANTIPATRONES": "core/orchestration/patrones/ANTIPATRONES.md"
+ "@NOMENCLATURA": "core/orchestration/patrones/NOMENCLATURA-UNIFICADA.md"
+
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ # IMPACTOS DE CAMBIOS (CONSULTAR ANTES DE MODIFICAR)
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ "@IMPACTOS": "core/orchestration/impactos/"
+ "@IMPACTO_DDL": "core/orchestration/impactos/IMPACTO-CAMBIOS-DDL.md"
+ "@IMPACTO_BACKEND": "core/orchestration/impactos/IMPACTO-CAMBIOS-BACKEND.md"
+ "@IMPACTO_ENTITY": "core/orchestration/impactos/IMPACTO-CAMBIOS-ENTITY.md"
+ "@IMPACTO_API": "core/orchestration/impactos/IMPACTO-CAMBIOS-API.md"
+ "@MATRIZ_DEPENDENCIAS": "core/orchestration/impactos/MATRIZ-DEPENDENCIAS.md"
+
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ # PROCESOS DE TRABAJO
+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ "@PROCESOS": "core/orchestration/procesos/"
+ "@ORDEN_IMPLEMENTACION": "core/orchestration/procesos/ORDEN-IMPLEMENTACION.md"
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# ALIAS DE OPERACIONES (atajos directos a directivas SIMCO)
# βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
diff --git a/orchestration/ANALISIS-ALINEACION-WORKSPACE-2025-12-08.md b/orchestration/ANALISIS-ALINEACION-WORKSPACE-2025-12-08.md
new file mode 100644
index 0000000..b092de4
--- /dev/null
+++ b/orchestration/ANALISIS-ALINEACION-WORKSPACE-2025-12-08.md
@@ -0,0 +1,434 @@
+# AnΓ‘lisis de AlineaciΓ³n del Workspace
+**Fecha:** 2025-12-08
+**VersiΓ³n Sistema:** NEXUS v3.2 + SIMCO + CAPVED
+
+---
+
+## RESUMEN EJECUTIVO
+
+Este documento presenta el anΓ‘lisis exhaustivo de alineaciΓ³n entre el sistema de orquestaciΓ³n central (`core/orchestration/`) y su implementaciΓ³n en todos los proyectos del workspace.
+
+### Hallazgos Clave
+
+| Γrea | Estado | AcciΓ³n Requerida |
+|------|--------|------------------|
+| Sistema SIMCO/CAPVED | Completo (20+ directivas) | Base sΓ³lida |
+| ERP-Core | 100% docs, 0% cΓ³digo | Implementar |
+| Verticales | Parcialmente alineadas | Propagar estΓ‘ndares |
+| SaaS Layer | 0% (vacΓo) | Crear desde cero |
+| Proyectos Standalone | Variable | Homologar |
+
+---
+
+## 1. SISTEMA DE ORQUESTACIΓN (CORE)
+
+### 1.1 Componentes Implementados
+
+| Componente | UbicaciΓ³n | Archivos | Estado |
+|------------|-----------|----------|--------|
+| Directivas SIMCO | `core/orchestration/directivas/simco/` | 17 archivos | Completo |
+| Principios | `core/orchestration/directivas/principios/` | 5 archivos | Completo |
+| Perfiles Agentes | `core/orchestration/agents/perfiles/` | 12 archivos | Completo |
+| Templates | `core/orchestration/templates/` | 14 archivos | Completo |
+| Checklists | `core/orchestration/checklists/` | 3 archivos | Completo |
+| CatΓ‘logo | `core/catalog/` | 8 funcionalidades | Documentado |
+
+### 1.2 Directivas SIMCO Disponibles
+
+```
+SIMCO-TAREA.md # Ciclo CAPVED (obligatorio)
+SIMCO-CREAR.md # Crear archivos nuevos
+SIMCO-MODIFICAR.md # Modificar existentes
+SIMCO-VALIDAR.md # ValidaciΓ³n obligatoria
+SIMCO-DOCUMENTAR.md # DocumentaciΓ³n
+SIMCO-DELEGACION.md # Delegar a subagentes
+SIMCO-BUSCAR.md # ExploraciΓ³n
+SIMCO-REUTILIZAR.md # Uso del catΓ‘logo
+SIMCO-DDL.md # Base de datos
+SIMCO-BACKEND.md # NestJS/TypeORM
+SIMCO-FRONTEND.md # React/TypeScript
+SIMCO-NIVELES.md # JerarquΓa de proyectos
+SIMCO-PROPAGACION.md # PropagaciΓ³n de cambios
+SIMCO-ML.md # Machine Learning
+SIMCO-MOBILE.md # Aplicaciones mΓ³viles
+SIMCO-ALINEACION.md # AlineaciΓ³n entre capas
+SIMCO-DECISION-MATRIZ.md # Matriz de decisiones
+```
+
+### 1.3 Principios Fundamentales (5)
+
+1. **PRINCIPIO-CAPVED** - Ciclo obligatorio: ContextoβAnΓ‘lisisβPlaneaciΓ³nβValidaciΓ³nβEjecuciΓ³nβDocumentaciΓ³n
+2. **PRINCIPIO-DOC-PRIMERO** - Documentar antes de implementar
+3. **PRINCIPIO-ANTI-DUPLICACION** - Verificar catΓ‘logo/inventarios antes de crear
+4. **PRINCIPIO-VALIDACION-OBLIGATORIA** - Build+Lint+Tests deben pasar
+5. **PRINCIPIO-ECONOMIA-TOKENS** - Desglosar tareas grandes
+
+### 1.4 CatΓ‘logo de Funcionalidades Reutilizables
+
+| Funcionalidad | UbicaciΓ³n | Estado |
+|---------------|-----------|--------|
+| auth | `core/catalog/auth/` | Documentado |
+| session-management | `core/catalog/session-management/` | Documentado |
+| rate-limiting | `core/catalog/rate-limiting/` | Documentado |
+| notifications | `core/catalog/notifications/` | Documentado |
+| multi-tenancy | `core/catalog/multi-tenancy/` | Documentado |
+| feature-flags | `core/catalog/feature-flags/` | Documentado |
+| websocket | `core/catalog/websocket/` | Documentado |
+| payments | `core/catalog/payments/` | Documentado |
+
+---
+
+## 2. ANΓLISIS POR PROYECTO
+
+### 2.1 ERP-SUITE
+
+#### Estado General
+| Componente | DocumentaciΓ³n | CΓ³digo | BD | OrquestaciΓ³n |
+|------------|---------------|--------|-----|--------------|
+| ERP-Core | 100% (827 MD) | 0% | 0% | 100% |
+| ConstrucciΓ³n | 100% (449 MD) | 25% | 0% | 100% |
+| MecΓ‘nicas Diesel | 95% (75 MD) | 0% | 0% | 100% |
+| Vidrio Templado | 0% | 0% | 0% | 50% |
+| Retail | 0% | 0% | 0% | 50% |
+| ClΓnicas | 0% | 0% | 0% | 50% |
+| SaaS Layer | 10% | 0% | 0% | 0% |
+
+#### Gaps Identificados en ERP-Suite
+
+| ID | Gap | Severidad | UbicaciΓ³n |
+|----|-----|-----------|-----------|
+| GAP-ERP-001 | SaaS layer vacΓo | CRΓTICO | `apps/saas/` |
+| GAP-ERP-002 | shared-libs vacΓo | ALTO | `apps/shared-libs/` |
+| GAP-ERP-003 | Verticales sin HERENCIA-ERP-CORE.md | MEDIO | 3 de 5 verticales |
+| GAP-ERP-004 | Inventarios desactualizados | MEDIO | Varios |
+| GAP-ERP-005 | No existe POS bΓ‘sico minimalista | CRΓTICO | No existe |
+
+### 2.2 Otros Proyectos
+
+| Proyecto | Estado | Docs | CΓ³digo | AlineaciΓ³n |
+|----------|--------|------|--------|------------|
+| Gamilit | ProducciΓ³n | 470 MD | Completo | Alta |
+| Trading-Platform | Desarrollo | 259 MD | 70% | Alta |
+| Betting-Analytics | PlanificaciΓ³n | 1 MD | 0% | Parcial |
+| Inmobiliaria-Analytics | PlanificaciΓ³n | 1 MD | 0% | Parcial |
+
+---
+
+## 3. GAPS DE ALINEACIΓN CRΓTICOS
+
+### 3.1 Gaps Estructurales
+
+| # | DescripciΓ³n | Proyectos Afectados | Impacto |
+|---|-------------|---------------------|---------|
+| 1 | Falta estructura SaaS multi-tier | erp-suite | Bloqueante para comercializaciΓ³n |
+| 2 | Falta POS minimalista (100 MXN) | erp-suite | Mercado desatendido |
+| 3 | Inventarios no propagados | Todos | Trazabilidad incompleta |
+| 4 | HERENCIA-DIRECTIVAS inconsistente | Verticales | DuplicaciΓ³n de esfuerzo |
+
+### 3.2 Gaps de DocumentaciΓ³n
+
+| # | DescripciΓ³n | UbicaciΓ³n |
+|---|-------------|-----------|
+| 1 | ERP-Core sin README actualizado con arquitectura SaaS | `erp-suite/apps/erp-core/` |
+| 2 | Verticales sin docs de herencia | 3 verticales |
+| 3 | CatΓ‘logo sin cΓ³digo de referencia | `core/catalog/*/` |
+| 4 | betting/inmobiliaria sin documentaciΓ³n | 2 proyectos |
+
+### 3.3 Gaps de ImplementaciΓ³n
+
+| # | DescripciΓ³n | Prioridad |
+|---|-------------|-----------|
+| 1 | ERP-Core 0% cΓ³digo con 100% docs | P0 |
+| 2 | SaaS Layer inexistente | P0 |
+| 3 | POS BΓ‘sico no existe | P0 |
+| 4 | MecΓ‘nicas Diesel 0% cΓ³digo | P1 |
+
+---
+
+## 4. PROPUESTA: ARQUITECTURA SAAS MULTI-TIER
+
+### 4.1 Estructura Propuesta
+
+```
+erp-suite/
+βββ apps/
+β βββ erp-core/ # Base compartida (EXISTENTE)
+β β βββ backend/ # API Core
+β β βββ frontend/ # UI Core (componentes base)
+β β βββ database/ # Schemas compartidos
+β β
+β βββ saas/ # Capa SaaS (CREAR)
+β β βββ billing/ # FacturaciΓ³n y suscripciones
+β β βββ portal/ # Portal de clientes
+β β βββ admin/ # Admin multi-tenant
+β β βββ onboarding/ # Autoregistro
+β β
+β βββ products/ # Productos SaaS (CREAR)
+β β β
+β β βββ erp-basico/ # ERP SaaS Mediano (~300-500 MXN/mes)
+β β β βββ backend/ # Hereda erp-core + mΓ³dulos seleccionados
+β β β βββ frontend/ # UI simplificada
+β β β βββ config/ # Feature flags para mΓ³dulos
+β β β
+β β βββ pos-micro/ # POS Ultra BΓ‘sico (~100 MXN/mes)
+β β βββ backend/ # MΓnimo: ventas, inventario bΓ‘sico, reportes
+β β βββ frontend/ # UI ultra simple (mΓ³vil-first)
+β β βββ pwa/ # Progressive Web App
+β β βββ whatsapp/ # IntegraciΓ³n WhatsApp Business
+β β
+β βββ verticales/ # Extensiones por industria (EXISTENTE)
+β βββ construccion/
+β βββ mecanicas-diesel/
+β βββ vidrio-templado/
+β βββ retail/
+β βββ clinicas/
+```
+
+### 4.2 Producto: ERP SaaS Mediano
+
+**Target:** PyMEs que necesitan ERP integral pero econΓ³mico
+**Precio:** ~300-500 MXN/mes
+**CaracterΓsticas:**
+
+| MΓ³dulo | Incluido | DescripciΓ³n |
+|--------|----------|-------------|
+| Auth | Obligatorio | Login, roles bΓ‘sicos |
+| Usuarios | Obligatorio | GestiΓ³n de usuarios |
+| Multi-tenant | Obligatorio | Aislamiento por empresa |
+| Inventario | Incluido | Control de stock bΓ‘sico |
+| Ventas | Incluido | Cotizaciones, pedidos, facturas |
+| Compras | Incluido | Γrdenes de compra bΓ‘sicas |
+| Clientes/Proveedores | Incluido | CRM bΓ‘sico |
+| Reportes | Incluido | Reportes esenciales |
+| Contabilidad | Opcional | +100 MXN/mes |
+| RRHH | Opcional | +100 MXN/mes |
+| WhatsApp Bot | Opcional | Por consumo de tokens |
+
+### 4.3 Producto: POS Micro (Ultra BΓ‘sico)
+
+**Target:** Mercado informal mexicano
+- Puestos de calle
+- Tiendas de abarrotes/miscelΓ‘neas
+- Puestos de comida
+- PequeΓ±os locales
+
+**Precio:** ~100 MXN/mes
+**Modelo:** SaaS + consumo de IA
+
+**CaracterΓsticas MΓNIMAS:**
+
+| CaracterΓstica | DescripciΓ³n |
+|----------------|-------------|
+| Punto de Venta | Vender productos, calcular cambio |
+| Inventario BΓ‘sico | Agregar productos, ver stock |
+| CatΓ‘logo Simple | Lista de productos con precio |
+| Corte de Caja | Resumen diario de ventas |
+| Reportes BΓ‘sicos | Ventas del dΓa/semana/mes |
+| WhatsApp Bot | Consultas de precio, stock, ventas |
+| PWA Offline | Funciona sin internet (sincroniza despuΓ©s) |
+
+**Arquitectura Minimalista:**
+
+```
+pos-micro/
+βββ backend/
+β βββ src/
+β β βββ modules/
+β β β βββ auth/ # Login simple (email/WhatsApp)
+β β β βββ products/ # CRUD productos
+β β β βββ sales/ # Registrar ventas
+β β β βββ inventory/ # Stock bΓ‘sico
+β β β βββ reports/ # Reportes simples
+β β βββ shared/
+β β βββ tenant/ # Multi-tenant bΓ‘sico
+β β βββ whatsapp/ # IntegraciΓ³n WA Business
+βββ frontend/
+β βββ pwa/ # Progressive Web App
+β β βββ pages/
+β β β βββ pos/ # Pantalla de venta
+β β β βββ products/ # GestiΓ³n productos
+β β β βββ reports/ # Ver reportes
+β β β βββ settings/ # ConfiguraciΓ³n
+β β βββ offline/ # Service Worker
+βββ database/
+ βββ schemas/
+ βββ pos_micro/ # ~10 tablas mΓ‘ximo
+```
+
+**Base de Datos Minimalista (~10 tablas):**
+
+```sql
+-- Schema: pos_micro
+CREATE TABLE tenants (id, name, whatsapp_number, plan, created_at);
+CREATE TABLE users (id, tenant_id, email, password_hash, role);
+CREATE TABLE products (id, tenant_id, name, price, stock, barcode);
+CREATE TABLE sales (id, tenant_id, user_id, total, payment_method, created_at);
+CREATE TABLE sale_items (id, sale_id, product_id, quantity, price);
+CREATE TABLE inventory_movements (id, tenant_id, product_id, quantity, type, created_at);
+CREATE TABLE daily_closures (id, tenant_id, date, total_sales, total_cash);
+CREATE TABLE whatsapp_sessions (id, tenant_id, phone, token, expires_at);
+CREATE TABLE ai_usage (id, tenant_id, tokens_used, model, created_at);
+CREATE TABLE subscriptions (id, tenant_id, plan, amount, status, next_billing);
+```
+
+### 4.4 IntegraciΓ³n WhatsApp Business
+
+```
+Flujo Usuario POS Micro:
+1. Usuario envΓa "hola" a nΓΊmero de WhatsApp
+2. Bot responde: "Hola! Soy tu asistente. Puedo ayudarte con:
+ - Ver ventas del dΓa
+ - Consultar stock de producto
+ - Agregar producto
+ - Ver reporte semanal"
+3. Usuario: "ventas del dΓa"
+4. Bot: "Ventas hoy: $2,450 MXN (23 tickets)"
+5. Usuario: "stock de coca cola"
+6. Bot: "Coca Cola 600ml: 45 unidades en stock"
+
+Costo: Tokens consumidos por consulta (~0.01-0.05 USD por consulta)
+```
+
+---
+
+## 5. PLAN DE IMPLEMENTACIΓN
+
+### Fase 1: PreparaciΓ³n (Inmediato)
+
+| Tarea | DescripciΓ³n | Prioridad |
+|-------|-------------|-----------|
+| 1.1 | Actualizar HERENCIA-ERP-CORE.md en todas las verticales | P0 |
+| 1.2 | Crear estructura `apps/products/` | P0 |
+| 1.3 | Crear documentaciΓ³n base para pos-micro | P0 |
+| 1.4 | Crear documentaciΓ³n base para erp-basico | P0 |
+| 1.5 | Actualizar SaaS layer con billing bΓ‘sico | P0 |
+
+### Fase 2: POS Micro (Prioridad Alta)
+
+| Tarea | DescripciΓ³n | EstimaciΓ³n |
+|-------|-------------|------------|
+| 2.1 | DiseΓ±ar schema BD (~10 tablas) | 2h |
+| 2.2 | Implementar backend mΓnimo | 8h |
+| 2.3 | Implementar PWA frontend | 8h |
+| 2.4 | Integrar WhatsApp Business API | 4h |
+| 2.5 | Implementar offline-first | 4h |
+| 2.6 | Testing y validaciΓ³n | 4h |
+
+### Fase 3: ERP BΓ‘sico SaaS
+
+| Tarea | DescripciΓ³n | EstimaciΓ³n |
+|-------|-------------|------------|
+| 3.1 | Definir mΓ³dulos incluidos vs opcionales | 2h |
+| 3.2 | Configurar feature flags | 4h |
+| 3.3 | Implementar billing/suscripciones | 8h |
+| 3.4 | Portal de onboarding | 8h |
+| 3.5 | Testing multi-tenant | 4h |
+
+### Fase 4: PropagaciΓ³n
+
+| Tarea | DescripciΓ³n |
+|-------|-------------|
+| 4.1 | Actualizar inventarios en todos los proyectos |
+| 4.2 | Verificar HERENCIA-DIRECTIVAS en cada vertical |
+| 4.3 | Ejecutar CHECKLIST-PROPAGACION en todos los niveles |
+| 4.4 | Documentar dependencias entre productos |
+
+---
+
+## 6. MΓTRICAS DE ALINEACIΓN
+
+### 6.1 Checklist de AlineaciΓ³n por Proyecto
+
+```yaml
+Proyecto Alineado:
+ Estructura:
+ [ ] apps/backend/ existe
+ [ ] apps/frontend/ existe
+ [ ] apps/database/ existe
+ [ ] docs/ con estructura estΓ‘ndar
+ [ ] orchestration/ con estructura NEXUS
+
+ Orchestration:
+ [ ] 00-guidelines/CONTEXTO-PROYECTO.md
+ [ ] PROXIMA-ACCION.md
+ [ ] inventarios/MASTER_INVENTORY.yml
+ [ ] trazas/ con archivos por capa
+ [ ] HERENCIA-DIRECTIVAS.md
+
+ DocumentaciΓ³n:
+ [ ] README.md actualizado
+ [ ] Γpicas documentadas
+ [ ] Historias de usuario
+ [ ] Especificaciones tΓ©cnicas
+ [ ] Schemas de BD
+
+ CΓ³digo:
+ [ ] Sigue estΓ‘ndares de nomenclatura
+ [ ] Entities alineadas con DDL
+ [ ] DTOs con validaciones
+ [ ] Tests implementados
+ [ ] Build + Lint pasan
+```
+
+### 6.2 Estado Actual de AlineaciΓ³n
+
+| Proyecto | Estructura | Orchestration | Docs | CΓ³digo | TOTAL |
+|----------|------------|---------------|------|--------|-------|
+| Gamilit | 100% | 100% | 100% | 90% | **97%** |
+| Trading | 100% | 90% | 95% | 70% | **89%** |
+| ERP-Core | 100% | 100% | 100% | 0% | **75%** |
+| ConstrucciΓ³n | 100% | 100% | 100% | 25% | **81%** |
+| MecΓ‘nicas Diesel | 100% | 100% | 95% | 0% | **74%** |
+| Vidrio Templado | 80% | 50% | 0% | 0% | **33%** |
+| Retail | 80% | 50% | 0% | 0% | **33%** |
+| ClΓnicas | 80% | 50% | 0% | 0% | **33%** |
+| Betting | 80% | 40% | 5% | 0% | **31%** |
+| Inmobiliaria | 80% | 40% | 5% | 0% | **31%** |
+
+---
+
+## 7. ACCIONES INMEDIATAS
+
+### 7.1 Crear Productos SaaS
+
+```bash
+# Crear estructura de productos
+mkdir -p projects/erp-suite/apps/products/erp-basico/{backend,frontend,database,docs,orchestration}
+mkdir -p projects/erp-suite/apps/products/pos-micro/{backend,frontend,pwa,database,docs,orchestration}
+```
+
+### 7.2 Propagar HERENCIA-ERP-CORE.md
+
+Verticales que necesitan el archivo:
+- [ ] vidrio-templado
+- [ ] retail
+- [ ] clinicas
+
+### 7.3 Actualizar SaaS Layer
+
+```bash
+mkdir -p projects/erp-suite/apps/saas/{billing,portal,admin,onboarding}
+```
+
+---
+
+## 8. CONCLUSIONES
+
+1. **El sistema de orquestaciΓ³n estΓ‘ completo** - SIMCO, CAPVED, perfiles y catΓ‘logo bien definidos
+
+2. **La documentaciΓ³n es excelente** - ERP-Core tiene 827 MD, gap analysis completo vs Odoo
+
+3. **Falta implementaciΓ³n de cΓ³digo** - 0% en ERP-Core a pesar de 100% documentaciΓ³n
+
+4. **Falta capa SaaS** - CrΓtico para comercializaciΓ³n
+
+5. **Falta producto POS minimalista** - Oportunidad de mercado desatendida (100 MXN/mes)
+
+6. **Verticales parcialmente alineadas** - 3 de 5 sin HERENCIA-ERP-CORE.md
+
+7. **Proyectos standalone bien alineados** - Gamilit y Trading-Platform son ejemplos a seguir
+
+---
+
+*Documento generado: 2025-12-08*
+*Sistema: NEXUS v3.2 + SIMCO + CAPVED*
diff --git a/orchestration/WORKSPACE-STATUS.md b/orchestration/WORKSPACE-STATUS.md
index 4ea5eed..8b5c82c 100644
--- a/orchestration/WORKSPACE-STATUS.md
+++ b/orchestration/WORKSPACE-STATUS.md
@@ -1,8 +1,8 @@
# WORKSPACE STATUS
**Nivel:** 0 - Workspace Root
-**Actualizado:** 2025-12-08 (Post-Limpieza)
-**Sistema:** SIMCO v2.2.0 + CAPVED
+**Actualizado:** 2025-12-08 (AnΓ‘lisis AlineaciΓ³n + Productos SaaS)
+**Sistema:** SIMCO v3.2 + CAPVED + NEXUS
---
@@ -10,10 +10,11 @@
```yaml
estado: "OPERATIVO"
-version_simco: "2.2.0"
+version_simco: "3.2"
ultima_actualizacion: "2025-12-08"
proyectos_activos: 5
verticales_activos: 5
+productos_saas: 2 # NUEVO: pos-micro, erp-basico
catalogo_funcionalidades: 8
```
@@ -23,7 +24,25 @@ catalogo_funcionalidades: 8
### 2025-12-08
-#### CorrecciΓ³n de Gaps de DocumentaciΓ³n (NUEVO)
+#### AnΓ‘lisis de AlineaciΓ³n y Productos SaaS (NUEVO)
+- **AcciΓ³n:** AnΓ‘lisis exhaustivo del sistema de orquestaciΓ³n y alineaciΓ³n de proyectos
+- **Documento generado:** `ANALISIS-ALINEACION-WORKSPACE-2025-12-08.md`
+- **Estructuras creadas:**
+ - `apps/products/pos-micro/` - POS ultra bΓ‘sico (100 MXN/mes)
+ - `apps/products/erp-basico/` - ERP austero (300-500 MXN/mes)
+ - `apps/saas/` - Capa de billing, portal, admin, onboarding
+- **DocumentaciΓ³n:**
+ - README.md y CONTEXTO-PROYECTO.md para cada producto
+ - README.md para SaaS layer
+ - CONTEXTO-SAAS.md para orquestaciΓ³n SaaS
+- **Hallazgos:**
+ - Sistema SIMCO/CAPVED completo (20+ directivas)
+ - ERP-Core: 100% docs, 0% cΓ³digo
+ - Verticales: Todas con HERENCIA-ERP-CORE.md
+ - Productos SaaS: Nueva lΓnea para mercado mexicano
+- **Agente:** Claude Code
+
+#### CorrecciΓ³n de Gaps de DocumentaciΓ³n
- **AcciΓ³n:** CorrecciΓ³n de 7 gaps identificados en anΓ‘lisis de documentaciΓ³n
- **Archivos creados:**
- `PERFIL-REQUIREMENTS-ANALYST.md` (v1.4.0)
diff --git a/projects/erp-suite/apps/erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md b/projects/erp-suite/apps/erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md
new file mode 100644
index 0000000..4ab69f5
--- /dev/null
+++ b/projects/erp-suite/apps/erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md
@@ -0,0 +1,211 @@
+# Mapeo de Especificaciones Transversales a Verticales
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Autor:** Sistema SIMCO
+**UbicaciΓ³n SPECS:** `docs/04-modelado/especificaciones-tecnicas/transversal/`
+
+---
+
+## PropΓ³sito
+
+Este documento define quΓ© especificaciones transversales del ERP-Core aplican a cada vertical del ERP-Suite. Sirve como referencia para la propagaciΓ³n de funcionalidades y el desarrollo de cada proyecto vertical.
+
+---
+
+## Leyenda
+
+| SΓmbolo | Significado |
+|---------|-------------|
+| β | Aplica - Debe implementarse |
+| β | Opcional - Puede implementarse segΓΊn necesidad |
+| β | No aplica - No es relevante para esta vertical |
+
+---
+
+## Matriz de Aplicabilidad
+
+### SPECS P0 - Funcionales (CrΓticos)
+
+| SPEC | DescripciΓ³n | ConstrucciΓ³n | MecΓ‘nicas | Vidrio | Retail | ClΓnicas |
+|------|-------------|:------------:|:---------:|:------:|:------:|:--------:|
+| SPEC-SISTEMA-SECUENCIAS | Secuencias automΓ‘ticas de documentos | β | β | β | β | β |
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO valorizaciΓ³n | β | β | β | β | β |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL + RLS | β | β | β | β | β |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | β | β | β | β | β |
+| SPEC-PORTAL-PROVEEDORES | Portal RFQ | β | β | β | β | β |
+| SPEC-NOMINA-BASICA | hr_payroll | β | β | β | β | β |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | β | β | β | β | β |
+| SPEC-TAREAS-RECURRENTES | project.task.recurrence | β | β | β | β | β |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | β | β | β | β | β |
+| SPEC-INTEGRACION-CALENDAR | calendar integration | β | β | β | β | β |
+
+### SPECS P1 - Complementarios
+
+| SPEC | DescripciΓ³n | ConstrucciΓ³n | MecΓ‘nicas | Vidrio | Retail | ClΓnicas |
+|------|-------------|:------------:|:---------:|:------:|:------:|:--------:|
+| SPEC-CONTABILIDAD-ANALITICA-MULTIDIMENSIONAL | Centros de costo | β | β | β | β | β |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n automΓ‘tica | β | β | β | β | β |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | Firma electrΓ³nica | β | β | β | β | β |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA, TOTP, SMS | β | β | β | β | β |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes y nΓΊmeros de serie | β | β | β | β | β |
+| SPEC-PRICING-RULES | Reglas de precios | β | β | β | β | β |
+| SPEC-BLANKET-ORDERS | Γrdenes marco | β | β | β | β | β |
+| SPEC-OAUTH2-SOCIAL-LOGIN | OAuth2, Google, Microsoft | β | β | β | β | β |
+| SPEC-INVENTARIOS-CICLICOS | Conteo cΓclico | β | β | β | β | β |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR configurables | β | β | β | β | β |
+| SPEC-PLANTILLAS-CUENTAS | Plan de cuentas por paΓs | β | β | β | β | β |
+| SPEC-CONSOLIDACION-FINANCIERA | Multi-empresa | β | β | β | β | β |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos de cambio | β | β | β | β | β |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas de exceso | β | β | β | β | β |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n de presupuestos | β | β | β | β | β |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones, skills | β | β | β | β | β |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | Dependencias, burndown | β | β | β | β | β |
+| SPEC-LOCALIZACION-PAISES | ConfiguraciΓ³n por paΓs | β | β | β | β | β |
+
+### Patrones TΓ©cnicos P0
+
+| SPEC | DescripciΓ³n | ConstrucciΓ³n | MecΓ‘nicas | Vidrio | Retail | ClΓnicas |
+|------|-------------|:------------:|:---------:|:------:|:------:|:--------:|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread mixin | β | β | β | β | β |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | β | β | β | β | β |
+
+---
+
+## Resumen por Vertical
+
+### ConstrucciΓ³n (MAI/MAE)
+- **SPECS Aplicables:** 26/30
+- **SPECS Obligatorias:** 22
+- **SPECS Opcionales:** 4
+- **SPECS No Aplican:** 4
+- **Enfoque:** Proyectos, control de obra, estimaciones, RRHH construcciΓ³n
+
+### MecΓ‘nicas-Diesel (MMD)
+- **SPECS Aplicables:** 25/30
+- **SPECS Obligatorias:** 23
+- **SPECS Opcionales:** 2
+- **SPECS No Aplican:** 5
+- **Enfoque:** Γrdenes de trabajo, inventario refacciones, diagnΓ³sticos
+
+### Vidrio-Templado (VT)
+- **SPECS Aplicables:** 25/30
+- **SPECS Obligatorias:** 22
+- **SPECS Opcionales:** 3
+- **SPECS No Aplican:** 5
+- **Enfoque:** ProducciΓ³n, control de calidad, hornos de templado
+
+### Retail (RT)
+- **SPECS Aplicables:** 24/30
+- **SPECS Obligatorias:** 21
+- **SPECS Opcionales:** 3
+- **SPECS No Aplican:** 6
+- **Enfoque:** POS, inventario multi-sucursal, promociones, caja
+
+### ClΓnicas (CL)
+- **SPECS Aplicables:** 24/30
+- **SPECS Obligatorias:** 20
+- **SPECS Opcionales:** 4
+- **SPECS No Aplican:** 6
+- **Enfoque:** Expediente clΓnico, citas, calendario, cumplimiento normativo
+
+---
+
+## Detalle por Vertical
+
+### ConstrucciΓ³n
+
+**SPECS CrΓticas para el Dominio:**
+1. `SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN` - Control de obra y avances
+2. `SPEC-VALORACION-INVENTARIO` - Costeo de materiales de construcciΓ³n
+3. `SPEC-TRAZABILIDAD-LOTES-SERIES` - Trazabilidad de materiales
+4. `SPEC-PRESUPUESTOS-REVISIONES` - Control presupuestal de obras
+
+**Adaptaciones Requeridas:**
+- Proyectos = Obras/Fraccionamientos
+- Tareas = Etapas de construcciΓ³n
+- Productos = Materiales de construcciΓ³n
+
+### MecΓ‘nicas-Diesel
+
+**SPECS CrΓticas para el Dominio:**
+1. `SPEC-VALORACION-INVENTARIO` - Costeo de refacciones
+2. `SPEC-TRAZABILIDAD-LOTES-SERIES` - Tracking de partes OEM
+3. `SPEC-INVENTARIOS-CICLICOS` - Control de stock
+4. `SPEC-PRICING-RULES` - Reglas de precio por tipo de servicio
+
+**Adaptaciones Requeridas:**
+- Productos = Refacciones, partes
+- Γrdenes de venta = Γrdenes de servicio
+- Partners = Clientes con vehΓculos
+
+### Vidrio-Templado
+
+**SPECS CrΓticas para el Dominio:**
+1. `SPEC-VALORACION-INVENTARIO` - Costeo de materia prima y producto terminado
+2. `SPEC-TRAZABILIDAD-LOTES-SERIES` - Lotes de producciΓ³n de vidrio
+3. `SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN` - Γrdenes de producciΓ³n
+4. `SPEC-PRICING-RULES` - Precios por dimensiones y tipos de vidrio
+
+**Adaptaciones Requeridas:**
+- Productos = Tipos de vidrio (templado, laminado, etc.)
+- ProducciΓ³n = Control de hornos y parΓ‘metros
+- Calidad = Inspecciones de fragmentaciΓ³n
+
+### Retail
+
+**SPECS CrΓticas para el Dominio:**
+1. `SPEC-PRICING-RULES` - Promociones y descuentos
+2. `SPEC-INVENTARIOS-CICLICOS` - Conteos en sucursales
+3. `SPEC-TRAZABILIDAD-LOTES-SERIES` - Productos con lote/serie
+4. `SPEC-VALORACION-INVENTARIO` - Costeo de mercancΓa
+
+**Adaptaciones Requeridas:**
+- Almacenes = Sucursales
+- Ventas = Transacciones POS
+- Clientes = Programa de lealtad
+
+### ClΓnicas
+
+**SPECS CrΓticas para el Dominio:**
+1. `SPEC-INTEGRACION-CALENDAR` - Agenda de citas mΓ©dicas
+2. `SPEC-MAIL-THREAD-TRACKING` - Historial de comunicaciΓ³n con pacientes
+3. `SPEC-RRHH-EVALUACIONES-SKILLS` - Credenciales mΓ©dicas
+4. `SPEC-FIRMA-ELECTRONICA-NOM151` - Firma de expedientes
+
+**Adaptaciones Requeridas:**
+- Partners = Pacientes
+- Productos = Servicios mΓ©dicos, medicamentos
+- Calendario = Agenda de consultas
+- Cumplimiento = NOM-024-SSA3-2012
+
+---
+
+## Workflows Aplicables
+
+| Workflow | ConstrucciΓ³n | MecΓ‘nicas | Vidrio | Retail | ClΓnicas |
+|----------|:------------:|:---------:|:------:|:------:|:--------:|
+| WORKFLOW-CIERRE-PERIODO-CONTABLE | β | β | β | β | β |
+| WORKFLOW-3-WAY-MATCH | β | β | β | β | β |
+| WORKFLOW-PAGOS-ANTICIPADOS | β | β | β | β | β |
+
+---
+
+## PrΓ³ximos Pasos
+
+1. Crear `HERENCIA-SPECS-CORE.md` en cada vertical con detalle de implementaciΓ³n
+2. Actualizar `HERENCIA-ERP-CORE.md` con referencia a SPECS aplicables
+3. Documentar adaptaciones especΓficas por vertical en carpeta `transversal-core/`
+
+---
+
+## Referencias
+
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- AnΓ‘lisis de Gaps: `erp-core/orchestration/01-analisis/ANALISIS-GAPS-CONSOLIDADO.md`
+- Directiva de ExtensiΓ³n: `erp-core/orchestration/directivas/DIRECTIVA-EXTENSION-VERTICALES.md`
+
+---
+
+**Documento de referencia canΓ³nico para propagaciΓ³n de SPECS**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml b/projects/erp-suite/apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
index 7ced484..1c57ea6 100644
--- a/projects/erp-suite/apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
+++ b/projects/erp-suite/apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
@@ -231,24 +231,74 @@ modulos:
verticales_dependientes:
- nombre: construccion
- estado: 35%
+ codigo: MAI/MAE
+ estado: 40%
+ fase: EN_DESARROLLO
path: ../verticales/construccion/
-
- - nombre: vidrio-templado
- estado: 0%
- path: ../verticales/vidrio-templado/
+ modulos: 18
+ specs_aplicables: 26
+ specs_implementadas: 0
+ tablas_heredadas: 124
+ tablas_especificas: 33
- nombre: mecanicas-diesel
- estado: 0%
+ codigo: MMD
+ estado: 20%
+ fase: DDL_IMPLEMENTADO
path: ../verticales/mecanicas-diesel/
+ modulos: 6
+ specs_aplicables: 25
+ specs_implementadas: 0
+ tablas_heredadas: 97
+ tablas_especificas: 30
+
+ - nombre: vidrio-templado
+ codigo: VT
+ estado: 15%
+ fase: PLANIFICACION_COMPLETA
+ path: ../verticales/vidrio-templado/
+ modulos: 8
+ specs_aplicables: 25
+ specs_implementadas: 0
+ tablas_heredadas: 97
+ tablas_especificas: 25
- nombre: retail
- estado: 0%
+ codigo: RT
+ estado: 15%
+ fase: PLANIFICACION_COMPLETA
path: ../verticales/retail/
+ modulos: 10
+ specs_aplicables: 24
+ specs_implementadas: 0
+ tablas_heredadas: 102
+ tablas_especificas: 30
- nombre: clinicas
- estado: 0%
+ codigo: CL
+ estado: 15%
+ fase: PLANIFICACION_COMPLETA
path: ../verticales/clinicas/
+ modulos: 12
+ specs_aplicables: 24
+ specs_implementadas: 0
+ tablas_heredadas: 100
+ tablas_especificas: 35
+
+# ============================================================================
+# MAPEO DE SPECS A VERTICALES (Referencia)
+# ============================================================================
+mapeo_specs_verticales:
+ documento_completo: docs/04-modelado/MAPEO-SPECS-VERTICALES.md
+ fecha_actualizacion: 2025-12-08
+ resumen:
+ total_specs: 30
+ por_vertical:
+ construccion: {aplicables: 26, obligatorias: 22, opcionales: 4}
+ mecanicas_diesel: {aplicables: 25, obligatorias: 23, opcionales: 2}
+ vidrio_templado: {aplicables: 25, obligatorias: 22, opcionales: 3}
+ retail: {aplicables: 24, obligatorias: 21, opcionales: 3}
+ clinicas: {aplicables: 24, obligatorias: 20, opcionales: 4}
documentacion:
total_archivos: 630
diff --git a/projects/erp-suite/apps/products/erp-basico/README.md b/projects/erp-suite/apps/products/erp-basico/README.md
new file mode 100644
index 0000000..c235527
--- /dev/null
+++ b/projects/erp-suite/apps/products/erp-basico/README.md
@@ -0,0 +1,191 @@
+# ERP BΓ‘sico SaaS - SoluciΓ³n Integral Austera
+
+## DescripciΓ³n
+
+Sistema ERP completo pero austero, diseΓ±ado para PyMEs que necesitan funcionalidad integral sin la complejidad ni el costo de soluciones enterprise.
+
+## Target de Mercado
+
+- PyMEs con 5-50 empleados
+- Negocios que necesitan mΓ‘s que un POS
+- Empresas que buscan digitalizaciΓ³n econΓ³mica
+- Comercios con operaciones de compra-venta
+- PequeΓ±as manufacturas
+
+## Precio
+
+**~300-500 MXN/mes** (segΓΊn mΓ³dulos activos)
+
+## Plan Base (300 MXN/mes)
+
+| MΓ³dulo | Incluido | DescripciΓ³n |
+|--------|----------|-------------|
+| AutenticaciΓ³n | Obligatorio | Login, 2FA, roles bΓ‘sicos |
+| Usuarios | Obligatorio | Hasta 5 usuarios |
+| Multi-tenant | Obligatorio | Aislamiento por empresa |
+| CatΓ‘logos | Incluido | Productos, categorΓas, unidades |
+| Inventario | Incluido | Stock, movimientos, alertas |
+| Ventas | Incluido | Cotizaciones, pedidos, facturas |
+| Compras | Incluido | Γrdenes de compra, proveedores |
+| Clientes | Incluido | CRM bΓ‘sico, contactos |
+| Reportes | Incluido | Dashboard, reportes esenciales |
+
+## MΓ³dulos Opcionales
+
+| MΓ³dulo | Precio | DescripciΓ³n |
+|--------|--------|-------------|
+| Contabilidad | +150 MXN/mes | PΓ³lizas, balances, estados financieros |
+| RRHH | +100 MXN/mes | Empleados, nΓ³mina bΓ‘sica, asistencia |
+| FacturaciΓ³n CFDI | +100 MXN/mes | Timbrado SAT MΓ©xico |
+| Usuarios extra | +50 MXN/usuario | MΓ‘s de 5 usuarios |
+| WhatsApp Bot | Por consumo | Consultas y notificaciones |
+| Soporte Premium | +200 MXN/mes | AtenciΓ³n prioritaria |
+
+## Stack TecnolΓ³gico
+
+- **Backend:** Node.js + Express/NestJS + TypeScript
+- **Frontend:** React 18 + Vite + Tailwind CSS
+- **Database:** PostgreSQL 15+ con RLS
+- **Cache:** Redis (compartido)
+- **Auth:** JWT + bcrypt
+
+## Arquitectura
+
+```
+erp-basico/
+βββ backend/
+β βββ src/
+β β βββ modules/
+β β β βββ auth/ # AutenticaciΓ³n
+β β β βββ users/ # GestiΓ³n usuarios
+β β β βββ companies/ # Multi-tenant
+β β β βββ catalogs/ # CatΓ‘logos maestros
+β β β βββ inventory/ # Inventario
+β β β βββ sales/ # Ventas
+β β β βββ purchases/ # Compras
+β β β βββ partners/ # Clientes/Proveedores
+β β β βββ reports/ # Reportes
+β β βββ shared/
+β β βββ guards/
+β β βββ decorators/
+β β βββ utils/
+βββ frontend/
+β βββ src/
+β β βββ features/ # Por mΓ³dulo
+β β βββ shared/ # Componentes base
+β β βββ app/ # Layout, routing
+βββ database/
+β βββ ddl/
+β βββ 00-extensions.sql
+β βββ 01-schemas.sql
+β βββ 02-core-tables.sql
+β βββ 03-business-tables.sql
+βββ orchestration/
+```
+
+## Base de Datos (~40 tablas)
+
+### Schema: `auth`
+- users, roles, permissions, sessions, tokens
+
+### Schema: `core`
+- companies, settings, sequences, audit_logs
+
+### Schema: `catalog`
+- products, categories, units, taxes, payment_methods
+
+### Schema: `inventory`
+- warehouses, stock_moves, stock_quants, adjustments
+
+### Schema: `sales`
+- quotations, sale_orders, invoices, payments
+
+### Schema: `purchases`
+- purchase_orders, supplier_invoices, receipts
+
+### Schema: `partners`
+- partners, contacts, addresses
+
+### Schema: `reports`
+- report_configs, saved_reports
+
+## DiferenciaciΓ³n vs POS Micro
+
+| Aspecto | POS Micro | ERP BΓ‘sico |
+|---------|-----------|------------|
+| Precio | 100 MXN | 300-500 MXN |
+| Tablas BD | ~10 | ~40 |
+| MΓ³dulos | 4 | 10+ |
+| Usuarios | 1 | 5+ |
+| Compras | No | SΓ |
+| Inventario | BΓ‘sico | Completo |
+| Reportes | MΓnimos | Dashboard |
+| FacturaciΓ³n | No | Opcional |
+| Contabilidad | No | Opcional |
+
+## Herencia del Core
+
+Este producto hereda **directamente** de `erp-core`:
+
+| Componente | % Herencia | AdaptaciΓ³n |
+|------------|------------|------------|
+| Auth | 100% | Ninguna |
+| Users | 100% | Ninguna |
+| Multi-tenant | 100% | Ninguna |
+| CatΓ‘logos | 80% | Simplificado |
+| Inventario | 70% | Sin lotes/series |
+| Ventas | 70% | Sin workflows complejos |
+| Compras | 70% | Sin aprobaciones |
+| Partners | 90% | Ninguna |
+| Reportes | 50% | Subset de reportes |
+
+## Feature Flags
+
+```yaml
+# ConfiguraciΓ³n por tenant
+features:
+ accounting: false # +150 MXN
+ hr: false # +100 MXN
+ cfdi: false # +100 MXN
+ whatsapp_bot: false # Por consumo
+ advanced_reports: false
+ multi_warehouse: false
+ serial_numbers: false
+ lot_tracking: false
+```
+
+## Limitaciones (Por diseΓ±o)
+
+- MΓ‘ximo 10,000 productos
+- MΓ‘ximo 5 usuarios en plan base
+- Sin multi-sucursal en plan base
+- Sin contabilidad avanzada (solo opcional)
+- Sin manufactura
+- Sin proyectos
+- Sin e-commerce integrado
+
+## Roadmap
+
+### MVP (v1.0)
+- [x] Auth completo (heredado de core)
+- [ ] CatΓ‘logos bΓ‘sicos
+- [ ] Inventario simple
+- [ ] Ventas (cotizaciΓ³n β pedido β factura)
+- [ ] Compras bΓ‘sicas
+- [ ] Dashboard inicial
+
+### v1.1
+- [ ] MΓ³dulo contabilidad (opcional)
+- [ ] CFDI MΓ©xico (opcional)
+- [ ] Reportes adicionales
+
+### v1.2
+- [ ] RRHH bΓ‘sico (opcional)
+- [ ] Multi-almacΓ©n
+- [ ] Integraciones bancarias
+
+---
+
+*Producto: ERP BΓ‘sico SaaS v1.0*
+*Precio Target: 300-500 MXN/mes*
+*Mercado: PyMEs MΓ©xico*
diff --git a/projects/erp-suite/apps/products/erp-basico/orchestration/00-guidelines/CONTEXTO-PROYECTO.md b/projects/erp-suite/apps/products/erp-basico/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
new file mode 100644
index 0000000..1f30589
--- /dev/null
+++ b/projects/erp-suite/apps/products/erp-basico/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
@@ -0,0 +1,238 @@
+# Contexto del Proyecto: ERP BΓ‘sico SaaS
+
+## IdentificaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **Nombre** | ERP BΓ‘sico SaaS |
+| **Tipo** | Producto SaaS |
+| **Nivel** | 2B.2 (Producto dentro de Suite) |
+| **Suite Padre** | erp-suite |
+| **Ruta Base** | `projects/erp-suite/apps/products/erp-basico/` |
+| **Estado** | En PlanificaciΓ³n |
+
+## DescripciΓ³n
+
+ERP completo pero austero para PyMEs. Hereda directamente de erp-core con configuraciΓ³n simplificada y precios accesibles.
+
+## Target de Mercado
+
+- PyMEs con 5-50 empleados
+- Comercios con operaciones compra-venta
+- PequeΓ±as manufacturas
+- Distribuidores
+- Empresas en proceso de digitalizaciΓ³n
+
+## Propuesta de Valor
+
+1. **ERP completo** - No solo POS, gestiΓ³n integral
+2. **Precio accesible** - 300-500 MXN/mes vs 2,000+ de SAP/Odoo
+3. **Sin complejidad** - ConfiguraciΓ³n mΓnima
+4. **Modular** - Paga solo lo que usas
+5. **Mexicanizado** - CFDI, bancos mexicanos
+
+## Stack TecnolΓ³gico
+
+```yaml
+backend:
+ runtime: Node.js 20+
+ framework: NestJS (heredado de core)
+ language: TypeScript 5.3+
+ orm: TypeORM
+ validation: class-validator
+
+frontend:
+ framework: React 18
+ bundler: Vite
+ styling: Tailwind CSS
+ state: Zustand
+ forms: React Hook Form
+
+database:
+ engine: PostgreSQL 15+
+ multi_tenant: true (RLS)
+ schemas: 8
+ tables: ~40
+
+cache:
+ engine: Redis
+ usage: Sessions, rate-limiting
+```
+
+## Variables del Proyecto
+
+```yaml
+# Identificadores
+PROJECT_NAME: erp-basico
+PROJECT_CODE: ERPB
+SUITE: erp-suite
+
+# Database
+DB_NAME: erp_suite_db # Compartida
+SCHEMAS:
+ - auth
+ - core
+ - catalog
+ - inventory
+ - sales
+ - purchases
+ - partners
+ - reports
+
+# Paths
+BACKEND_ROOT: apps/products/erp-basico/backend
+FRONTEND_ROOT: apps/products/erp-basico/frontend
+DATABASE_ROOT: apps/products/erp-basico/database
+
+# Business
+BASE_PRICE_MXN: 300
+MAX_USERS_BASE: 5
+MAX_PRODUCTS: 10000
+```
+
+## Herencia del Core
+
+### MΓ³dulos Heredados (100%)
+
+| MΓ³dulo Core | Uso en ERP BΓ‘sico |
+|-------------|-------------------|
+| MGN-001 Auth | Completo |
+| MGN-002 Users | Completo |
+| MGN-003 Roles | Simplificado (3 roles) |
+| MGN-004 Tenants | Completo |
+| MGN-005 Catalogs | 80% (sin variantes) |
+| MGN-008 Notifications | Simplificado |
+
+### MΓ³dulos Adaptados
+
+| MΓ³dulo Core | AdaptaciΓ³n |
+|-------------|------------|
+| MGN-007 Audit | Solo logs crΓticos |
+| MGN-009 Reports | Subset de reportes |
+| Inventory | Sin lotes/series |
+| Sales | Sin workflows aprobaciΓ³n |
+| Purchases | Sin aprobaciones multi-nivel |
+
+### MΓ³dulos NO Incluidos
+
+| MΓ³dulo Core | RazΓ³n |
+|-------------|-------|
+| MGN-010 Financial | Opcional (+150 MXN) |
+| Projects | Complejidad innecesaria |
+| Manufacturing | Fuera de scope |
+| Advanced HR | Opcional (+100 MXN) |
+
+## MΓ³dulos del Producto
+
+### Obligatorios (Plan Base)
+
+| MΓ³dulo | Tablas | Endpoints | Componentes |
+|--------|--------|-----------|-------------|
+| auth | 5 | 8 | 4 |
+| users | 2 | 6 | 3 |
+| companies | 3 | 5 | 2 |
+| catalogs | 5 | 12 | 6 |
+| inventory | 4 | 10 | 5 |
+| sales | 4 | 12 | 6 |
+| purchases | 3 | 8 | 4 |
+| partners | 3 | 8 | 4 |
+| reports | 2 | 6 | 3 |
+
+### Opcionales (Feature Flags)
+
+| MΓ³dulo | Precio | Tablas Extra |
+|--------|--------|--------------|
+| accounting | +150 MXN | 8 |
+| hr | +100 MXN | 6 |
+| cfdi | +100 MXN | 3 |
+
+## Feature Flags
+
+```typescript
+interface TenantFeatures {
+ // Plan base
+ base_erp: true;
+ max_users: 5;
+ max_products: 10000;
+
+ // Opcionales
+ accounting: boolean; // +150 MXN
+ hr: boolean; // +100 MXN
+ cfdi: boolean; // +100 MXN
+ extra_users: number; // +50 MXN c/u
+ multi_warehouse: boolean; // +100 MXN
+ whatsapp_bot: boolean; // Por consumo
+ advanced_reports: boolean;// +50 MXN
+}
+```
+
+## DiferenciaciΓ³n
+
+### vs POS Micro
+
+| Aspecto | POS Micro | ERP BΓ‘sico |
+|---------|-----------|------------|
+| Complejidad | MΓnima | Media |
+| MΓ³dulos | 4 | 10+ |
+| Usuarios | 1 | 5+ |
+| Compras | No | SΓ |
+| Multi-almacΓ©n | No | Opcional |
+| Contabilidad | No | Opcional |
+| Precio | 100 MXN | 300+ MXN |
+
+### vs ERP Enterprise (Verticales)
+
+| Aspecto | ERP BΓ‘sico | Verticales |
+|---------|------------|------------|
+| Industria | General | Especializado |
+| Complejidad | Media | Alta |
+| CustomizaciΓ³n | Baja | Alta |
+| Workflows | Simples | Complejos |
+| Precio | 300-500 MXN | 1,000+ MXN |
+
+## MΓ©tricas de Γxito
+
+| MΓ©trica | Target |
+|---------|--------|
+| Tiempo de onboarding | < 30 minutos |
+| Usuarios activos diarios | > 60% |
+| NPS | > 40 |
+| Churn mensual | < 3% |
+| Tickets soporte/usuario | < 0.5/mes |
+
+## Roadmap
+
+### MVP (v1.0)
+- [ ] Herencia completa de auth/users/tenants
+- [ ] CatΓ‘logos (productos, categorΓas, unidades)
+- [ ] Inventario bΓ‘sico (stock, movimientos)
+- [ ] Ventas (cotizaciΓ³n β pedido β factura)
+- [ ] Compras bΓ‘sicas
+- [ ] Dashboard inicial
+- [ ] Billing/suscripciones
+
+### v1.1
+- [ ] MΓ³dulo contabilidad (opcional)
+- [ ] CFDI MΓ©xico (opcional)
+- [ ] Reportes financieros
+
+### v1.2
+- [ ] RRHH bΓ‘sico (opcional)
+- [ ] Multi-almacΓ©n (opcional)
+- [ ] Integraciones bancarias MΓ©xico
+
+### v2.0
+- [ ] App mΓ³vil
+- [ ] Integraciones marketplace
+- [ ] IA para predicciones
+
+## Documentos Relacionados
+
+- `../README.md` - DescripciΓ³n general
+- `../../erp-core/` - Core heredado
+- `../../erp-core/docs/` - DocumentaciΓ³n detallada de mΓ³dulos
+- `../../../orchestration/` - OrquestaciΓ³n suite level
+
+---
+
+*Γltima actualizaciΓ³n: 2025-12-08*
diff --git a/projects/erp-suite/apps/products/pos-micro/README.md b/projects/erp-suite/apps/products/pos-micro/README.md
new file mode 100644
index 0000000..8dfcf7b
--- /dev/null
+++ b/projects/erp-suite/apps/products/pos-micro/README.md
@@ -0,0 +1,139 @@
+# POS Micro - Punto de Venta Ultra BΓ‘sico
+
+## DescripciΓ³n
+
+Sistema de punto de venta minimalista diseΓ±ado para el mercado informal mexicano. Enfocado en simplicidad extrema, bajo costo y funcionalidad offline.
+
+## Target de Mercado
+
+- Puestos de calle y ambulantes
+- Tiendas de abarrotes y miscelΓ‘neas
+- Puestos de comida (tacos, tortas, etc.)
+- PequeΓ±os locales comerciales
+- Vendedores independientes
+
+## Precio
+
+**~100 MXN/mes** + consumo de IA (opcional)
+
+## CaracterΓsticas
+
+### Incluidas en Plan Base (100 MXN/mes)
+
+| CaracterΓstica | DescripciΓ³n |
+|----------------|-------------|
+| Punto de Venta | Registrar ventas, calcular cambio |
+| CatΓ‘logo | Lista de productos con precios |
+| Inventario BΓ‘sico | Control de stock simple |
+| Corte de Caja | Resumen diario |
+| Reportes | Ventas dΓa/semana/mes |
+| PWA Offline | Funciona sin internet |
+| 1 Usuario | Operador principal |
+
+### Opcionales (Por Consumo)
+
+| CaracterΓstica | Costo |
+|----------------|-------|
+| WhatsApp Bot | ~0.02 USD por consulta |
+| Usuario adicional | +30 MXN/mes |
+| Soporte prioritario | +50 MXN/mes |
+
+## Stack TecnolΓ³gico
+
+- **Backend:** Node.js + Express + TypeScript
+- **Frontend:** React + PWA + Tailwind CSS
+- **Database:** PostgreSQL (compartida multi-tenant)
+- **WhatsApp:** WhatsApp Business API
+- **IA:** Claude API (para bot)
+
+## Arquitectura
+
+```
+pos-micro/
+βββ backend/ # API mΓnima
+βββ frontend/ # SPA React
+βββ pwa/ # Service Worker + Offline
+βββ database/ # ~10 tablas
+βββ whatsapp/ # IntegraciΓ³n WA Business
+βββ docs/ # DocumentaciΓ³n
+βββ orchestration/ # Sistema NEXUS
+```
+
+## Base de Datos (~10 tablas)
+
+1. `tenants` - Empresas/negocios
+2. `users` - Usuarios del sistema
+3. `products` - CatΓ‘logo de productos
+4. `sales` - Ventas registradas
+5. `sale_items` - Detalle de ventas
+6. `inventory_movements` - Movimientos de inventario
+7. `daily_closures` - Cortes de caja
+8. `whatsapp_sessions` - Sesiones WA
+9. `ai_usage` - Consumo de tokens IA
+10. `subscriptions` - Suscripciones y pagos
+
+## Flujo de Usuario
+
+### Registro
+1. Usuario accede a landing page
+2. Ingresa nΓΊmero de WhatsApp
+3. Recibe cΓ³digo de verificaciΓ³n
+4. Configura nombre del negocio
+5. Agrega primeros productos
+6. Listo para vender
+
+### Venta TΓpica
+1. Abrir PWA (funciona offline)
+2. Seleccionar productos
+3. Ver total automΓ‘tico
+4. Registrar pago (efectivo/tarjeta)
+5. Calcular cambio
+6. Venta registrada
+
+### Consulta por WhatsApp
+```
+Usuario: "ventas de hoy"
+Bot: "Ventas hoy: $1,250 MXN (15 tickets)
+ Producto mΓ‘s vendido: Coca Cola 600ml (23 unidades)"
+
+Usuario: "stock de sabritas"
+Bot: "Sabritas Original: 12 unidades
+ Sabritas Adobadas: 8 unidades
+ Sabritas LimΓ³n: 15 unidades"
+```
+
+## Principios de DiseΓ±o
+
+1. **Simplicidad extrema** - MΓ‘ximo 3 clicks para cualquier acciΓ³n
+2. **Mobile-first** - DiseΓ±ado para celulares
+3. **Offline-first** - Funciona sin internet
+4. **Bajo costo** - Infraestructura mΓnima
+5. **Sin fricciΓ³n** - Onboarding en 5 minutos
+
+## Limitaciones (Por diseΓ±o)
+
+- MΓ‘ximo 500 productos
+- MΓ‘ximo 1,000 ventas/mes en plan base
+- Sin facturaciΓ³n electrΓ³nica (CFDI)
+- Sin contabilidad
+- Sin multi-sucursal
+- Sin CRM avanzado
+
+## Herencia del Core
+
+Este producto hereda de `erp-core`:
+- Sistema de autenticaciΓ³n bΓ‘sico
+- Multi-tenancy (RLS)
+- Estructura de proyectos
+
+NO hereda (por simplicidad):
+- MΓ³dulos financieros
+- RRHH
+- CRM completo
+- Reportes avanzados
+
+---
+
+*Producto: POS Micro v1.0*
+*Precio Target: 100 MXN/mes*
+*Mercado: Informal mexicano*
diff --git a/projects/erp-suite/apps/products/pos-micro/orchestration/00-guidelines/CONTEXTO-PROYECTO.md b/projects/erp-suite/apps/products/pos-micro/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
new file mode 100644
index 0000000..abb6715
--- /dev/null
+++ b/projects/erp-suite/apps/products/pos-micro/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
@@ -0,0 +1,164 @@
+# Contexto del Proyecto: POS Micro
+
+## IdentificaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **Nombre** | POS Micro |
+| **Tipo** | Producto SaaS |
+| **Nivel** | 2B.2 (Producto dentro de Suite) |
+| **Suite Padre** | erp-suite |
+| **Ruta Base** | `projects/erp-suite/apps/products/pos-micro/` |
+| **Estado** | En PlanificaciΓ³n |
+
+## DescripciΓ³n
+
+Sistema de punto de venta ultra-minimalista diseΓ±ado para el mercado informal mexicano. Precio target: **100 MXN/mes**.
+
+## Target de Mercado
+
+- Puestos ambulantes
+- Tiendas de abarrotes
+- MiscelΓ‘neas
+- Puestos de comida
+- PequeΓ±os comercios
+
+## Propuesta de Valor
+
+1. **Precio accesible** - 100 MXN/mes (vs 500+ de competidores)
+2. **Simplicidad** - Solo lo esencial
+3. **Offline** - Funciona sin internet
+4. **WhatsApp** - Consultas por chat
+5. **Sin fricciΓ³n** - Registro en 5 minutos
+
+## Stack TecnolΓ³gico
+
+```yaml
+backend:
+ runtime: Node.js 20+
+ framework: Express
+ language: TypeScript
+ orm: TypeORM (simplificado)
+
+frontend:
+ framework: React 18
+ bundler: Vite
+ styling: Tailwind CSS
+ pwa: Workbox
+
+database:
+ engine: PostgreSQL 15+
+ multi_tenant: true (RLS)
+ max_tables: 10
+
+integrations:
+ whatsapp: WhatsApp Business API
+ ai: Claude API (opcional)
+ payments: Stripe/Conekta
+```
+
+## Variables del Proyecto
+
+```yaml
+# Identificadores
+PROJECT_NAME: pos-micro
+PROJECT_CODE: POS
+SUITE: erp-suite
+
+# Database
+DB_SCHEMA: pos_micro
+DB_NAME: erp_suite_db # Compartida
+MAX_TABLES: 10
+
+# Paths
+BACKEND_ROOT: apps/products/pos-micro/backend
+FRONTEND_ROOT: apps/products/pos-micro/frontend
+PWA_ROOT: apps/products/pos-micro/pwa
+DATABASE_ROOT: apps/products/pos-micro/database
+
+# Business
+PRICE_MXN: 100
+PRICE_USD: 6
+MAX_PRODUCTS: 500
+MAX_SALES_MONTH: 1000
+```
+
+## Herencia del Core
+
+### SΓ Hereda
+
+| Componente | Origen | AdaptaciΓ³n |
+|------------|--------|------------|
+| Auth bΓ‘sico | erp-core/auth | Simplificado (solo email/WA) |
+| Multi-tenant | erp-core/tenant | RLS bΓ‘sico |
+| API patterns | erp-core/shared | Endpoints mΓnimos |
+
+### NO Hereda (Por DiseΓ±o)
+
+| Componente | RazΓ³n |
+|------------|-------|
+| Contabilidad | Demasiado complejo |
+| RRHH | No aplica |
+| CRM | Simplificar |
+| Compras | No necesario |
+| Reportes avanzados | Overkill |
+
+## MΓ³dulos del Producto
+
+| MΓ³dulo | Prioridad | Tablas | Endpoints |
+|--------|-----------|--------|-----------|
+| auth | P0 | 2 | 4 |
+| products | P0 | 1 | 5 |
+| sales | P0 | 2 | 4 |
+| inventory | P0 | 1 | 3 |
+| reports | P1 | 1 | 3 |
+| whatsapp | P1 | 2 | 2 |
+| billing | P1 | 1 | 2 |
+
+## Restricciones de DiseΓ±o
+
+1. **MΓ‘ximo 10 tablas** - Simplicidad de BD
+2. **MΓ‘ximo 20 endpoints** - API mΓnima
+3. **MΓ‘ximo 10 pantallas** - UI simple
+4. **Offline-first** - Service Worker obligatorio
+5. **Mobile-first** - DiseΓ±o responsivo primero mΓ³vil
+6. **3-click rule** - Cualquier acciΓ³n en mΓ‘ximo 3 clicks
+
+## MΓ©tricas de Γxito
+
+| MΓ©trica | Target |
+|---------|--------|
+| Tiempo de onboarding | < 5 minutos |
+| Tiempo carga PWA | < 2 segundos |
+| Funcionalidad offline | 100% ventas |
+| Costo infraestructura/usuario | < $1 USD/mes |
+| Churn mensual | < 5% |
+
+## Roadmap
+
+### MVP (v1.0)
+- [ ] Auth por WhatsApp
+- [ ] CRUD productos
+- [ ] Registro de ventas
+- [ ] Corte de caja
+- [ ] PWA offline
+
+### v1.1
+- [ ] WhatsApp Bot bΓ‘sico
+- [ ] Reportes por WhatsApp
+- [ ] Notificaciones stock bajo
+
+### v1.2
+- [ ] Dashboard web simple
+- [ ] Exportar datos CSV
+- [ ] Backup automΓ‘tico
+
+## Documentos Relacionados
+
+- `../README.md` - DescripciΓ³n general
+- `../../erp-core/orchestration/` - Core heredado
+- `../../../orchestration/` - Suite level
+
+---
+
+*Γltima actualizaciΓ³n: 2025-12-08*
diff --git a/projects/erp-suite/apps/saas/README.md b/projects/erp-suite/apps/saas/README.md
new file mode 100644
index 0000000..7169ff8
--- /dev/null
+++ b/projects/erp-suite/apps/saas/README.md
@@ -0,0 +1,198 @@
+# SaaS Layer - ERP Suite
+
+## DescripciΓ³n
+
+Capa de servicios SaaS que gestiona multi-tenancy, billing, suscripciones y portal de clientes para todos los productos del ERP Suite.
+
+## Componentes
+
+```
+saas/
+βββ billing/ # FacturaciΓ³n y cobros
+βββ portal/ # Portal de clientes
+βββ admin/ # AdministraciΓ³n multi-tenant
+βββ onboarding/ # Registro y configuraciΓ³n inicial
+βββ docs/ # DocumentaciΓ³n
+βββ orchestration/ # Sistema NEXUS
+```
+
+## Billing
+
+GestiΓ³n de suscripciones y cobros.
+
+### Funcionalidades
+
+- Planes de suscripciΓ³n (POS Micro, ERP BΓ‘sico, Verticales)
+- Cobro recurrente (mensual/anual)
+- IntegraciΓ³n con Stripe/Conekta
+- FacturaciΓ³n automΓ‘tica (CFDI MΓ©xico)
+- GestiΓ³n de mΓ³dulos opcionales
+
+### Planes
+
+| Plan | Precio Base | Productos |
+|------|-------------|-----------|
+| POS Micro | 100 MXN/mes | pos-micro |
+| ERP BΓ‘sico | 300 MXN/mes | erp-basico |
+| ERP Pro | 500 MXN/mes | erp-basico + mΓ³dulos |
+| Vertical | 1,000+ MXN/mes | erp-core + vertical |
+
+### MΓ³dulos Opcionales
+
+| MΓ³dulo | Precio | Disponible en |
+|--------|--------|---------------|
+| Contabilidad | +150 MXN/mes | ERP BΓ‘sico, Verticales |
+| RRHH | +100 MXN/mes | ERP BΓ‘sico, Verticales |
+| CFDI | +100 MXN/mes | Todos |
+| WhatsApp Bot | Por consumo | Todos |
+| Usuario extra | +50 MXN/mes | Todos |
+
+## Portal
+
+Portal self-service para clientes.
+
+### Funcionalidades
+
+- Dashboard de cuenta
+- GestiΓ³n de suscripciΓ³n
+- Historial de facturas
+- Cambio de plan
+- Soporte/tickets
+- ConfiguraciΓ³n de mΓ³dulos
+
+## Admin
+
+Panel de administraciΓ³n para operadores.
+
+### Funcionalidades
+
+- GestiΓ³n de tenants
+- MΓ©tricas de uso
+- FacturaciΓ³n manual
+- Soporte nivel 1
+- ConfiguraciΓ³n global
+- Feature flags por tenant
+
+## Onboarding
+
+Flujo de registro y configuraciΓ³n inicial.
+
+### Flujo
+
+1. **Registro** - Email o WhatsApp
+2. **SelecciΓ³n de plan** - POS Micro, ERP BΓ‘sico, etc.
+3. **Datos de empresa** - RFC, direcciΓ³n, giro
+4. **ConfiguraciΓ³n inicial** - Productos, usuarios
+5. **Pago** - Tarjeta o transferencia
+6. **ActivaciΓ³n** - Acceso inmediato
+
+## Stack TecnolΓ³gico
+
+```yaml
+backend:
+ runtime: Node.js 20+
+ framework: NestJS
+ language: TypeScript
+ payments: Stripe + Conekta
+ invoicing: PAC CFDI
+
+frontend:
+ framework: React 18
+ bundler: Vite
+ styling: Tailwind CSS
+
+database:
+ engine: PostgreSQL 15+
+ schema: saas
+ tables: ~15
+```
+
+## Base de Datos
+
+### Schema: `saas`
+
+```sql
+-- GestiΓ³n de tenants y suscripciones
+
+saas.tenants -- Empresas/clientes
+saas.subscriptions -- Suscripciones activas
+saas.plans -- CatΓ‘logo de planes
+saas.plan_features -- Features por plan
+saas.invoices -- Facturas emitidas
+saas.payments -- Pagos recibidos
+saas.payment_methods -- MΓ©todos de pago guardados
+saas.usage_tracking -- Tracking de consumo
+saas.support_tickets -- Tickets de soporte
+saas.onboarding_sessions -- Sesiones de registro
+```
+
+## IntegraciΓ³n con Productos
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β SAAS LAYER β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β billing β β portal β β admin β βonboardingβ β
+β ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ β
+β β β β β β
+β βββββββββββββ΄ββββββββββββ΄ββββββββββββ β
+β β β
+β API Gateway β
+β β β
+βββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
+ β
+ βββββββββββββββββΌββββββββββββββββ
+ β β β
+ βΌ βΌ βΌ
+ ββββββββββββ ββββββββββββ ββββββββββββ
+ β POS Microβ βERP BΓ‘sicoβ βVerticalesβ
+ ββββββββββββ ββββββββββββ ββββββββββββ
+```
+
+## Variables de Entorno
+
+```env
+# Payments
+STRIPE_SECRET_KEY=sk_xxx
+STRIPE_WEBHOOK_SECRET=whsec_xxx
+CONEKTA_API_KEY=key_xxx
+
+# CFDI
+PAC_RFC=XXX
+PAC_API_KEY=xxx
+PAC_ENVIRONMENT=sandbox|production
+
+# Database
+DATABASE_URL=postgresql://...
+SAAS_SCHEMA=saas
+
+# General
+ONBOARDING_URL=https://registro.erp-suite.com
+PORTAL_URL=https://portal.erp-suite.com
+```
+
+## Roadmap
+
+### MVP (v1.0)
+- [ ] Modelo de datos billing
+- [ ] IntegraciΓ³n Stripe bΓ‘sica
+- [ ] Portal mΓnimo (ver facturas)
+- [ ] Onboarding POS Micro
+- [ ] Admin bΓ‘sico
+
+### v1.1
+- [ ] IntegraciΓ³n Conekta
+- [ ] CFDI automΓ‘tico
+- [ ] Onboarding ERP BΓ‘sico
+- [ ] MΓ©tricas de uso
+
+### v1.2
+- [ ] Portal completo
+- [ ] Cambio de plan self-service
+- [ ] Soporte integrado
+- [ ] Referidos
+
+---
+
+*SaaS Layer v1.0*
+*ERP Suite*
diff --git a/projects/erp-suite/apps/saas/orchestration/CONTEXTO-SAAS.md b/projects/erp-suite/apps/saas/orchestration/CONTEXTO-SAAS.md
new file mode 100644
index 0000000..3857af0
--- /dev/null
+++ b/projects/erp-suite/apps/saas/orchestration/CONTEXTO-SAAS.md
@@ -0,0 +1,122 @@
+# Contexto del Proyecto: SaaS Layer
+
+## IdentificaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **Nombre** | SaaS Layer |
+| **Tipo** | Infraestructura |
+| **Nivel** | 2B.1 (Core de Suite) |
+| **Suite** | erp-suite |
+| **Ruta Base** | `projects/erp-suite/apps/saas/` |
+| **Estado** | En PlanificaciΓ³n |
+
+## DescripciΓ³n
+
+Capa de servicios compartidos para gestiΓ³n de multi-tenancy, billing, suscripciones y portal de clientes.
+
+## Responsabilidades
+
+1. **Billing** - Cobros, suscripciones, facturaciΓ³n
+2. **Portal** - Self-service para clientes
+3. **Admin** - GestiΓ³n de tenants
+4. **Onboarding** - Registro de nuevos clientes
+
+## Stack TecnolΓ³gico
+
+```yaml
+backend:
+ runtime: Node.js 20+
+ framework: NestJS
+ language: TypeScript 5.3+
+
+frontend:
+ framework: React 18
+ bundler: Vite
+ styling: Tailwind CSS
+
+database:
+ engine: PostgreSQL 15+
+ schema: saas
+
+integrations:
+ payments: Stripe, Conekta
+ invoicing: PAC CFDI (MΓ©xico)
+ notifications: Email, WhatsApp
+```
+
+## Variables del Proyecto
+
+```yaml
+PROJECT_NAME: saas-layer
+PROJECT_CODE: SAAS
+SUITE: erp-suite
+
+# Paths
+BILLING_ROOT: apps/saas/billing
+PORTAL_ROOT: apps/saas/portal
+ADMIN_ROOT: apps/saas/admin
+ONBOARDING_ROOT: apps/saas/onboarding
+
+# Database
+DB_SCHEMA: saas
+MAX_TABLES: 15
+```
+
+## MΓ³dulos
+
+| MΓ³dulo | DescripciΓ³n | Prioridad |
+|--------|-------------|-----------|
+| billing | Suscripciones y cobros | P0 |
+| portal | Portal de clientes | P1 |
+| admin | Panel de administraciΓ³n | P1 |
+| onboarding | Registro de clientes | P0 |
+
+## Planes de SuscripciΓ³n
+
+| ID | Plan | Precio | Target |
+|----|------|--------|--------|
+| pos-micro | POS Micro | 100 MXN/mes | Mercado informal |
+| erp-basic | ERP BΓ‘sico | 300 MXN/mes | PyMEs |
+| erp-pro | ERP Pro | 500 MXN/mes | PyMEs+ |
+| vertical-x | Vertical | 1,000+ MXN/mes | Industrias especΓficas |
+
+## Dependencias
+
+### Productos que dependen de SaaS Layer
+
+- `products/pos-micro` - Billing, onboarding
+- `products/erp-basico` - Billing, portal, onboarding
+- `verticales/*` - Billing, portal, admin
+
+### Servicios externos
+
+- Stripe - Pagos internacionales
+- Conekta - Pagos MΓ©xico
+- PAC CFDI - FacturaciΓ³n electrΓ³nica
+- SendGrid - Email transaccional
+- WhatsApp Business API - Notificaciones
+
+## Roadmap
+
+### Sprint 1: Billing MVP
+- [ ] Modelo de datos
+- [ ] IntegraciΓ³n Stripe bΓ‘sica
+- [ ] Webhook de pagos
+- [ ] API de suscripciones
+
+### Sprint 2: Onboarding
+- [ ] Flujo de registro
+- [ ] SelecciΓ³n de plan
+- [ ] ConfiguraciΓ³n inicial
+- [ ] ActivaciΓ³n automΓ‘tica
+
+### Sprint 3: Portal
+- [ ] Dashboard cliente
+- [ ] Ver facturas
+- [ ] Cambiar plan
+- [ ] Soporte bΓ‘sico
+
+---
+
+*Γltima actualizaciΓ³n: 2025-12-08*
diff --git a/projects/erp-suite/apps/verticales/clinicas/database/HERENCIA-ERP-CORE.md b/projects/erp-suite/apps/verticales/clinicas/database/HERENCIA-ERP-CORE.md
new file mode 100644
index 0000000..5030bd2
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/clinicas/database/HERENCIA-ERP-CORE.md
@@ -0,0 +1,213 @@
+# Herencia de Base de Datos - ERP Core -> ClΓnicas
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** ClΓnicas
+**Nivel:** 2B.2
+
+---
+
+## RESUMEN
+
+La vertical de ClΓnicas hereda los schemas base del ERP Core y extiende con schemas especΓficos del dominio de gestiΓ³n mΓ©dica y expediente clΓnico.
+
+**UbicaciΓ³n DDL Core:** `apps/erp-core/database/ddl/`
+
+---
+
+## ARQUITECTURA DE HERENCIA
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β ERP CORE (Base) β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β auth β β core β βfinancialβ βinventoryβ β hr β β
+β β 26 tbl β β 12 tbl β β 15 tbl β β 15 tbl β β 6 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β sales β βanalyticsβ β system β β crm β β
+β β 6 tbl β β 5 tbl β β 10 tbl β β 5 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β TOTAL: ~100 tablas heredadas β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ β HEREDA
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β CLΓNICAS (Extensiones) β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β β medical β β appointments β β patients β β
+β β (expediente) β β (citas) β β (pacientes) β β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β EXTENSIONES: ~35 tablas (planificadas) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## SCHEMAS HEREDADOS DEL CORE
+
+| Schema | Tablas | Uso en ClΓnicas |
+|--------|--------|-----------------|
+| `auth` | 26 | AutenticaciΓ³n, usuarios mΓ©dicos |
+| `core` | 12 | Partners (pacientes), catΓ‘logos |
+| `financial` | 15 | Facturas de servicios mΓ©dicos |
+| `inventory` | 15 | Medicamentos, insumos |
+| `hr` | 6 | Personal mΓ©dico |
+| `sales` | 6 | Servicios mΓ©dicos |
+| `crm` | 5 | Seguimiento de pacientes |
+| `analytics` | 5 | EstadΓsticas mΓ©dicas |
+| `system` | 10 | Recordatorios, notificaciones |
+
+**Total heredado:** ~100 tablas
+
+---
+
+## SCHEMAS ESPECΓFICOS DE CLΓNICAS (Planificados)
+
+### 1. Schema `patients` (estimado 10+ tablas)
+
+**PropΓ³sito:** GestiΓ³n de pacientes
+
+```sql
+-- Tablas principales planificadas:
+patients.patients -- Pacientes (extiende core.partners)
+patients.patient_contacts -- Contactos de emergencia
+patients.insurance_policies -- PΓ³lizas de seguro
+patients.medical_history -- Antecedentes mΓ©dicos
+patients.allergies -- Alergias
+patients.family_history -- Antecedentes familiares
+```
+
+### 2. Schema `medical` (estimado 15+ tablas)
+
+**PropΓ³sito:** Expediente clΓnico electrΓ³nico
+
+```sql
+-- Tablas principales planificadas:
+medical.consultations -- Consultas mΓ©dicas
+medical.diagnoses -- DiagnΓ³sticos (CIE-10)
+medical.prescriptions -- Recetas mΓ©dicas
+medical.prescription_lines -- Medicamentos recetados
+medical.vital_signs -- Signos vitales
+medical.lab_results -- Resultados de laboratorio
+medical.imaging_studies -- Estudios de imagen
+medical.clinical_notes -- Notas clΓnicas
+medical.treatments -- Tratamientos
+```
+
+### 3. Schema `appointments` (estimado 10+ tablas)
+
+**PropΓ³sito:** GestiΓ³n de citas
+
+```sql
+-- Tablas principales planificadas:
+appointments.doctors -- MΓ©dicos
+appointments.specialties -- Especialidades
+appointments.doctor_schedules -- Horarios de mΓ©dicos
+appointments.consulting_rooms -- Consultorios
+appointments.appointments -- Citas
+appointments.appointment_types -- Tipos de cita
+appointments.reminders -- Recordatorios
+```
+
+---
+
+## SPECS DEL CORE APLICABLES
+
+**Documento detallado:** `orchestration/00-guidelines/HERENCIA-SPECS-CORE.md`
+
+### SPECS Obligatorias
+
+| Spec Core | AplicaciΓ³n en ClΓnicas | SP | Estado |
+|-----------|----------------------|----:|--------|
+| SPEC-SISTEMA-SECUENCIAS | Foliado de expedientes y citas | 8 | PENDIENTE |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | Control de acceso a expedientes | 31 | PENDIENTE |
+| SPEC-INTEGRACION-CALENDAR | Agenda de citas mΓ©dicas | 8 | PENDIENTE |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Credenciales mΓ©dicas | 26 | PENDIENTE |
+| SPEC-MAIL-THREAD-TRACKING | Historial de comunicaciΓ³n | 13 | PENDIENTE |
+| SPEC-WIZARD-TRANSIENT-MODEL | Wizards de receta y referencia | 8 | PENDIENTE |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | Firma de expedientes clΓnicos | 13 | PENDIENTE |
+| SPEC-TWO-FACTOR-AUTHENTICATION | Seguridad de acceso | 13 | PENDIENTE |
+| SPEC-OAUTH2-SOCIAL-LOGIN | Portal de pacientes | 8 | PENDIENTE |
+
+### SPECS Opcionales
+
+| Spec Core | DecisiΓ³n | RazΓ³n |
+|-----------|----------|-------|
+| SPEC-VALORACION-INVENTARIO | EVALUAR | Solo si hay farmacia interna |
+| SPEC-PRICING-RULES | EVALUAR | Para paquetes de servicios |
+| SPEC-TAREAS-RECURRENTES | EVALUAR | Para citas periΓ³dicas |
+
+### SPECS No Aplican
+
+| Spec Core | RazΓ³n |
+|-----------|-------|
+| SPEC-PORTAL-PROVEEDORES | No hay compras complejas |
+| SPEC-BLANKET-ORDERS | No aplica en servicios mΓ©dicos |
+| SPEC-INVENTARIOS-CICLICOS | Solo si hay farmacia grande |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | No hay proyectos de este tipo |
+
+### Cumplimiento Normativo
+
+| Norma | DescripciΓ³n | SPECS Relacionadas |
+|-------|-------------|-------------------|
+| NOM-024-SSA3-2012 | Expediente clΓnico electrΓ³nico | SPEC-SEGURIDAD, SPEC-MAIL-THREAD |
+| LFPDPPP | ProtecciΓ³n de datos personales | SPEC-SEGURIDAD, SPEC-2FA |
+| NOM-004-SSA3-2012 | Expediente clΓnico | SPEC-FIRMA-ELECTRONICA |
+
+---
+
+## CUMPLIMIENTO NORMATIVO
+
+Este sistema debe cumplir con:
+
+| Norma | DescripciΓ³n | Impacto |
+|-------|-------------|---------|
+| NOM-024-SSA3-2012 | Expediente clΓnico electrΓ³nico | Estructura de datos |
+| LFPDPPP | ProtecciΓ³n de datos personales | Seguridad y acceso |
+| NOM-004-SSA3-2012 | Expediente clΓnico | Contenido mΓnimo |
+
+---
+
+## ORDEN DE EJECUCIΓN DDL (Futuro)
+
+```bash
+# PASO 1: Cargar ERP Core (base)
+cd apps/erp-core/database
+./scripts/reset-database.sh --force
+
+# PASO 2: Cargar extensiones de ClΓnicas
+cd apps/verticales/clinicas/database
+psql $DATABASE_URL -f init/00-extensions.sql
+psql $DATABASE_URL -f init/01-create-schemas.sql
+psql $DATABASE_URL -f init/02-patients-tables.sql
+psql $DATABASE_URL -f init/03-medical-tables.sql
+psql $DATABASE_URL -f init/04-appointments-tables.sql
+```
+
+---
+
+## MAPEO DE NOMENCLATURA
+
+| Core | ClΓnicas |
+|------|----------|
+| `core.partners` | Pacientes base |
+| `hr.employees` | Personal mΓ©dico |
+| `inventory.products` | Medicamentos, insumos |
+| `sales.sale_orders` | Servicios mΓ©dicos |
+| `financial.invoices` | Facturas de consultas |
+
+---
+
+## REFERENCIAS
+
+- ERP Core DDL: `apps/erp-core/database/ddl/`
+- ERP Core README: `apps/erp-core/database/README.md`
+- Directivas: `orchestration/directivas/`
+- Inventarios: `orchestration/inventarios/`
+
+---
+
+**Documento de herencia oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/clinicas/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md b/projects/erp-suite/apps/verticales/clinicas/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
new file mode 100644
index 0000000..f3bc55d
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/clinicas/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
@@ -0,0 +1,199 @@
+# Herencia de SPECS del Core - ClΓnicas
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** ClΓnicas (CL)
+**Nivel:** 2B.2
+
+---
+
+## Resumen
+
+| MΓ©trica | Valor |
+|---------|-------|
+| SPECS Aplicables | 24/30 |
+| SPECS Obligatorias | 20 |
+| SPECS Opcionales | 4 |
+| SPECS No Aplican | 6 |
+| Estado ImplementaciΓ³n | 0% |
+
+---
+
+## SPECS Obligatorias (Deben Implementarse)
+
+### P0 - CrΓticas
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-SISTEMA-SECUENCIAS | ir.sequence | 8 | PENDIENTE | CL-001, CL-002, CL-005 |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL | 31 | PENDIENTE | CL-001, CL-011 |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | 13 | PENDIENTE | CL-008, CL-009 |
+| SPEC-NOMINA-BASICA | hr_payroll | 21 | PENDIENTE | CL-001 |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | 13 | PENDIENTE | CL-001 |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | 8 | PENDIENTE | CL-009 |
+| SPEC-INTEGRACION-CALENDAR | calendar integration | 8 | PENDIENTE | CL-003 |
+
+### P1 - Complementarias
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-CONTABILIDAD-ANALITICA | Centros de costo | 21 | PENDIENTE | CL-008, CL-009 |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n | 21 | PENDIENTE | CL-008 |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | e.firma | 13 | PENDIENTE | CL-011 |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA | 13 | PENDIENTE | CL-001 |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes/Series | 13 | PENDIENTE | CL-007 |
+| SPEC-OAUTH2-SOCIAL-LOGIN | OAuth2 | 8 | PENDIENTE | CL-002, CL-010 |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR | 8 | PENDIENTE | CL-008 |
+| SPEC-PLANTILLAS-CUENTAS | Plan contable | 8 | PENDIENTE | CL-008 |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos cambio | 5 | PENDIENTE | CL-008 |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas | 8 | PENDIENTE | CL-008 |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones | 26 | PENDIENTE | CL-001 |
+| SPEC-LOCALIZACION-PAISES | LocalizaciΓ³n | 13 | PENDIENTE | CL-001, CL-008 |
+
+### Patrones TΓ©cnicos
+
+| SPEC | PatrΓ³n | SP | Estado | AplicaciΓ³n |
+|------|--------|----:|--------|------------|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread | 13 | PENDIENTE | Expedientes, Citas, ComunicaciΓ³n |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | 8 | PENDIENTE | Wizards de receta, referencia |
+
+---
+
+## SPECS Opcionales
+
+| SPEC | DescripciΓ³n | SP | DecisiΓ³n | RazΓ³n |
+|------|-------------|----:|----------|-------|
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO | 21 | EVALUAR | Solo para farmacia interna |
+| SPEC-PRICING-RULES | Reglas precio | 8 | EVALUAR | Para paquetes de servicios |
+| SPEC-TAREAS-RECURRENTES | Recurrencia | 13 | EVALUAR | Para citas periΓ³dicas |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n | 8 | EVALUAR | Para tratamientos largos |
+
+---
+
+## SPECS No Aplicables
+
+| SPEC | RazΓ³n |
+|------|-------|
+| SPEC-PORTAL-PROVEEDORES | No hay compras complejas |
+| SPEC-BLANKET-ORDERS | No aplica en servicios mΓ©dicos |
+| SPEC-INVENTARIOS-CICLICOS | Solo si hay farmacia grande |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | No hay proyectos de este tipo |
+| SPEC-CONSOLIDACION-FINANCIERA | Generalmente una clΓnica |
+
+---
+
+## Adaptaciones Requeridas
+
+### Mapeo de Conceptos Core β ClΓnicas
+
+| Concepto Core | Concepto ClΓnicas |
+|---------------|-------------------|
+| `core.partners` | Pacientes |
+| `sales.sale_orders` | Consultas/Servicios |
+| `inventory.products` | Medicamentos, servicios mΓ©dicos |
+| `hr.employees` | Personal mΓ©dico |
+| `calendar.events` | Citas mΓ©dicas |
+| `financial.invoices` | Facturas de consulta |
+
+### Extensiones de Entidad
+
+```sql
+-- Pacientes (extiende partners)
+patients.patients (
+ partner_id β core.partners,
+ numero_expediente VARCHAR UNIQUE,
+ fecha_nacimiento DATE,
+ sexo ENUM('M', 'F'),
+ tipo_sangre VARCHAR(5),
+ alergias TEXT[],
+ antecedentes JSONB,
+ seguro_medico_id β insurance_policies
+)
+
+-- Expediente clΓnico
+medical.clinical_records (
+ id UUID,
+ patient_id β patients,
+ fecha TIMESTAMPTZ,
+ tipo ENUM('consulta', 'urgencia', 'hospitalizacion'),
+ motivo_consulta TEXT,
+ diagnostico TEXT,
+ tratamiento TEXT,
+ medico_id β hr.employees,
+ signos_vitales JSONB
+)
+
+-- Citas mΓ©dicas
+appointments.appointments (
+ id UUID,
+ patient_id β patients,
+ doctor_id β hr.employees,
+ specialty_id β specialties,
+ fecha_hora TIMESTAMPTZ,
+ duracion_minutos INTEGER,
+ estado ENUM('programada', 'confirmada', 'en_progreso', 'completada', 'cancelada'),
+ notas TEXT
+)
+
+-- Recetas mΓ©dicas
+medical.prescriptions (
+ id UUID,
+ clinical_record_id β clinical_records,
+ fecha TIMESTAMPTZ,
+ vigencia_dias INTEGER,
+ firma_electronica BYTEA,
+ productos JSONB
+)
+```
+
+---
+
+## Cumplimiento Normativo
+
+Esta vertical debe cumplir con normas especΓficas:
+
+| Norma | DescripciΓ³n | SPECS Relacionadas |
+|-------|-------------|-------------------|
+| NOM-024-SSA3-2012 | Expediente clΓnico electrΓ³nico | SPEC-SEGURIDAD, SPEC-MAIL-THREAD |
+| LFPDPPP | ProtecciΓ³n de datos personales | SPEC-SEGURIDAD, SPEC-2FA |
+| NOM-004-SSA3-2012 | Expediente clΓnico | SPEC-FIRMA-ELECTRONICA |
+
+---
+
+## Plan de ImplementaciΓ³n
+
+### Fase 1: Fundamentos (SP: 60)
+1. SPEC-SISTEMA-SECUENCIAS
+2. SPEC-SEGURIDAD-API-KEYS-PERMISOS
+3. SPEC-TWO-FACTOR-AUTHENTICATION
+4. SPEC-OAUTH2-SOCIAL-LOGIN
+
+### Fase 2: Agenda y ComunicaciΓ³n (SP: 34)
+5. SPEC-INTEGRACION-CALENDAR
+6. SPEC-MAIL-THREAD-TRACKING
+7. SPEC-WIZARD-TRANSIENT-MODEL
+
+### Fase 3: Expediente y Cumplimiento (SP: 39)
+8. SPEC-FIRMA-ELECTRONICA-NOM151
+9. SPEC-RRHH-EVALUACIONES-SKILLS
+
+### Fase 4: Financiero (SP: 65)
+10. SPEC-REPORTES-FINANCIEROS
+11. SPEC-CONTABILIDAD-ANALITICA
+12. SPEC-CONCILIACION-BANCARIA
+13. SPEC-IMPUESTOS-AVANZADOS
+
+---
+
+## Referencias
+
+- Documento Core: `erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md`
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- Directivas: `orchestration/directivas/`
+- Normatividad: NOM-024-SSA3-2012, LFPDPPP, NOM-004-SSA3-2012
+
+---
+
+**Documento de herencia de SPECS oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/clinicas/orchestration/inventarios/README.md b/projects/erp-suite/apps/verticales/clinicas/orchestration/inventarios/README.md
new file mode 100644
index 0000000..8020d92
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/clinicas/orchestration/inventarios/README.md
@@ -0,0 +1,103 @@
+# Inventarios - ERP ClΓnicas
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Nivel SIMCO:** 2B.2
+
+---
+
+## DescripciΓ³n
+
+Este directorio contiene los inventarios YAML que sirven como **Single Source of Truth (SSOT)** para el proyecto ERP ClΓnicas. Estos archivos son la referencia canΓ³nica para mΓ©tricas, trazabilidad y componentes del sistema.
+
+---
+
+## Archivos de Inventario
+
+| Archivo | DescripciΓ³n | Estado |
+|---------|-------------|--------|
+| [MASTER_INVENTORY.yml](./MASTER_INVENTORY.yml) | Inventario maestro con mΓ©tricas globales | Completo |
+| [DATABASE_INVENTORY.yml](./DATABASE_INVENTORY.yml) | Inventario de objetos de base de datos | Planificado |
+| [BACKEND_INVENTORY.yml](./BACKEND_INVENTORY.yml) | Inventario de componentes backend | Planificado |
+| [FRONTEND_INVENTORY.yml](./FRONTEND_INVENTORY.yml) | Inventario de componentes frontend | Planificado |
+| [TRACEABILITY_MATRIX.yml](./TRACEABILITY_MATRIX.yml) | Matriz de trazabilidad RF->ET->US | Completo |
+| [DEPENDENCY_GRAPH.yml](./DEPENDENCY_GRAPH.yml) | Grafo de dependencias entre mΓ³dulos | Completo |
+
+---
+
+## Herencia del Core
+
+Este proyecto hereda del **ERP Core** (nivel 2B.1):
+
+| Aspecto | Heredado | EspecΓfico |
+|---------|----------|------------|
+| **Tablas DB** | ~100 | Planificado |
+| **Schemas** | 8+ | Planificado |
+| **Specs** | 3 | - |
+
+### Specs Heredadas
+
+1. SPEC-RRHH-EVALUACIONES-SKILLS.md
+2. SPEC-INTEGRACION-CALENDAR.md
+3. SPEC-MAIL-THREAD-TRACKING.md
+
+---
+
+## Resumen Ejecutivo
+
+### MΓ©tricas del Proyecto
+
+| MΓ©trica | Valor |
+|---------|-------|
+| **MΓ³dulos** | 5 (CL-001 a CL-005) |
+| **Estado** | PLANIFICACION_COMPLETA |
+| **Completitud** | 15% |
+
+### Dominio del Negocio
+
+- Expediente clΓnico electrΓ³nico
+- GestiΓ³n de citas mΓ©dicas
+- Control de consultorios
+- FacturaciΓ³n de servicios mΓ©dicos
+
+---
+
+## Directivas EspecΓficas
+
+1. [DIRECTIVA-EXPEDIENTE-CLINICO.md](../directivas/DIRECTIVA-EXPEDIENTE-CLINICO.md)
+2. [DIRECTIVA-GESTION-CITAS.md](../directivas/DIRECTIVA-GESTION-CITAS.md)
+
+---
+
+## ConfiguraciΓ³n de Puertos (Planificado)
+
+| Servicio | Puerto |
+|----------|--------|
+| Backend API | 3500 |
+| Frontend Web | 5179 |
+| Patient Portal | 5180 |
+
+---
+
+## Cumplimiento Normativo
+
+Este proyecto debe cumplir con:
+- NOM-024-SSA3-2012 (Expediente clΓnico electrΓ³nico)
+- Ley de ProtecciΓ³n de Datos Personales en PosesiΓ³n de Particulares
+
+---
+
+## AlineaciΓ³n con ERP Core
+
+Estos inventarios siguen la misma estructura que:
+- `/erp-core/orchestration/inventarios/` (proyecto padre)
+
+### Referencias
+
+- Suite Master: `orchestration/inventarios/SUITE_MASTER_INVENTORY.yml`
+- Core: `apps/erp-core/orchestration/inventarios/`
+- Status Global: `orchestration/inventarios/STATUS.yml`
+
+---
+
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/fraccionamiento.controller.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/fraccionamiento.controller.ts
new file mode 100644
index 0000000..fd05a6c
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/fraccionamiento.controller.ts
@@ -0,0 +1,157 @@
+/**
+ * Fraccionamiento Controller
+ * API endpoints para gestiΓ³n de fraccionamientos/obras
+ *
+ * @module Construction
+ * @prefix /api/v1/fraccionamientos
+ */
+
+import { Router, Request, Response, NextFunction } from 'express';
+import {
+ FraccionamientoService,
+ CreateFraccionamientoDto,
+ UpdateFraccionamientoDto
+} from '../services/fraccionamiento.service';
+
+const router = Router();
+const fraccionamientoService = new FraccionamientoService();
+
+/**
+ * GET /api/v1/fraccionamientos
+ * Lista todos los fraccionamientos del tenant
+ */
+router.get('/', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const { proyectoId, estado } = req.query;
+
+ const fraccionamientos = await fraccionamientoService.findAll({
+ tenantId,
+ proyectoId: proyectoId as string,
+ estado: estado as any,
+ });
+
+ return res.json({
+ success: true,
+ data: fraccionamientos,
+ count: fraccionamientos.length,
+ });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * GET /api/v1/fraccionamientos/:id
+ * Obtiene un fraccionamiento por ID
+ */
+router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const fraccionamiento = await fraccionamientoService.findById(req.params.id, tenantId);
+ if (!fraccionamiento) {
+ return res.status(404).json({ error: 'Fraccionamiento no encontrado' });
+ }
+
+ return res.json({ success: true, data: fraccionamiento });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * POST /api/v1/fraccionamientos
+ * Crea un nuevo fraccionamiento
+ */
+router.post('/', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const data: CreateFraccionamientoDto = {
+ ...req.body,
+ tenantId,
+ createdById: (req as any).user?.id,
+ };
+
+ // Validate required fields
+ if (!data.codigo || !data.nombre || !data.proyectoId) {
+ return res.status(400).json({
+ error: 'codigo, nombre y proyectoId son requeridos'
+ });
+ }
+
+ // Check if codigo already exists
+ const existing = await fraccionamientoService.findByCodigo(data.codigo, tenantId);
+ if (existing) {
+ return res.status(409).json({ error: 'Ya existe un fraccionamiento con ese cΓ³digo' });
+ }
+
+ const fraccionamiento = await fraccionamientoService.create(data);
+ return res.status(201).json({ success: true, data: fraccionamiento });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * PATCH /api/v1/fraccionamientos/:id
+ * Actualiza un fraccionamiento
+ */
+router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const data: UpdateFraccionamientoDto = req.body;
+ const fraccionamiento = await fraccionamientoService.update(
+ req.params.id,
+ tenantId,
+ data
+ );
+
+ if (!fraccionamiento) {
+ return res.status(404).json({ error: 'Fraccionamiento no encontrado' });
+ }
+
+ return res.json({ success: true, data: fraccionamiento });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * DELETE /api/v1/fraccionamientos/:id
+ * Elimina un fraccionamiento
+ */
+router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const deleted = await fraccionamientoService.delete(req.params.id, tenantId);
+ if (!deleted) {
+ return res.status(404).json({ error: 'Fraccionamiento no encontrado' });
+ }
+
+ return res.json({ success: true, message: 'Fraccionamiento eliminado' });
+ } catch (error) {
+ next(error);
+ }
+});
+
+export default router;
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/index.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/index.ts
new file mode 100644
index 0000000..543d60c
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/index.ts
@@ -0,0 +1,7 @@
+/**
+ * Construction Controllers Index
+ * @module Construction
+ */
+
+export { default as proyectoController } from './proyecto.controller';
+export { default as fraccionamientoController } from './fraccionamiento.controller';
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/proyecto.controller.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/proyecto.controller.ts
new file mode 100644
index 0000000..2a3eb11
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/controllers/proyecto.controller.ts
@@ -0,0 +1,165 @@
+/**
+ * Proyecto Controller
+ * API endpoints para gestiΓ³n de proyectos
+ *
+ * @module Construction
+ * @prefix /api/v1/proyectos
+ */
+
+import { Router, Request, Response, NextFunction } from 'express';
+import { ProyectoService, CreateProyectoDto, UpdateProyectoDto } from '../services/proyecto.service';
+
+const router = Router();
+const proyectoService = new ProyectoService();
+
+/**
+ * GET /api/v1/proyectos
+ * Lista todos los proyectos del tenant
+ */
+router.get('/', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const { estadoProyecto, ciudad } = req.query;
+
+ const proyectos = await proyectoService.findAll({
+ tenantId,
+ estadoProyecto: estadoProyecto as any,
+ ciudad: ciudad as string,
+ });
+
+ return res.json({
+ success: true,
+ data: proyectos,
+ count: proyectos.length,
+ });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * GET /api/v1/proyectos/statistics
+ * EstadΓsticas de proyectos
+ */
+router.get('/statistics', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const stats = await proyectoService.getStatistics(tenantId);
+ return res.json({ success: true, data: stats });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * GET /api/v1/proyectos/:id
+ * Obtiene un proyecto por ID
+ */
+router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const proyecto = await proyectoService.findById(req.params.id, tenantId);
+ if (!proyecto) {
+ return res.status(404).json({ error: 'Proyecto no encontrado' });
+ }
+
+ return res.json({ success: true, data: proyecto });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * POST /api/v1/proyectos
+ * Crea un nuevo proyecto
+ */
+router.post('/', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const data: CreateProyectoDto = {
+ ...req.body,
+ tenantId,
+ createdById: (req as any).user?.id,
+ };
+
+ // Validate required fields
+ if (!data.codigo || !data.nombre) {
+ return res.status(400).json({ error: 'codigo y nombre son requeridos' });
+ }
+
+ // Check if codigo already exists
+ const existing = await proyectoService.findByCodigo(data.codigo, tenantId);
+ if (existing) {
+ return res.status(409).json({ error: 'Ya existe un proyecto con ese cΓ³digo' });
+ }
+
+ const proyecto = await proyectoService.create(data);
+ return res.status(201).json({ success: true, data: proyecto });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * PATCH /api/v1/proyectos/:id
+ * Actualiza un proyecto
+ */
+router.patch('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const data: UpdateProyectoDto = req.body;
+ const proyecto = await proyectoService.update(req.params.id, tenantId, data);
+
+ if (!proyecto) {
+ return res.status(404).json({ error: 'Proyecto no encontrado' });
+ }
+
+ return res.json({ success: true, data: proyecto });
+ } catch (error) {
+ next(error);
+ }
+});
+
+/**
+ * DELETE /api/v1/proyectos/:id
+ * Elimina un proyecto
+ */
+router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const tenantId = req.headers['x-tenant-id'] as string;
+ if (!tenantId) {
+ return res.status(400).json({ error: 'X-Tenant-Id header required' });
+ }
+
+ const deleted = await proyectoService.delete(req.params.id, tenantId);
+ if (!deleted) {
+ return res.status(404).json({ error: 'Proyecto no encontrado' });
+ }
+
+ return res.json({ success: true, message: 'Proyecto eliminado' });
+ } catch (error) {
+ next(error);
+ }
+});
+
+export default router;
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/fraccionamiento.service.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/fraccionamiento.service.ts
new file mode 100644
index 0000000..604b234
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/fraccionamiento.service.ts
@@ -0,0 +1,117 @@
+/**
+ * Fraccionamiento Service
+ * Servicio para gestiΓ³n de fraccionamientos/obras
+ *
+ * @module Construction
+ */
+
+import { Repository, FindOptionsWhere } from 'typeorm';
+import { AppDataSource } from '../../../shared/database/typeorm.config';
+import { Fraccionamiento, EstadoFraccionamiento } from '../entities/fraccionamiento.entity';
+
+export interface CreateFraccionamientoDto {
+ tenantId: string;
+ proyectoId: string;
+ codigo: string;
+ nombre: string;
+ descripcion?: string;
+ direccion?: string;
+ ubicacionGeo?: string;
+ fechaInicio?: Date;
+ fechaFinEstimada?: Date;
+ createdById?: string;
+}
+
+export interface UpdateFraccionamientoDto {
+ nombre?: string;
+ descripcion?: string;
+ direccion?: string;
+ ubicacionGeo?: string;
+ fechaInicio?: Date;
+ fechaFinEstimada?: Date;
+ estado?: EstadoFraccionamiento;
+}
+
+export interface FraccionamientoFilters {
+ tenantId: string;
+ proyectoId?: string;
+ estado?: EstadoFraccionamiento;
+}
+
+export class FraccionamientoService {
+ private repository: Repository;
+
+ constructor() {
+ this.repository = AppDataSource.getRepository(Fraccionamiento);
+ }
+
+ async findAll(filters: FraccionamientoFilters): Promise {
+ const where: FindOptionsWhere = {
+ tenantId: filters.tenantId,
+ };
+
+ if (filters.proyectoId) {
+ where.proyectoId = filters.proyectoId;
+ }
+
+ if (filters.estado) {
+ where.estado = filters.estado;
+ }
+
+ return this.repository.find({
+ where,
+ relations: ['proyecto'],
+ order: { createdAt: 'DESC' },
+ });
+ }
+
+ async findById(id: string, tenantId: string): Promise {
+ return this.repository.findOne({
+ where: { id, tenantId },
+ relations: ['proyecto', 'createdBy'],
+ });
+ }
+
+ async findByCodigo(codigo: string, tenantId: string): Promise {
+ return this.repository.findOne({
+ where: { codigo, tenantId },
+ });
+ }
+
+ async findByProyecto(proyectoId: string, tenantId: string): Promise {
+ return this.repository.find({
+ where: { proyectoId, tenantId },
+ order: { codigo: 'ASC' },
+ });
+ }
+
+ async create(data: CreateFraccionamientoDto): Promise {
+ const fraccionamiento = this.repository.create(data);
+ return this.repository.save(fraccionamiento);
+ }
+
+ async update(
+ id: string,
+ tenantId: string,
+ data: UpdateFraccionamientoDto
+ ): Promise {
+ const fraccionamiento = await this.findById(id, tenantId);
+ if (!fraccionamiento) {
+ return null;
+ }
+
+ Object.assign(fraccionamiento, data);
+ return this.repository.save(fraccionamiento);
+ }
+
+ async delete(id: string, tenantId: string): Promise {
+ const result = await this.repository.delete({ id, tenantId });
+ return result.affected ? result.affected > 0 : false;
+ }
+
+ async countByProyecto(proyectoId: string, tenantId: string): Promise {
+ return this.repository.count({
+ where: { proyectoId, tenantId },
+ });
+ }
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/index.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/index.ts
new file mode 100644
index 0000000..e78e8c4
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/index.ts
@@ -0,0 +1,7 @@
+/**
+ * Construction Services Index
+ * @module Construction
+ */
+
+export * from './proyecto.service';
+export * from './fraccionamiento.service';
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/proyecto.service.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/proyecto.service.ts
new file mode 100644
index 0000000..ae55f2d
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/construction/services/proyecto.service.ts
@@ -0,0 +1,117 @@
+/**
+ * Proyecto Service
+ * Servicio para gestiΓ³n de proyectos de construcciΓ³n
+ *
+ * @module Construction
+ */
+
+import { Repository, FindOptionsWhere } from 'typeorm';
+import { AppDataSource } from '../../../shared/database/typeorm.config';
+import { Proyecto, EstadoProyecto } from '../entities/proyecto.entity';
+
+export interface CreateProyectoDto {
+ tenantId: string;
+ codigo: string;
+ nombre: string;
+ descripcion?: string;
+ direccion?: string;
+ ciudad?: string;
+ estado?: string;
+ fechaInicio?: Date;
+ fechaFinEstimada?: Date;
+ createdById?: string;
+}
+
+export interface UpdateProyectoDto {
+ nombre?: string;
+ descripcion?: string;
+ direccion?: string;
+ ciudad?: string;
+ estado?: string;
+ fechaInicio?: Date;
+ fechaFinEstimada?: Date;
+ estadoProyecto?: EstadoProyecto;
+}
+
+export interface ProyectoFilters {
+ tenantId: string;
+ estadoProyecto?: EstadoProyecto;
+ ciudad?: string;
+}
+
+export class ProyectoService {
+ private repository: Repository;
+
+ constructor() {
+ this.repository = AppDataSource.getRepository(Proyecto);
+ }
+
+ async findAll(filters: ProyectoFilters): Promise {
+ const where: FindOptionsWhere = {
+ tenantId: filters.tenantId,
+ };
+
+ if (filters.estadoProyecto) {
+ where.estadoProyecto = filters.estadoProyecto;
+ }
+
+ if (filters.ciudad) {
+ where.ciudad = filters.ciudad;
+ }
+
+ return this.repository.find({
+ where,
+ relations: ['fraccionamientos'],
+ order: { createdAt: 'DESC' },
+ });
+ }
+
+ async findById(id: string, tenantId: string): Promise {
+ return this.repository.findOne({
+ where: { id, tenantId },
+ relations: ['fraccionamientos', 'createdBy'],
+ });
+ }
+
+ async findByCodigo(codigo: string, tenantId: string): Promise {
+ return this.repository.findOne({
+ where: { codigo, tenantId },
+ });
+ }
+
+ async create(data: CreateProyectoDto): Promise {
+ const proyecto = this.repository.create(data);
+ return this.repository.save(proyecto);
+ }
+
+ async update(id: string, tenantId: string, data: UpdateProyectoDto): Promise {
+ const proyecto = await this.findById(id, tenantId);
+ if (!proyecto) {
+ return null;
+ }
+
+ Object.assign(proyecto, data);
+ return this.repository.save(proyecto);
+ }
+
+ async delete(id: string, tenantId: string): Promise {
+ const result = await this.repository.delete({ id, tenantId });
+ return result.affected ? result.affected > 0 : false;
+ }
+
+ async getStatistics(tenantId: string): Promise<{
+ total: number;
+ activos: number;
+ completados: number;
+ pausados: number;
+ }> {
+ const proyectos = await this.repository.find({ where: { tenantId } });
+
+ return {
+ total: proyectos.length,
+ activos: proyectos.filter(p => p.estadoProyecto === 'activo').length,
+ completados: proyectos.filter(p => p.estadoProyecto === 'completado').length,
+ pausados: proyectos.filter(p => p.estadoProyecto === 'pausado').length,
+ };
+ }
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/capacitacion.entity.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/capacitacion.entity.ts
new file mode 100644
index 0000000..ecbd699
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/capacitacion.entity.ts
@@ -0,0 +1,74 @@
+/**
+ * Capacitacion Entity
+ * CatΓ‘logo de capacitaciones HSE
+ *
+ * @module HSE
+ * @table hse.capacitaciones
+ * @ddl schemas/03-hse-schema-ddl.sql
+ * @rf RF-MAA017-002
+ */
+
+import {
+ Entity,
+ PrimaryGeneratedColumn,
+ Column,
+ CreateDateColumn,
+ UpdateDateColumn,
+ ManyToOne,
+ JoinColumn,
+ Index,
+} from 'typeorm';
+import { Tenant } from '../../core/entities/tenant.entity';
+
+export type TipoCapacitacion = 'induccion' | 'especifica' | 'certificacion' | 'reentrenamiento';
+
+@Entity({ schema: 'hse', name: 'capacitaciones' })
+@Index(['tenantId', 'codigo'], { unique: true })
+export class Capacitacion {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column({ name: 'tenant_id', type: 'uuid' })
+ tenantId: string;
+
+ @Column({ type: 'varchar', length: 20 })
+ codigo: string;
+
+ @Column({ type: 'varchar', length: 200 })
+ nombre: string;
+
+ @Column({ type: 'text', nullable: true })
+ descripcion: string;
+
+ @Column({
+ type: 'enum',
+ enum: ['induccion', 'especifica', 'certificacion', 'reentrenamiento']
+ })
+ tipo: TipoCapacitacion;
+
+ @Column({ name: 'duracion_horas', type: 'integer', default: 1 })
+ duracionHoras: number;
+
+ @Column({ name: 'vigencia_meses', type: 'integer', nullable: true })
+ vigenciaMeses: number;
+
+ @Column({ name: 'requiere_evaluacion', type: 'boolean', default: false })
+ requiereEvaluacion: boolean;
+
+ @Column({ name: 'calificacion_minima', type: 'integer', nullable: true })
+ calificacionMinima: number;
+
+ @Column({ type: 'boolean', default: true })
+ activo: boolean;
+
+ @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
+ createdAt: Date;
+
+ @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
+ updatedAt: Date;
+
+ // Relations
+ @ManyToOne(() => Tenant)
+ @JoinColumn({ name: 'tenant_id' })
+ tenant: Tenant;
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-accion.entity.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-accion.entity.ts
new file mode 100644
index 0000000..4fae042
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-accion.entity.ts
@@ -0,0 +1,71 @@
+/**
+ * IncidenteAccion Entity
+ * Acciones correctivas de incidentes
+ *
+ * @module HSE
+ * @table hse.incidente_acciones
+ * @ddl schemas/03-hse-schema-ddl.sql
+ * @rf RF-MAA017-001
+ */
+
+import {
+ Entity,
+ PrimaryGeneratedColumn,
+ Column,
+ CreateDateColumn,
+ UpdateDateColumn,
+ ManyToOne,
+ JoinColumn,
+} from 'typeorm';
+import { Incidente } from './incidente.entity';
+import { Employee } from '../../hr/entities/employee.entity';
+
+export type EstadoAccion = 'pendiente' | 'en_progreso' | 'completada' | 'verificada';
+
+@Entity({ schema: 'hse', name: 'incidente_acciones' })
+export class IncidenteAccion {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column({ name: 'incidente_id', type: 'uuid' })
+ incidenteId: string;
+
+ @Column({ type: 'text' })
+ descripcion: string;
+
+ @Column({ type: 'varchar', length: 50 })
+ tipo: string;
+
+ @Column({ name: 'responsable_id', type: 'uuid', nullable: true })
+ responsableId: string;
+
+ @Column({ name: 'fecha_compromiso', type: 'date' })
+ fechaCompromiso: Date;
+
+ @Column({ name: 'fecha_cierre', type: 'date', nullable: true })
+ fechaCierre: Date;
+
+ @Column({ type: 'varchar', length: 20, default: 'pendiente' })
+ estado: EstadoAccion;
+
+ @Column({ name: 'evidencia_url', type: 'varchar', length: 500, nullable: true })
+ evidenciaUrl: string;
+
+ @Column({ type: 'text', nullable: true })
+ observaciones: string;
+
+ @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
+ createdAt: Date;
+
+ @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
+ updatedAt: Date;
+
+ // Relations
+ @ManyToOne(() => Incidente, (i) => i.acciones, { onDelete: 'CASCADE' })
+ @JoinColumn({ name: 'incidente_id' })
+ incidente: Incidente;
+
+ @ManyToOne(() => Employee)
+ @JoinColumn({ name: 'responsable_id' })
+ responsable: Employee;
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-involucrado.entity.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-involucrado.entity.ts
new file mode 100644
index 0000000..b92eb67
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente-involucrado.entity.ts
@@ -0,0 +1,58 @@
+/**
+ * IncidenteInvolucrado Entity
+ * Personas involucradas en incidentes
+ *
+ * @module HSE
+ * @table hse.incidente_involucrados
+ * @ddl schemas/03-hse-schema-ddl.sql
+ * @rf RF-MAA017-001
+ */
+
+import {
+ Entity,
+ PrimaryGeneratedColumn,
+ Column,
+ CreateDateColumn,
+ ManyToOne,
+ JoinColumn,
+} from 'typeorm';
+import { Incidente } from './incidente.entity';
+import { Employee } from '../../hr/entities/employee.entity';
+
+export type RolInvolucrado = 'lesionado' | 'testigo' | 'responsable';
+
+@Entity({ schema: 'hse', name: 'incidente_involucrados' })
+export class IncidenteInvolucrado {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column({ name: 'incidente_id', type: 'uuid' })
+ incidenteId: string;
+
+ @Column({ name: 'employee_id', type: 'uuid' })
+ employeeId: string;
+
+ @Column({ type: 'enum', enum: ['lesionado', 'testigo', 'responsable'] })
+ rol: RolInvolucrado;
+
+ @Column({ name: 'descripcion_lesion', type: 'text', nullable: true })
+ descripcionLesion: string;
+
+ @Column({ name: 'parte_cuerpo', type: 'varchar', length: 100, nullable: true })
+ parteCuerpo: string;
+
+ @Column({ name: 'dias_incapacidad', type: 'integer', default: 0 })
+ diasIncapacidad: number;
+
+ @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
+ createdAt: Date;
+
+ // Relations
+ @ManyToOne(() => Incidente, (i) => i.involucrados, { onDelete: 'CASCADE' })
+ @JoinColumn({ name: 'incidente_id' })
+ incidente: Incidente;
+
+ @ManyToOne(() => Employee)
+ @JoinColumn({ name: 'employee_id' })
+ employee: Employee;
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente.entity.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente.entity.ts
new file mode 100644
index 0000000..249c5a6
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/incidente.entity.ts
@@ -0,0 +1,111 @@
+/**
+ * Incidente Entity
+ * GestiΓ³n de incidentes de seguridad
+ *
+ * @module HSE
+ * @table hse.incidentes
+ * @ddl schemas/03-hse-schema-ddl.sql
+ * @rf RF-MAA017-001
+ */
+
+import {
+ Entity,
+ PrimaryGeneratedColumn,
+ Column,
+ CreateDateColumn,
+ UpdateDateColumn,
+ ManyToOne,
+ OneToMany,
+ JoinColumn,
+ Index,
+} from 'typeorm';
+import { Tenant } from '../../core/entities/tenant.entity';
+import { User } from '../../core/entities/user.entity';
+import { Fraccionamiento } from '../../construction/entities/fraccionamiento.entity';
+import { IncidenteInvolucrado } from './incidente-involucrado.entity';
+import { IncidenteAccion } from './incidente-accion.entity';
+
+export type TipoIncidente = 'accidente' | 'incidente' | 'casi_accidente';
+export type GravedadIncidente = 'leve' | 'moderado' | 'grave' | 'fatal';
+export type EstadoIncidente = 'abierto' | 'en_investigacion' | 'cerrado';
+
+@Entity({ schema: 'hse', name: 'incidentes' })
+@Index(['tenantId', 'folio'], { unique: true })
+export class Incidente {
+ @PrimaryGeneratedColumn('uuid')
+ id: string;
+
+ @Column({ name: 'tenant_id', type: 'uuid' })
+ tenantId: string;
+
+ @Column({ type: 'varchar', length: 20 })
+ folio: string;
+
+ @Column({ name: 'fecha_hora', type: 'timestamptz' })
+ fechaHora: Date;
+
+ @Column({ name: 'fraccionamiento_id', type: 'uuid' })
+ fraccionamientoId: string;
+
+ @Column({ name: 'ubicacion_descripcion', type: 'text', nullable: true })
+ ubicacionDescripcion: string;
+
+ @Column({
+ name: 'ubicacion_geo',
+ type: 'geometry',
+ spatialFeatureType: 'Point',
+ srid: 4326,
+ nullable: true
+ })
+ ubicacionGeo: string;
+
+ @Column({ type: 'enum', enum: ['accidente', 'incidente', 'casi_accidente'] })
+ tipo: TipoIncidente;
+
+ @Column({ type: 'enum', enum: ['leve', 'moderado', 'grave', 'fatal'] })
+ gravedad: GravedadIncidente;
+
+ @Column({ type: 'text' })
+ descripcion: string;
+
+ @Column({ name: 'causa_inmediata', type: 'text', nullable: true })
+ causaInmediata: string;
+
+ @Column({ name: 'causa_basica', type: 'text', nullable: true })
+ causaBasica: string;
+
+ @Column({
+ type: 'enum',
+ enum: ['abierto', 'en_investigacion', 'cerrado'],
+ default: 'abierto'
+ })
+ estado: EstadoIncidente;
+
+ @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
+ createdAt: Date;
+
+ @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
+ updatedAt: Date;
+
+ @Column({ name: 'created_by', type: 'uuid', nullable: true })
+ createdById: string;
+
+ // Relations
+ @ManyToOne(() => Tenant)
+ @JoinColumn({ name: 'tenant_id' })
+ tenant: Tenant;
+
+ @ManyToOne(() => Fraccionamiento)
+ @JoinColumn({ name: 'fraccionamiento_id' })
+ fraccionamiento: Fraccionamiento;
+
+ @ManyToOne(() => User)
+ @JoinColumn({ name: 'created_by' })
+ createdBy: User;
+
+ @OneToMany(() => IncidenteInvolucrado, (ii) => ii.incidente)
+ involucrados: IncidenteInvolucrado[];
+
+ @OneToMany(() => IncidenteAccion, (ia) => ia.incidente)
+ acciones: IncidenteAccion[];
+}
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/index.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/index.ts
new file mode 100644
index 0000000..00cea16
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/modules/hse/entities/index.ts
@@ -0,0 +1,23 @@
+/**
+ * HSE Entities Index
+ * @module HSE
+ *
+ * Entities for Health, Safety & Environment module
+ * Based on RF-MAA017-001 to RF-MAA017-008
+ */
+
+// RF-MAA017-001: GestiΓ³n de Incidentes
+export * from './incidente.entity';
+export * from './incidente-involucrado.entity';
+export * from './incidente-accion.entity';
+
+// RF-MAA017-002: Control de Capacitaciones
+export * from './capacitacion.entity';
+
+// TODO: Implementar entities adicionales segΓΊn se necesiten:
+// - RF-MAA017-003: Inspecciones de Seguridad
+// - RF-MAA017-004: Control de EPP
+// - RF-MAA017-005: Cumplimiento STPS
+// - RF-MAA017-006: GestiΓ³n Ambiental
+// - RF-MAA017-007: Permisos de Trabajo
+// - RF-MAA017-008: Indicadores HSE
diff --git a/projects/erp-suite/apps/verticales/construccion/backend/src/server.ts b/projects/erp-suite/apps/verticales/construccion/backend/src/server.ts
index 571dcb4..9797f95 100644
--- a/projects/erp-suite/apps/verticales/construccion/backend/src/server.ts
+++ b/projects/erp-suite/apps/verticales/construccion/backend/src/server.ts
@@ -47,8 +47,10 @@ app.get('/health', (req, res) => {
/**
* API Routes
- * TODO: Agregar rutas de mΓ³dulos aquΓ
*/
+import { proyectoController, fraccionamientoController } from './modules/construction/controllers';
+
+// Root API info
app.get(`/api/${API_VERSION}`, (req, res) => {
res.status(200).json({
message: 'API MVP Sistema AdministraciΓ³n de Obra',
@@ -57,12 +59,16 @@ app.get(`/api/${API_VERSION}`, (req, res) => {
health: '/health',
docs: `/api/${API_VERSION}/docs`,
auth: `/api/${API_VERSION}/auth`,
- projects: `/api/${API_VERSION}/projects`,
- budgets: `/api/${API_VERSION}/budgets`,
+ proyectos: `/api/${API_VERSION}/proyectos`,
+ fraccionamientos: `/api/${API_VERSION}/fraccionamientos`,
},
});
});
+// Construction Module Routes
+app.use(`/api/${API_VERSION}/proyectos`, proyectoController);
+app.use(`/api/${API_VERSION}/fraccionamientos`, fraccionamientoController);
+
/**
* 404 Handler
*/
diff --git a/projects/erp-suite/apps/verticales/construccion/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md b/projects/erp-suite/apps/verticales/construccion/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
new file mode 100644
index 0000000..c55197b
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/construccion/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
@@ -0,0 +1,159 @@
+# Herencia de SPECS del Core - ConstrucciΓ³n
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** ConstrucciΓ³n (MAI/MAE)
+**Nivel:** 2B.2
+
+---
+
+## Resumen
+
+| MΓ©trica | Valor |
+|---------|-------|
+| SPECS Aplicables | 26/30 |
+| SPECS Obligatorias | 22 |
+| SPECS Opcionales | 4 |
+| SPECS No Aplican | 4 |
+| Estado ImplementaciΓ³n | 0% |
+
+---
+
+## SPECS Obligatorias (Deben Implementarse)
+
+### P0 - CrΓticas
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-SISTEMA-SECUENCIAS | ir.sequence | 8 | PENDIENTE | MAI-001, MAE-001 |
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO | 21 | PENDIENTE | MAI-004, MAI-012 |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL | 31 | PENDIENTE | MAI-001 |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | 13 | PENDIENTE | MAE-003 |
+| SPEC-PORTAL-PROVEEDORES | Portal RFQ | 13 | PENDIENTE | MAI-006 |
+| SPEC-NOMINA-BASICA | hr_payroll | 21 | PENDIENTE | MAI-008 |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | 13 | PENDIENTE | MAI-008 |
+| SPEC-TAREAS-RECURRENTES | project.task.recurrence | 13 | PENDIENTE | MAI-002, MAI-005 |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | 8 | PENDIENTE | MAE-003 |
+
+### P1 - Complementarias
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-CONTABILIDAD-ANALITICA | Centros de costo | 21 | PENDIENTE | MAE-003 |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n | 21 | PENDIENTE | MAE-003 |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | e.firma | 13 | PENDIENTE | MAE-001, MAI-007 |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA | 13 | PENDIENTE | MAI-001 |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes/Series | 13 | PENDIENTE | MAI-004, MAI-012 |
+| SPEC-BLANKET-ORDERS | Γrdenes marco | 13 | PENDIENTE | MAI-006 |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR | 8 | PENDIENTE | MAE-003 |
+| SPEC-PLANTILLAS-CUENTAS | Plan contable | 8 | PENDIENTE | MAE-003 |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos cambio | 5 | PENDIENTE | MAE-003 |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas | 8 | PENDIENTE | MAI-012 |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n | 8 | PENDIENTE | MAI-005, MAI-012 |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones | 26 | PENDIENTE | MAI-008 |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | Burndown | 13 | PENDIENTE | MAI-002, MAI-005 |
+| SPEC-LOCALIZACION-PAISES | LocalizaciΓ³n | 13 | PENDIENTE | MAE-001 |
+
+### Patrones TΓ©cnicos
+
+| SPEC | PatrΓ³n | SP | Estado | AplicaciΓ³n |
+|------|--------|----:|--------|------------|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread | 13 | PENDIENTE | Proyectos, Estimaciones, Obras |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | 8 | PENDIENTE | Wizards de cierre, aprobaciΓ³n |
+
+---
+
+## SPECS Opcionales
+
+| SPEC | DescripciΓ³n | SP | DecisiΓ³n | RazΓ³n |
+|------|-------------|----:|----------|-------|
+| SPEC-INTEGRACION-CALENDAR | Calendario | 8 | EVALUAR | Γtil para programaciΓ³n de obra |
+| SPEC-PRICING-RULES | Reglas precio | 8 | EVALUAR | Para cotizaciones complejas |
+| SPEC-OAUTH2-SOCIAL-LOGIN | OAuth2 | 8 | DIFERIR | No prioritario |
+| SPEC-CONSOLIDACION-FINANCIERA | Multi-empresa | 13 | DIFERIR | Futuro para constructoras grandes |
+
+---
+
+## SPECS No Aplicables
+
+| SPEC | RazΓ³n |
+|------|-------|
+| SPEC-INVENTARIOS-CICLICOS | No hay inventario tradicional de productos |
+| SPEC-INTEGRACION-CALENDAR | El mΓ³dulo de proyectos maneja calendario propio |
+
+---
+
+## Adaptaciones Requeridas
+
+### Mapeo de Conceptos Core β ConstrucciΓ³n
+
+| Concepto Core | Concepto ConstrucciΓ³n |
+|---------------|----------------------|
+| `projects.projects` | Obras, Fraccionamientos |
+| `projects.tasks` | Etapas de construcciΓ³n |
+| `inventory.products` | Materiales de construcciΓ³n |
+| `inventory.lots` | Lotes de materiales |
+| `hr.employees` | Trabajadores de obra |
+| `sales.sale_orders` | Contratos de obra |
+| `purchase.purchase_orders` | Γrdenes de compra de materiales |
+
+### Extensiones de Entidad
+
+```sql
+-- ExtensiΓ³n de projects para construcciΓ³n
+construction.project_extensions (
+ project_id β projects.projects,
+ tipo_obra ENUM,
+ numero_licencia VARCHAR,
+ fecha_inicio_obra DATE,
+ fecha_fin_estimada DATE,
+ m2_construccion DECIMAL,
+ presupuesto_aprobado DECIMAL
+)
+
+-- ExtensiΓ³n de employees para construcciΓ³n
+construction.employee_extensions (
+ employee_id β hr.employees,
+ numero_imss VARCHAR,
+ categoria_obra ENUM,
+ especialidad VARCHAR,
+ certificaciones JSONB
+)
+```
+
+---
+
+## Plan de ImplementaciΓ³n
+
+### Fase 1: Fundamentos (SP: 60)
+1. SPEC-SISTEMA-SECUENCIAS
+2. SPEC-SEGURIDAD-API-KEYS-PERMISOS
+3. SPEC-TWO-FACTOR-AUTHENTICATION
+
+### Fase 2: Core de Negocio (SP: 80)
+4. SPEC-VALORACION-INVENTARIO
+5. SPEC-TRAZABILIDAD-LOTES-SERIES
+6. SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN
+
+### Fase 3: Financiero (SP: 65)
+7. SPEC-REPORTES-FINANCIEROS
+8. SPEC-CONTABILIDAD-ANALITICA
+9. SPEC-IMPUESTOS-AVANZADOS
+
+### Fase 4: RRHH (SP: 60)
+10. SPEC-NOMINA-BASICA
+11. SPEC-GASTOS-EMPLEADOS
+12. SPEC-RRHH-EVALUACIONES-SKILLS
+
+---
+
+## Referencias
+
+- Documento Core: `erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md`
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+
+---
+
+**Documento de herencia de SPECS oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/construccion/orchestration/inventarios/BACKEND_INVENTORY.yml b/projects/erp-suite/apps/verticales/construccion/orchestration/inventarios/BACKEND_INVENTORY.yml
index a85da10..debaf97 100644
--- a/projects/erp-suite/apps/verticales/construccion/orchestration/inventarios/BACKEND_INVENTORY.yml
+++ b/projects/erp-suite/apps/verticales/construccion/orchestration/inventarios/BACKEND_INVENTORY.yml
@@ -53,20 +53,37 @@ resumen:
# ESTADO REAL DE IMPLEMENTACIΓN (2025-12-08)
estado_implementacion:
- porcentaje: "5%"
- archivos_ts: 7
- entities_implementadas: 2
- services_implementados: 0
- controllers_implementados: 0
+ porcentaje: "15%"
+ archivos_ts: 25
+ entities_implementadas: 12
+ services_implementados: 2
+ controllers_implementados: 2
- archivos_existentes:
- - src/types/
- - src/entities/ # Parcialmente definidas
+ modulos_implementados:
+ construction:
+ entities: [Proyecto, Fraccionamiento]
+ services: [ProyectoService, FraccionamientoService]
+ controllers: [ProyectoController, FraccionamientoController]
+ estado: "FUNCIONAL"
+ hr:
+ entities: [Employee, Puesto, EmployeeFraccionamiento]
+ services: []
+ controllers: []
+ estado: "ENTITIES_COMPLETAS"
+ hse:
+ entities: [Incidente, IncidenteInvolucrado, IncidenteAccion, Capacitacion]
+ services: []
+ controllers: []
+ estado: "ENTITIES_PARCIALES"
+ core:
+ entities: [User, Tenant]
+ estado: "BASE"
gap_documentacion_vs_codigo:
documentacion_md: 449
- archivos_codigo: 7
- ratio: "1.5%"
+ archivos_codigo: 25
+ ratio: "5.6%"
+ nota: "Gap reducido - entities y services base implementados"
herencia_core:
version_core: "1.1.0"
diff --git a/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md b/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
new file mode 100644
index 0000000..bf5dae8
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
@@ -0,0 +1,169 @@
+# Herencia de SPECS del Core - MecΓ‘nicas Diesel
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** MecΓ‘nicas Diesel (MMD)
+**Nivel:** 2B.2
+
+---
+
+## Resumen
+
+| MΓ©trica | Valor |
+|---------|-------|
+| SPECS Aplicables | 25/30 |
+| SPECS Obligatorias | 23 |
+| SPECS Opcionales | 2 |
+| SPECS No Aplican | 5 |
+| Estado ImplementaciΓ³n | 0% |
+
+---
+
+## SPECS Obligatorias (Deben Implementarse)
+
+### P0 - CrΓticas
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-SISTEMA-SECUENCIAS | ir.sequence | 8 | PENDIENTE | MMD-001, MMD-002 |
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO | 21 | PENDIENTE | MMD-004 |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL | 31 | PENDIENTE | MMD-001 |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | 13 | PENDIENTE | MMD-006 |
+| SPEC-PORTAL-PROVEEDORES | Portal RFQ | 13 | PENDIENTE | MMD-004 |
+| SPEC-NOMINA-BASICA | hr_payroll | 21 | PENDIENTE | MMD-001 |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | 13 | PENDIENTE | MMD-001 |
+| SPEC-TAREAS-RECURRENTES | project.task.recurrence | 13 | PENDIENTE | MMD-002 |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | 8 | PENDIENTE | MMD-006 |
+
+### P1 - Complementarias
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-CONTABILIDAD-ANALITICA | Centros de costo | 21 | PENDIENTE | MMD-006 |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n | 21 | PENDIENTE | MMD-006 |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA | 13 | PENDIENTE | MMD-001 |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes/Series | 13 | PENDIENTE | MMD-004 |
+| SPEC-PRICING-RULES | Reglas precio | 8 | PENDIENTE | MMD-002, MMD-006 |
+| SPEC-BLANKET-ORDERS | Γrdenes marco | 13 | PENDIENTE | MMD-004 |
+| SPEC-INVENTARIOS-CICLICOS | Conteo cΓclico | 13 | PENDIENTE | MMD-004 |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR | 8 | PENDIENTE | MMD-006 |
+| SPEC-PLANTILLAS-CUENTAS | Plan contable | 8 | PENDIENTE | MMD-006 |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos cambio | 5 | PENDIENTE | MMD-006 |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas | 8 | PENDIENTE | MMD-002, MMD-006 |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n | 8 | PENDIENTE | MMD-002 |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones | 26 | PENDIENTE | MMD-001 |
+| SPEC-LOCALIZACION-PAISES | LocalizaciΓ³n | 13 | PENDIENTE | MMD-001 |
+
+### Patrones TΓ©cnicos
+
+| SPEC | PatrΓ³n | SP | Estado | AplicaciΓ³n |
+|------|--------|----:|--------|------------|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread | 13 | PENDIENTE | Γrdenes de trabajo, DiagnΓ³sticos |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | 8 | PENDIENTE | Wizards de cotizaciΓ³n, cierre |
+
+---
+
+## SPECS Opcionales
+
+| SPEC | DescripciΓ³n | SP | DecisiΓ³n | RazΓ³n |
+|------|-------------|----:|----------|-------|
+| SPEC-FIRMA-ELECTRONICA-NOM151 | e.firma | 13 | EVALUAR | Para contratos de servicio |
+| SPEC-OAUTH2-SOCIAL-LOGIN | OAuth2 | 8 | DIFERIR | No prioritario |
+
+---
+
+## SPECS No Aplicables
+
+| SPEC | RazΓ³n |
+|------|-------|
+| SPEC-INTEGRACION-CALENDAR | No hay agenda de citas compleja |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | No hay gestiΓ³n de proyectos larga |
+| SPEC-CONSOLIDACION-FINANCIERA | Negocio de una sola ubicaciΓ³n |
+
+---
+
+## Adaptaciones Requeridas
+
+### Mapeo de Conceptos Core β MecΓ‘nicas
+
+| Concepto Core | Concepto MecΓ‘nicas |
+|---------------|-------------------|
+| `sales.sale_orders` | Γrdenes de servicio |
+| `inventory.products` | Refacciones, partes |
+| `inventory.lots` | Lotes OEM, garantΓas |
+| `core.partners` | Clientes con vehΓculos |
+| `projects.tasks` | Trabajos de servicio |
+
+### Extensiones de Entidad
+
+```sql
+-- VehΓculos de clientes
+service_management.vehicles (
+ id UUID,
+ partner_id β core.partners,
+ vin VARCHAR(17),
+ marca VARCHAR,
+ modelo VARCHAR,
+ anio INTEGER,
+ motor_tipo VARCHAR,
+ placas VARCHAR
+)
+
+-- Γrdenes de servicio
+service_management.service_orders (
+ id UUID,
+ vehicle_id β vehicles,
+ sale_order_id β sales.sale_orders,
+ tipo_servicio ENUM,
+ km_entrada INTEGER,
+ diagnostico TEXT,
+ estado ENUM
+)
+
+-- Refacciones con compatibilidad
+parts_management.parts (
+ product_id β inventory.products,
+ oem_number VARCHAR,
+ aftermarket_number VARCHAR,
+ compatibilidad JSONB
+)
+```
+
+---
+
+## Plan de ImplementaciΓ³n
+
+### Fase 1: Fundamentos (SP: 52)
+1. SPEC-SISTEMA-SECUENCIAS
+2. SPEC-SEGURIDAD-API-KEYS-PERMISOS
+3. SPEC-TWO-FACTOR-AUTHENTICATION
+
+### Fase 2: Inventario (SP: 55)
+4. SPEC-VALORACION-INVENTARIO
+5. SPEC-TRAZABILIDAD-LOTES-SERIES
+6. SPEC-INVENTARIOS-CICLICOS
+7. SPEC-PRICING-RULES
+
+### Fase 3: Operaciones (SP: 34)
+8. SPEC-MAIL-THREAD-TRACKING
+9. SPEC-WIZARD-TRANSIENT-MODEL
+10. SPEC-TAREAS-RECURRENTES
+
+### Fase 4: Financiero (SP: 65)
+11. SPEC-REPORTES-FINANCIEROS
+12. SPEC-CONTABILIDAD-ANALITICA
+13. SPEC-CONCILIACION-BANCARIA
+
+---
+
+## Referencias
+
+- Documento Core: `erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md`
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- Directivas: `orchestration/directivas/`
+
+---
+
+**Documento de herencia de SPECS oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/inventarios/README.md b/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/inventarios/README.md
new file mode 100644
index 0000000..bdff046
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/mecanicas-diesel/orchestration/inventarios/README.md
@@ -0,0 +1,106 @@
+# Inventarios - ERP MecΓ‘nicas Diesel
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Nivel SIMCO:** 2B.2
+
+---
+
+## DescripciΓ³n
+
+Este directorio contiene los inventarios YAML que sirven como **Single Source of Truth (SSOT)** para el proyecto ERP MecΓ‘nicas Diesel. Estos archivos son la referencia canΓ³nica para mΓ©tricas, trazabilidad y componentes del sistema.
+
+---
+
+## Archivos de Inventario
+
+| Archivo | DescripciΓ³n | Estado |
+|---------|-------------|--------|
+| [MASTER_INVENTORY.yml](./MASTER_INVENTORY.yml) | Inventario maestro con mΓ©tricas globales | Completo |
+| [DATABASE_INVENTORY.yml](./DATABASE_INVENTORY.yml) | Inventario de objetos de base de datos | Completo |
+| [BACKEND_INVENTORY.yml](./BACKEND_INVENTORY.yml) | Inventario de componentes backend | Planificado |
+| [FRONTEND_INVENTORY.yml](./FRONTEND_INVENTORY.yml) | Inventario de componentes frontend | Planificado |
+| [TRACEABILITY_MATRIX.yml](./TRACEABILITY_MATRIX.yml) | Matriz de trazabilidad RF->ET->US | Completo |
+| [DEPENDENCY_GRAPH.yml](./DEPENDENCY_GRAPH.yml) | Grafo de dependencias entre mΓ³dulos | Completo |
+
+---
+
+## Herencia del Core
+
+Este proyecto hereda del **ERP Core** (nivel 2B.1):
+
+| Aspecto | Heredado | EspecΓfico |
+|---------|----------|------------|
+| **Tablas DB** | 97 | 30+ |
+| **Schemas** | 8 | 3 |
+| **Specs** | 5 | - |
+
+### Specs Heredadas
+
+1. SPEC-VALORACION-INVENTARIO.md
+2. SPEC-TRAZABILIDAD-LOTES-SERIES.md
+3. SPEC-INVENTARIOS-CICLICOS.md
+4. SPEC-MAIL-THREAD-TRACKING.md
+5. SPEC-TAREAS-RECURRENTES.md
+
+### Documento de Herencia
+
+Ver: [`database/HERENCIA-ERP-CORE.md`](../../database/HERENCIA-ERP-CORE.md)
+
+---
+
+## Resumen Ejecutivo
+
+### MΓ©tricas del Proyecto
+
+| MΓ©trica | Valor |
+|---------|-------|
+| **MΓ³dulos** | 5 (MD-001 a MD-005) |
+| **Schemas especΓficos** | 3 |
+| **Tablas especΓficas** | 30+ |
+| **DDL implementado** | 1,561 lΓneas |
+| **Estado** | DDL_IMPLEMENTADO |
+
+### Schemas EspecΓficos
+
+| Schema | PropΓ³sito | Tablas |
+|--------|-----------|--------|
+| `service_management` | Γrdenes de servicio | 10+ |
+| `parts_management` | Inventario refacciones | 12+ |
+| `vehicle_management` | GestiΓ³n de vehΓculos | 8+ |
+
+---
+
+## ConfiguraciΓ³n de Puertos (Planificado)
+
+| Servicio | Puerto |
+|----------|--------|
+| Backend API | 3200 |
+| Frontend Web | 5175 |
+| PostgreSQL | Compartido con Core |
+| Redis | Compartido con Core |
+
+---
+
+## Directivas EspecΓficas
+
+1. [DIRECTIVA-ORDENES-TRABAJO.md](../directivas/DIRECTIVA-ORDENES-TRABAJO.md)
+2. [DIRECTIVA-INVENTARIO-REFACCIONES.md](../directivas/DIRECTIVA-INVENTARIO-REFACCIONES.md)
+
+---
+
+## AlineaciΓ³n con ERP Core
+
+Estos inventarios siguen la misma estructura que:
+- `/erp-core/orchestration/inventarios/` (proyecto padre)
+- `/verticales/construccion/orchestration/inventarios/` (vertical hermana)
+
+### Referencias
+
+- Suite Master: `orchestration/inventarios/SUITE_MASTER_INVENTORY.yml`
+- Core: `apps/erp-core/orchestration/inventarios/`
+- Status Global: `orchestration/inventarios/STATUS.yml`
+
+---
+
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/retail/database/HERENCIA-ERP-CORE.md b/projects/erp-suite/apps/verticales/retail/database/HERENCIA-ERP-CORE.md
new file mode 100644
index 0000000..62bf581
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/retail/database/HERENCIA-ERP-CORE.md
@@ -0,0 +1,187 @@
+# Herencia de Base de Datos - ERP Core -> Retail
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** Retail
+**Nivel:** 2B.2
+
+---
+
+## RESUMEN
+
+La vertical de Retail hereda los schemas base del ERP Core y extiende con schemas especΓficos del dominio de punto de venta y comercio minorista.
+
+**UbicaciΓ³n DDL Core:** `apps/erp-core/database/ddl/`
+
+---
+
+## ARQUITECTURA DE HERENCIA
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β ERP CORE (Base) β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β auth β β core β βfinancialβ βinventoryβ β purchase β β
+β β 26 tbl β β 12 tbl β β 15 tbl β β 15 tbl β β 8 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β sales β βanalyticsβ β system β β crm β β
+β β 6 tbl β β 5 tbl β β 10 tbl β β 5 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β TOTAL: ~102 tablas heredadas β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ β HEREDA
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β RETAIL (Extensiones) β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β β pos β β stores β β pricing β β
+β β (punto venta) β β (sucursales) β β (promociones) β β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β EXTENSIONES: ~30 tablas (planificadas) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## SCHEMAS HEREDADOS DEL CORE
+
+| Schema | Tablas | Uso en Retail |
+|--------|--------|---------------|
+| `auth` | 26 | AutenticaciΓ³n, usuarios por sucursal |
+| `core` | 12 | Partners (clientes), catΓ‘logos |
+| `financial` | 15 | Facturas, cuentas, caja |
+| `inventory` | 15 | Inventario multi-sucursal |
+| `purchase` | 8 | Compras a proveedores |
+| `sales` | 6 | Ventas base |
+| `crm` | 5 | Clientes frecuentes |
+| `analytics` | 5 | MΓ©tricas de venta |
+| `system` | 10 | Notificaciones |
+
+**Total heredado:** ~102 tablas
+
+---
+
+## SCHEMAS ESPECΓFICOS DE RETAIL (Planificados)
+
+### 1. Schema `pos` (estimado 12+ tablas)
+
+**PropΓ³sito:** Punto de venta y operaciones de caja
+
+```sql
+-- Tablas principales planificadas:
+pos.cash_registers -- Cajas registradoras
+pos.cash_sessions -- Sesiones de caja
+pos.pos_orders -- Tickets/ventas POS
+pos.pos_order_lines -- LΓneas de ticket
+pos.payment_methods -- MΓ©todos de pago
+pos.cash_movements -- Movimientos de caja
+pos.cash_counts -- Cortes de caja
+pos.receipts -- Recibos
+```
+
+### 2. Schema `stores` (estimado 8+ tablas)
+
+**PropΓ³sito:** GestiΓ³n de sucursales
+
+```sql
+-- Tablas principales planificadas:
+stores.branches -- Sucursales
+stores.branch_inventory -- Inventario por sucursal
+stores.transfers -- Transferencias entre sucursales
+stores.transfer_lines -- LΓneas de transferencia
+stores.branch_employees -- Empleados por sucursal
+```
+
+### 3. Schema `pricing` (estimado 10+ tablas)
+
+**PropΓ³sito:** Precios y promociones
+
+```sql
+-- Extiende: sales schema del core
+pricing.price_lists -- Listas de precios
+pricing.promotions -- Promociones
+pricing.discounts -- Descuentos
+pricing.loyalty_programs -- Programas de lealtad
+pricing.coupons -- Cupones
+pricing.price_history -- Historial de precios
+```
+
+---
+
+## SPECS DEL CORE APLICABLES
+
+**Documento detallado:** `orchestration/00-guidelines/HERENCIA-SPECS-CORE.md`
+
+### SPECS Obligatorias
+
+| Spec Core | AplicaciΓ³n en Retail | SP | Estado |
+|-----------|---------------------|----:|--------|
+| SPEC-SISTEMA-SECUENCIAS | Foliado de tickets y facturas | 8 | PENDIENTE |
+| SPEC-VALORACION-INVENTARIO | Costeo de mercancΓa | 21 | PENDIENTE |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | Control de acceso por sucursal | 31 | PENDIENTE |
+| SPEC-PRICING-RULES | Precios y promociones | 8 | PENDIENTE |
+| SPEC-INVENTARIOS-CICLICOS | Conteos en sucursales | 13 | PENDIENTE |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Productos con lote/serie | 13 | PENDIENTE |
+| SPEC-MAIL-THREAD-TRACKING | ComunicaciΓ³n con clientes | 13 | PENDIENTE |
+| SPEC-WIZARD-TRANSIENT-MODEL | Wizards de cierre de caja | 8 | PENDIENTE |
+
+### SPECS Opcionales
+
+| Spec Core | DecisiΓ³n | RazΓ³n |
+|-----------|----------|-------|
+| SPEC-PORTAL-PROVEEDORES | EVALUAR | Para compras centralizadas |
+| SPEC-TAREAS-RECURRENTES | EVALUAR | Para reorden automΓ‘tico |
+
+### SPECS No Aplican
+
+| Spec Core | RazΓ³n |
+|-----------|-------|
+| SPEC-INTEGRACION-CALENDAR | No requiere calendario de citas |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | No hay proyectos largos |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | No aplica para tickets POS |
+
+---
+
+## ORDEN DE EJECUCIΓN DDL (Futuro)
+
+```bash
+# PASO 1: Cargar ERP Core (base)
+cd apps/erp-core/database
+./scripts/reset-database.sh --force
+
+# PASO 2: Cargar extensiones de Retail
+cd apps/verticales/retail/database
+psql $DATABASE_URL -f init/00-extensions.sql
+psql $DATABASE_URL -f init/01-create-schemas.sql
+psql $DATABASE_URL -f init/02-pos-tables.sql
+psql $DATABASE_URL -f init/03-stores-tables.sql
+psql $DATABASE_URL -f init/04-pricing-tables.sql
+```
+
+---
+
+## MAPEO DE NOMENCLATURA
+
+| Core | Retail |
+|------|--------|
+| `core.partners` | Clientes, proveedores |
+| `inventory.products` | Productos de venta |
+| `inventory.locations` | Almacenes de sucursal |
+| `sales.sale_orders` | Base para POS orders |
+| `financial.invoices` | Facturas de venta |
+
+---
+
+## REFERENCIAS
+
+- ERP Core DDL: `apps/erp-core/database/ddl/`
+- ERP Core README: `apps/erp-core/database/README.md`
+- Directivas: `orchestration/directivas/`
+- Inventarios: `orchestration/inventarios/`
+
+---
+
+**Documento de herencia oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/retail/docs/00-vision-general/VISION-RETAIL.md b/projects/erp-suite/apps/verticales/retail/docs/00-vision-general/VISION-RETAIL.md
new file mode 100644
index 0000000..300a88d
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/retail/docs/00-vision-general/VISION-RETAIL.md
@@ -0,0 +1,97 @@
+# VisiΓ³n General - ERP Retail
+
+**VersiΓ³n:** 1.0
+**Fecha:** 2025-12-08
+**Nivel:** 2B.2 (Vertical)
+
+---
+
+## PropΓ³sito del Sistema
+
+Sistema ERP especializado para comercio minorista con punto de venta (POS), gestiΓ³n de inventario multi-sucursal, control de caja y programas de fidelizaciΓ³n. Optimizado para operaciΓ³n en tienda fΓsica con capacidad offline.
+
+---
+
+## Dominio del Negocio
+
+### Procesos Principales
+
+1. **Punto de Venta (POS)**
+ - Venta rΓ‘pida en mostrador
+ - MΓΊltiples mΓ©todos de pago
+ - FacturaciΓ³n CFDI 4.0
+ - OperaciΓ³n offline
+
+2. **Inventario Multi-Sucursal**
+ - Control de stock por sucursal
+ - Transferencias entre tiendas
+ - Conteos cΓclicos
+ - Alertas de reorden
+
+3. **Compras y Reabastecimiento**
+ - Γrdenes de compra centralizadas
+ - DistribuciΓ³n a sucursales
+ - Control de proveedores
+
+4. **Clientes y FidelizaciΓ³n**
+ - Programa de lealtad
+ - Puntos y recompensas
+ - Historial de compras
+
+5. **GestiΓ³n de Caja**
+ - Apertura y cierre de caja
+ - Arqueos
+ - Control de efectivo
+
+---
+
+## Arquitectura de MΓ³dulos
+
+```
+RT-001 Fundamentos β Auth, Users, Tenants (hereda 100% core)
+RT-002 POS β Punto de venta (20% core)
+RT-003 Inventario β Stock multi-sucursal (60% core)
+RT-004 Compras β Reabastecimiento (80% core)
+RT-005 Clientes β Programa fidelidad (40% core)
+RT-006 Precios β Promociones, descuentos (30% core)
+RT-007 Caja β Arqueos, cortes (10% core)
+RT-008 Reportes β Dashboard ventas (70% core)
+RT-009 E-commerce β Tienda online (20% core)
+RT-010 FacturaciΓ³n β CFDI 4.0 (60% core)
+```
+
+---
+
+## Stack TecnolΓ³gico
+
+- **Backend:** NestJS + TypeORM + PostgreSQL
+- **Frontend POS:** React + PWA (offline-first)
+- **Base de Datos:** PostgreSQL 15+ (hereda ERP Core)
+- **Hardware:** Impresora tΓ©rmica, lector de cΓ³digos, cajΓ³n
+
+---
+
+## MΓ©tricas Objetivo
+
+| MΓ©trica | Valor Objetivo |
+|---------|----------------|
+| MΓ³dulos | 10 |
+| Tablas EspecΓficas | ~30 |
+| Tablas Heredadas | ~102 |
+| Story Points Est. | ~280 |
+| Tiempo Venta | < 30 segundos |
+| Disponibilidad | 99.9% |
+
+---
+
+## Referencias
+
+- ERP Core: `apps/erp-core/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- SPECS del Core: `HERENCIA-SPECS-CORE.md`
+- Inventarios: `orchestration/inventarios/`
+
+---
+
+**Documento de visiΓ³n oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/retail/docs/02-definicion-modulos/INDICE-MODULOS.md b/projects/erp-suite/apps/verticales/retail/docs/02-definicion-modulos/INDICE-MODULOS.md
new file mode 100644
index 0000000..ada07c9
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/retail/docs/02-definicion-modulos/INDICE-MODULOS.md
@@ -0,0 +1,116 @@
+# Γndice de MΓ³dulos - ERP Retail
+
+**VersiΓ³n:** 1.0
+**Fecha:** 2025-12-08
+**Total MΓ³dulos:** 10
+
+---
+
+## Resumen
+
+| CΓ³digo | Nombre | DescripciΓ³n | ReutilizaciΓ³n Core | Estado |
+|--------|--------|-------------|-------------------|--------|
+| RT-001 | Fundamentos | Auth, Users, Tenants | 100% | PLANIFICADO |
+| RT-002 | POS | Punto de venta | 20% | PLANIFICADO |
+| RT-003 | Inventario | Stock multi-sucursal | 60% | PLANIFICADO |
+| RT-004 | Compras | Reabastecimiento | 80% | PLANIFICADO |
+| RT-005 | Clientes | Programa fidelidad | 40% | PLANIFICADO |
+| RT-006 | Precios | Promociones y descuentos | 30% | PLANIFICADO |
+| RT-007 | Caja | Arqueos y cortes | 10% | PLANIFICADO |
+| RT-008 | Reportes | Dashboard de ventas | 70% | PLANIFICADO |
+| RT-009 | E-commerce | Tienda online | 20% | PLANIFICADO |
+| RT-010 | FacturaciΓ³n | CFDI 4.0 | 60% | PLANIFICADO |
+
+---
+
+## Detalle por MΓ³dulo
+
+### RT-001: Fundamentos
+**Herencia:** 100% del core
+- Usuarios por sucursal
+- Roles: Cajero, Supervisor, Gerente, Admin
+
+### RT-002: POS
+**Herencia:** 20%
+- Venta rΓ‘pida en mostrador
+- MΓΊltiples formas de pago
+- OperaciΓ³n offline (PWA)
+- IntegraciΓ³n con hardware
+
+### RT-003: Inventario
+**Herencia:** 60%
+- Stock por sucursal
+- Transferencias entre tiendas
+- Conteos cΓclicos
+- Alertas de mΓnimos
+
+### RT-004: Compras
+**Herencia:** 80%
+- Γrdenes de compra centralizadas
+- DistribuciΓ³n a sucursales
+- Control de proveedores
+
+### RT-005: Clientes
+**Herencia:** 40%
+- Programa de lealtad
+- Puntos y recompensas
+- Historial de compras
+- MembresΓas
+
+### RT-006: Precios
+**Herencia:** 30%
+- Listas de precios
+- Promociones temporales
+- Descuentos por volumen
+- Cupones
+
+### RT-007: Caja
+**Herencia:** 10%
+- Sesiones de caja
+- Apertura/cierre
+- Arqueos
+- Movimientos de efectivo
+
+### RT-008: Reportes
+**Herencia:** 70%
+- Dashboard de ventas
+- AnΓ‘lisis por sucursal
+- Top productos
+- MΓ©tricas de cajeros
+
+### RT-009: E-commerce
+**Herencia:** 20%
+- Tienda online
+- Carrito de compras
+- Checkout
+- SincronizaciΓ³n de inventario
+
+### RT-010: FacturaciΓ³n
+**Herencia:** 60%
+- CFDI 4.0
+- Timbrado automΓ‘tico
+- Notas de crΓ©dito
+- Reportes fiscales
+
+---
+
+## Story Points Estimados
+
+| MΓ³dulo | SP Backend | SP Frontend | SP Total |
+|--------|-----------|-------------|----------|
+| RT-001 | 0 | 0 | 0 |
+| RT-002 | 34 | 21 | 55 |
+| RT-003 | 21 | 13 | 34 |
+| RT-004 | 13 | 8 | 21 |
+| RT-005 | 21 | 13 | 34 |
+| RT-006 | 21 | 13 | 34 |
+| RT-007 | 21 | 13 | 34 |
+| RT-008 | 13 | 13 | 26 |
+| RT-009 | 34 | 21 | 55 |
+| RT-010 | 21 | 8 | 29 |
+| **Total** | **199** | **123** | **322** |
+
+---
+
+**Γndice de mΓ³dulos oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/retail/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md b/projects/erp-suite/apps/verticales/retail/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
new file mode 100644
index 0000000..58041b5
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/retail/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
@@ -0,0 +1,184 @@
+# Herencia de SPECS del Core - Retail
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** Retail (RT)
+**Nivel:** 2B.2
+
+---
+
+## Resumen
+
+| MΓ©trica | Valor |
+|---------|-------|
+| SPECS Aplicables | 24/30 |
+| SPECS Obligatorias | 21 |
+| SPECS Opcionales | 3 |
+| SPECS No Aplican | 6 |
+| Estado ImplementaciΓ³n | 0% |
+
+---
+
+## SPECS Obligatorias (Deben Implementarse)
+
+### P0 - CrΓticas
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-SISTEMA-SECUENCIAS | ir.sequence | 8 | PENDIENTE | RT-001, RT-002, RT-007 |
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO | 21 | PENDIENTE | RT-003 |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL | 31 | PENDIENTE | RT-001 |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | 13 | PENDIENTE | RT-008, RT-010 |
+| SPEC-NOMINA-BASICA | hr_payroll | 21 | PENDIENTE | RT-001 |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | 13 | PENDIENTE | RT-001 |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | 8 | PENDIENTE | RT-008 |
+
+### P1 - Complementarias
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-CONTABILIDAD-ANALITICA | Centros de costo | 21 | PENDIENTE | RT-008 |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n | 21 | PENDIENTE | RT-007, RT-008 |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA | 13 | PENDIENTE | RT-001 |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes/Series | 13 | PENDIENTE | RT-003 |
+| SPEC-PRICING-RULES | Reglas precio | 8 | PENDIENTE | RT-006 |
+| SPEC-BLANKET-ORDERS | Γrdenes marco | 13 | PENDIENTE | RT-004 |
+| SPEC-INVENTARIOS-CICLICOS | Conteo cΓclico | 13 | PENDIENTE | RT-003 |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR | 8 | PENDIENTE | RT-010 |
+| SPEC-PLANTILLAS-CUENTAS | Plan contable | 8 | PENDIENTE | RT-008 |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos cambio | 5 | PENDIENTE | RT-008 |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas | 8 | PENDIENTE | RT-008 |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones | 26 | PENDIENTE | RT-001 |
+| SPEC-LOCALIZACION-PAISES | LocalizaciΓ³n | 13 | PENDIENTE | RT-001, RT-010 |
+
+### Patrones TΓ©cnicos
+
+| SPEC | PatrΓ³n | SP | Estado | AplicaciΓ³n |
+|------|--------|----:|--------|------------|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread | 13 | PENDIENTE | Γrdenes, Clientes |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | 8 | PENDIENTE | Wizards de cierre, arqueo |
+
+---
+
+## SPECS Opcionales
+
+| SPEC | DescripciΓ³n | SP | DecisiΓ³n | RazΓ³n |
+|------|-------------|----:|----------|-------|
+| SPEC-PORTAL-PROVEEDORES | Portal RFQ | 13 | EVALUAR | Para compras centralizadas |
+| SPEC-TAREAS-RECURRENTES | Recurrencia | 13 | EVALUAR | Para reorden automΓ‘tico |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n | 8 | DIFERIR | Menos relevante en retail |
+
+---
+
+## SPECS No Aplicables
+
+| SPEC | RazΓ³n |
+|------|-------|
+| SPEC-INTEGRACION-CALENDAR | No requiere calendario de citas |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | No hay proyectos largos |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | No aplica para tickets POS |
+| SPEC-OAUTH2-SOCIAL-LOGIN | El personal usa login tradicional |
+| SPEC-CONSOLIDACION-FINANCIERA | Generalmente una empresa |
+
+---
+
+## Adaptaciones Requeridas
+
+### Mapeo de Conceptos Core β Retail
+
+| Concepto Core | Concepto Retail |
+|---------------|-----------------|
+| `sales.sale_orders` | Tickets POS |
+| `inventory.products` | Productos de venta |
+| `inventory.locations` | Sucursales |
+| `inventory.stock_moves` | Transferencias entre tiendas |
+| `core.partners` | Clientes con membresΓa |
+| `financial.payments` | Pagos en caja |
+
+### Extensiones de Entidad
+
+```sql
+-- Sucursales
+stores.branches (
+ id UUID,
+ location_id β inventory.locations,
+ nombre VARCHAR,
+ direccion TEXT,
+ gerente_id β hr.employees,
+ horario JSONB,
+ activa BOOLEAN
+)
+
+-- Sesiones de caja
+pos.cash_sessions (
+ id UUID,
+ branch_id β branches,
+ cajero_id β hr.employees,
+ caja_id β cash_registers,
+ fecha_apertura TIMESTAMPTZ,
+ fecha_cierre TIMESTAMPTZ,
+ saldo_inicial DECIMAL,
+ saldo_final DECIMAL,
+ estado ENUM
+)
+
+-- Tickets POS
+pos.pos_orders (
+ id UUID,
+ session_id β cash_sessions,
+ sale_order_id β sales.sale_orders,
+ numero_ticket VARCHAR,
+ subtotal DECIMAL,
+ descuentos DECIMAL,
+ impuestos DECIMAL,
+ total DECIMAL
+)
+
+-- Programa de lealtad
+pricing.loyalty_programs (
+ id UUID,
+ nombre VARCHAR,
+ tipo ENUM('puntos', 'cashback', 'descuento'),
+ reglas JSONB,
+ activo BOOLEAN
+)
+```
+
+---
+
+## Plan de ImplementaciΓ³n
+
+### Fase 1: Fundamentos (SP: 52)
+1. SPEC-SISTEMA-SECUENCIAS
+2. SPEC-SEGURIDAD-API-KEYS-PERMISOS
+3. SPEC-TWO-FACTOR-AUTHENTICATION
+
+### Fase 2: Inventario (SP: 55)
+4. SPEC-VALORACION-INVENTARIO
+5. SPEC-TRAZABILIDAD-LOTES-SERIES
+6. SPEC-INVENTARIOS-CICLICOS
+7. SPEC-PRICING-RULES
+
+### Fase 3: Operaciones POS (SP: 21)
+8. SPEC-MAIL-THREAD-TRACKING
+9. SPEC-WIZARD-TRANSIENT-MODEL
+
+### Fase 4: Financiero (SP: 65)
+10. SPEC-REPORTES-FINANCIEROS
+11. SPEC-CONTABILIDAD-ANALITICA
+12. SPEC-CONCILIACION-BANCARIA
+13. SPEC-IMPUESTOS-AVANZADOS
+
+---
+
+## Referencias
+
+- Documento Core: `erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md`
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- Directivas: `orchestration/directivas/`
+
+---
+
+**Documento de herencia de SPECS oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/retail/orchestration/inventarios/README.md b/projects/erp-suite/apps/verticales/retail/orchestration/inventarios/README.md
new file mode 100644
index 0000000..20a7ca9
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/retail/orchestration/inventarios/README.md
@@ -0,0 +1,95 @@
+# Inventarios - ERP Retail
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Nivel SIMCO:** 2B.2
+
+---
+
+## DescripciΓ³n
+
+Este directorio contiene los inventarios YAML que sirven como **Single Source of Truth (SSOT)** para el proyecto ERP Retail. Estos archivos son la referencia canΓ³nica para mΓ©tricas, trazabilidad y componentes del sistema.
+
+---
+
+## Archivos de Inventario
+
+| Archivo | DescripciΓ³n | Estado |
+|---------|-------------|--------|
+| [MASTER_INVENTORY.yml](./MASTER_INVENTORY.yml) | Inventario maestro con mΓ©tricas globales | Completo |
+| [DATABASE_INVENTORY.yml](./DATABASE_INVENTORY.yml) | Inventario de objetos de base de datos | Planificado |
+| [BACKEND_INVENTORY.yml](./BACKEND_INVENTORY.yml) | Inventario de componentes backend | Planificado |
+| [FRONTEND_INVENTORY.yml](./FRONTEND_INVENTORY.yml) | Inventario de componentes frontend | Planificado |
+| [TRACEABILITY_MATRIX.yml](./TRACEABILITY_MATRIX.yml) | Matriz de trazabilidad RF->ET->US | Completo |
+| [DEPENDENCY_GRAPH.yml](./DEPENDENCY_GRAPH.yml) | Grafo de dependencias entre mΓ³dulos | Completo |
+
+---
+
+## Herencia del Core
+
+Este proyecto hereda del **ERP Core** (nivel 2B.1):
+
+| Aspecto | Heredado | EspecΓfico |
+|---------|----------|------------|
+| **Tablas DB** | ~100 | Planificado |
+| **Schemas** | 8+ | Planificado |
+| **Specs** | 3 | - |
+
+### Specs Heredadas
+
+1. SPEC-PRICING-RULES.md
+2. SPEC-INVENTARIOS-CICLICOS.md
+3. SPEC-TRAZABILIDAD-LOTES-SERIES.md
+
+---
+
+## Resumen Ejecutivo
+
+### MΓ©tricas del Proyecto
+
+| MΓ©trica | Valor |
+|---------|-------|
+| **MΓ³dulos** | 5 (RT-001 a RT-005) |
+| **Estado** | PLANIFICACION_COMPLETA |
+| **Completitud** | 15% |
+
+### Dominio del Negocio
+
+- Punto de venta (POS)
+- Inventario multi-sucursal
+- GestiΓ³n de precios y promociones
+- Control de cajas
+
+---
+
+## Directivas EspecΓficas
+
+1. [DIRECTIVA-PUNTO-VENTA.md](../directivas/DIRECTIVA-PUNTO-VENTA.md)
+2. [DIRECTIVA-INVENTARIO-SUCURSALES.md](../directivas/DIRECTIVA-INVENTARIO-SUCURSALES.md)
+
+---
+
+## ConfiguraciΓ³n de Puertos (Planificado)
+
+| Servicio | Puerto |
+|----------|--------|
+| Backend API | 3400 |
+| Frontend Web | 5177 |
+| POS App | 5178 |
+
+---
+
+## AlineaciΓ³n con ERP Core
+
+Estos inventarios siguen la misma estructura que:
+- `/erp-core/orchestration/inventarios/` (proyecto padre)
+
+### Referencias
+
+- Suite Master: `orchestration/inventarios/SUITE_MASTER_INVENTORY.yml`
+- Core: `apps/erp-core/orchestration/inventarios/`
+- Status Global: `orchestration/inventarios/STATUS.yml`
+
+---
+
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/database/HERENCIA-ERP-CORE.md b/projects/erp-suite/apps/verticales/vidrio-templado/database/HERENCIA-ERP-CORE.md
new file mode 100644
index 0000000..a817e75
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/database/HERENCIA-ERP-CORE.md
@@ -0,0 +1,182 @@
+# Herencia de Base de Datos - ERP Core -> Vidrio Templado
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** Vidrio Templado
+**Nivel:** 2B.2
+
+---
+
+## RESUMEN
+
+La vertical de Vidrio Templado hereda los schemas base del ERP Core y extiende con schemas especΓficos del dominio de producciΓ³n de vidrio.
+
+**UbicaciΓ³n DDL Core:** `apps/erp-core/database/ddl/`
+
+---
+
+## ARQUITECTURA DE HERENCIA
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β ERP CORE (Base) β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β β auth β β core β βfinancialβ βinventoryβ β purchase β β
+β β 26 tbl β β 12 tbl β β 15 tbl β β 15 tbl β β 8 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
+β βββββββββββ βββββββββββ βββββββββββ β
+β β sales β βanalyticsβ β system β β
+β β 6 tbl β β 5 tbl β β 10 tbl β β
+β βββββββββββ βββββββββββ βββββββββββ β
+β TOTAL: ~97 tablas heredadas β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ β HEREDA
+ βΌ
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β VIDRIO TEMPLADO (Extensiones) β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β β production β β quality β β glass β β
+β β management β β control β β inventory β β
+β β (hornos) β β (inspecciΓ³n) β β (lotes) β β
+β βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ β
+β EXTENSIONES: ~25 tablas (planificadas) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## SCHEMAS HEREDADOS DEL CORE
+
+| Schema | Tablas | Uso en Vidrio Templado |
+|--------|--------|------------------------|
+| `auth` | 26 | AutenticaciΓ³n, usuarios, roles, permisos |
+| `core` | 12 | Partners (clientes), catΓ‘logos |
+| `financial` | 15 | Facturas, cuentas contables |
+| `inventory` | 15 | Base para materia prima y producto terminado |
+| `purchase` | 8 | Compras de materiales |
+| `sales` | 6 | Cotizaciones, Γ³rdenes de venta |
+| `analytics` | 5 | Centros de costo |
+| `system` | 10 | Mensajes, notificaciones |
+
+**Total heredado:** ~97 tablas
+
+---
+
+## SCHEMAS ESPECΓFICOS DE VIDRIO TEMPLADO (Planificados)
+
+### 1. Schema `production` (estimado 10+ tablas)
+
+**PropΓ³sito:** GestiΓ³n de producciΓ³n y hornos de templado
+
+```sql
+-- Tablas principales planificadas:
+production.production_orders -- Γrdenes de producciΓ³n
+production.production_lines -- LΓneas de producciΓ³n (hornos)
+production.work_orders -- Γrdenes de trabajo
+production.cutting_plans -- Planes de corte
+production.oven_schedules -- ProgramaciΓ³n de hornos
+production.temperature_logs -- Registros de temperatura
+```
+
+### 2. Schema `quality` (estimado 8+ tablas)
+
+**PropΓ³sito:** Control de calidad y trazabilidad
+
+```sql
+-- Tablas principales planificadas:
+quality.inspections -- Inspecciones de calidad
+quality.defect_types -- CatΓ‘logo de defectos
+quality.quality_tests -- Pruebas de calidad
+quality.certifications -- Certificaciones de producto
+quality.non_conformities -- No conformidades
+```
+
+### 3. Schema `glass` (estimado 7+ tablas)
+
+**PropΓ³sito:** Inventario especializado de vidrio
+
+```sql
+-- Extiende: inventory schema del core
+glass.glass_types -- Tipos de vidrio
+glass.glass_lots -- Lotes de producciΓ³n
+glass.glass_dimensions -- Dimensiones estΓ‘ndar
+glass.raw_materials -- Materia prima
+```
+
+---
+
+## SPECS DEL CORE APLICABLES
+
+**Documento detallado:** `orchestration/00-guidelines/HERENCIA-SPECS-CORE.md`
+
+### SPECS Obligatorias
+
+| Spec Core | AplicaciΓ³n en Vidrio Templado | SP | Estado |
+|-----------|------------------------------|----:|--------|
+| SPEC-SISTEMA-SECUENCIAS | Foliado de Γ³rdenes y lotes | 8 | PENDIENTE |
+| SPEC-VALORACION-INVENTARIO | Costeo de materia prima y producto | 21 | PENDIENTE |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | Control de acceso | 31 | PENDIENTE |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes de producciΓ³n de vidrio | 13 | PENDIENTE |
+| SPEC-PRICING-RULES | Precios por dimensiones y tipo | 8 | PENDIENTE |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | Control de producciΓ³n | 13 | PENDIENTE |
+| SPEC-MAIL-THREAD-TRACKING | Historial de Γ³rdenes | 13 | PENDIENTE |
+| SPEC-WIZARD-TRANSIENT-MODEL | Wizards de corte y templado | 8 | PENDIENTE |
+
+### SPECS Opcionales
+
+| Spec Core | DecisiΓ³n | RazΓ³n |
+|-----------|----------|-------|
+| SPEC-INVENTARIOS-CICLICOS | EVALUAR | Γtil para materia prima |
+| SPEC-FIRMA-ELECTRONICA-NOM151 | EVALUAR | Certificados de calidad |
+
+### SPECS No Aplican
+
+| Spec Core | RazΓ³n |
+|-----------|-------|
+| SPEC-INTEGRACION-CALENDAR | No requiere calendario externo |
+| SPEC-CONSOLIDACION-FINANCIERA | Negocio de una sola planta |
+
+---
+
+## ORDEN DE EJECUCIΓN DDL (Futuro)
+
+```bash
+# PASO 1: Cargar ERP Core (base)
+cd apps/erp-core/database
+./scripts/reset-database.sh --force
+
+# PASO 2: Cargar extensiones de Vidrio Templado
+cd apps/verticales/vidrio-templado/database
+psql $DATABASE_URL -f init/00-extensions.sql
+psql $DATABASE_URL -f init/01-create-schemas.sql
+psql $DATABASE_URL -f init/02-production-tables.sql
+psql $DATABASE_URL -f init/03-quality-tables.sql
+psql $DATABASE_URL -f init/04-glass-inventory.sql
+```
+
+---
+
+## MAPEO DE NOMENCLATURA
+
+| Core | Vidrio Templado |
+|------|-----------------|
+| `core.partners` | Clientes, proveedores |
+| `inventory.products` | Producto terminado base |
+| `inventory.locations` | Almacenes de vidrio |
+| `sales.sale_orders` | Pedidos de vidrio |
+| `purchase.purchase_orders` | Compras de materia prima |
+
+---
+
+## REFERENCIAS
+
+- ERP Core DDL: `apps/erp-core/database/ddl/`
+- ERP Core README: `apps/erp-core/database/README.md`
+- Directivas: `orchestration/directivas/`
+- Inventarios: `orchestration/inventarios/`
+
+---
+
+**Documento de herencia oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/00-vision-general/VISION-VIDRIO.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/00-vision-general/VISION-VIDRIO.md
new file mode 100644
index 0000000..4ab1200
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/00-vision-general/VISION-VIDRIO.md
@@ -0,0 +1,104 @@
+# VisiΓ³n General - ERP Vidrio Templado
+
+**VersiΓ³n:** 1.0
+**Fecha:** 2025-12-08
+**Nivel:** 2B.2 (Vertical)
+
+---
+
+## PropΓ³sito del Sistema
+
+Sistema ERP especializado para empresas de manufactura de vidrio templado, laminado y procesado. Gestiona todo el ciclo desde la cotizaciΓ³n hasta el despacho, incluyendo control de producciΓ³n, optimizaciΓ³n de corte, control de hornos de templado y gestiΓ³n de calidad.
+
+---
+
+## Dominio del Negocio
+
+### Procesos Principales
+
+1. **CotizaciΓ³n y Ventas**
+ - CotizaciΓ³n por dimensiones, tipo de vidrio y acabados
+ - CΓ‘lculo automΓ‘tico de precios por mΒ²
+ - GestiΓ³n de clientes y arquitectos
+
+2. **ProducciΓ³n**
+ - Γrdenes de producciΓ³n
+ - OptimizaciΓ³n de corte (nesting)
+ - Control de hornos de templado
+ - ProgramaciΓ³n de producciΓ³n
+
+3. **Inventario**
+ - Control de materia prima (lΓ‘minas de vidrio)
+ - Trazabilidad de lotes
+ - GestiΓ³n de producto terminado
+
+4. **Control de Calidad**
+ - Inspecciones de producto
+ - Pruebas de fragmentaciΓ³n
+ - Certificaciones
+
+5. **Despacho**
+ - LogΓstica de entrega
+ - InstalaciΓ³n (opcional)
+
+---
+
+## Tipos de Vidrio Manejados
+
+| Tipo | DescripciΓ³n |
+|------|-------------|
+| Templado | Tratamiento tΓ©rmico para resistencia |
+| Laminado | Capas con PVB/EVA |
+| Insulado | CΓ‘maras de aire |
+| Curvo | Templado con curvatura |
+| Esmerilado | Acabado mate |
+| Serigrafiado | Con diseΓ±os impresos |
+
+---
+
+## Arquitectura de MΓ³dulos
+
+```
+VT-001 Fundamentos β Auth, Users, Tenants (hereda 100% core)
+VT-002 Cotizaciones β Cotizador de vidrio (30% core)
+VT-003 ProducciΓ³n β Γrdenes de producciΓ³n (20% core)
+VT-004 Inventario β Stock de vidrio (70% core)
+VT-005 Corte β OptimizaciΓ³n de corte (0% core - nuevo)
+VT-006 Templado β Control de hornos (0% core - nuevo)
+VT-007 Calidad β Inspecciones, QC (40% core)
+VT-008 Despacho β LogΓstica (50% core)
+```
+
+---
+
+## Stack TecnolΓ³gico
+
+- **Backend:** NestJS + TypeORM + PostgreSQL
+- **Frontend:** React + TypeScript + Vite
+- **Base de Datos:** PostgreSQL 15+ (hereda ERP Core)
+- **Extensiones:** PostGIS (dimensiones)
+
+---
+
+## MΓ©tricas Objetivo
+
+| MΓ©trica | Valor Objetivo |
+|---------|----------------|
+| MΓ³dulos | 8 |
+| Tablas EspecΓficas | ~25 |
+| Tablas Heredadas | ~97 |
+| Story Points Est. | ~200 |
+
+---
+
+## Referencias
+
+- ERP Core: `apps/erp-core/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- SPECS del Core: `HERENCIA-SPECS-CORE.md`
+- Inventarios: `orchestration/inventarios/`
+
+---
+
+**Documento de visiΓ³n oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/INDICE-MODULOS.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/INDICE-MODULOS.md
new file mode 100644
index 0000000..eaa3914
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/INDICE-MODULOS.md
@@ -0,0 +1,154 @@
+# Γndice de MΓ³dulos - ERP Vidrio Templado
+
+**VersiΓ³n:** 1.0
+**Fecha:** 2025-12-08
+**Total MΓ³dulos:** 8
+
+---
+
+## Resumen
+
+| CΓ³digo | Nombre | DescripciΓ³n | ReutilizaciΓ³n Core | Estado |
+|--------|--------|-------------|-------------------|--------|
+| VT-001 | Fundamentos | Auth, Users, Tenants | 100% | PLANIFICADO |
+| VT-002 | Cotizaciones | Cotizador de vidrio | 30% | PLANIFICADO |
+| VT-003 | ProducciΓ³n | Γrdenes de producciΓ³n | 20% | PLANIFICADO |
+| VT-004 | Inventario | Stock de vidrio y materia prima | 70% | PLANIFICADO |
+| VT-005 | Corte | OptimizaciΓ³n de corte | 0% | PLANIFICADO |
+| VT-006 | Templado | Control de hornos | 0% | PLANIFICADO |
+| VT-007 | Calidad | Control de calidad | 40% | PLANIFICADO |
+| VT-008 | Despacho | LogΓstica y entregas | 50% | PLANIFICADO |
+
+---
+
+## Detalle por MΓ³dulo
+
+### VT-001: Fundamentos
+
+**Herencia:** 100% del core (MGN-001 a MGN-004)
+**PropΓ³sito:** AutenticaciΓ³n, usuarios, roles, multi-tenancy
+
+- Usuarios del sistema (operadores, supervisores, gerentes)
+- Roles y permisos por planta
+- Multi-tenancy para franquicias
+
+### VT-002: Cotizaciones
+
+**Herencia:** 30% del core (sales)
+**PropΓ³sito:** CotizaciΓ³n de productos de vidrio
+
+- Cotizador por dimensiones (alto Γ ancho)
+- Tipos de vidrio y espesores
+- CΓ‘lculo de precios por mΒ²
+- Acabados y procesamientos adicionales
+- GeneraciΓ³n de PDF para cliente
+
+### VT-003: ProducciΓ³n
+
+**Herencia:** 20% del core (projects)
+**PropΓ³sito:** GestiΓ³n de Γ³rdenes de producciΓ³n
+
+- Γrdenes de producciΓ³n
+- Estados: borrador β programado β corte β templado β QC β terminado
+- AsignaciΓ³n de recursos
+- Tiempos de producciΓ³n
+
+### VT-004: Inventario
+
+**Herencia:** 70% del core (inventory)
+**PropΓ³sito:** Control de materia prima y producto terminado
+
+- LΓ‘minas de vidrio (materia prima)
+- Control de lotes por proveedor
+- Producto terminado
+- Merma y desperdicio
+- Alertas de reorden
+
+### VT-005: Corte
+
+**Herencia:** 0% - MΓ³dulo nuevo
+**PropΓ³sito:** OptimizaciΓ³n de corte de vidrio
+
+- Algoritmo de nesting para optimizar cortes
+- Planes de corte
+- ReducciΓ³n de desperdicio
+- IntegraciΓ³n con mΓ‘quinas CNC (futuro)
+
+### VT-006: Templado
+
+**Herencia:** 0% - MΓ³dulo nuevo
+**PropΓ³sito:** Control de hornos de templado
+
+- ProgramaciΓ³n de hornos
+- ParΓ‘metros de templado (temperatura, tiempo, velocidad)
+- Registro de ciclos de templado
+- Mantenimiento preventivo de hornos
+
+### VT-007: Calidad
+
+**Herencia:** 40% del core (system)
+**PropΓ³sito:** Control de calidad
+
+- Inspecciones de producto
+- Pruebas de fragmentaciΓ³n
+- No conformidades
+- Certificaciones de producto
+- Trazabilidad de defectos
+
+### VT-008: Despacho
+
+**Herencia:** 50% del core (inventory, sales)
+**PropΓ³sito:** LogΓstica de entregas
+
+- ProgramaciΓ³n de entregas
+- Rutas de entrega
+- ConfirmaciΓ³n de recepciΓ³n
+- InstalaciΓ³n (opcional)
+- Evidencia fotogrΓ‘fica
+
+---
+
+## Dependencias entre MΓ³dulos
+
+```
+VT-001 (Fundamentos)
+ β
+VT-002 (Cotizaciones) ββ VT-004 (Inventario)
+ β
+VT-003 (ProducciΓ³n)
+ β
+VT-005 (Corte) β VT-006 (Templado)
+ β
+ VT-007 (Calidad)
+ β
+ VT-008 (Despacho)
+```
+
+---
+
+## Story Points Estimados
+
+| MΓ³dulo | SP Backend | SP Frontend | SP Total |
+|--------|-----------|-------------|----------|
+| VT-001 | 0 (hereda) | 0 (hereda) | 0 |
+| VT-002 | 21 | 13 | 34 |
+| VT-003 | 21 | 13 | 34 |
+| VT-004 | 13 | 8 | 21 |
+| VT-005 | 34 | 13 | 47 |
+| VT-006 | 21 | 13 | 34 |
+| VT-007 | 13 | 8 | 21 |
+| VT-008 | 13 | 8 | 21 |
+| **Total** | **136** | **76** | **212** |
+
+---
+
+## Referencias
+
+- DocumentaciΓ³n por mΓ³dulo: `VT-XXX-nombre/README.md`
+- SPECS heredadas: `orchestration/00-guidelines/HERENCIA-SPECS-CORE.md`
+- VisiΓ³n: `00-vision-general/VISION-VIDRIO.md`
+
+---
+
+**Γndice de mΓ³dulos oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-001-fundamentos/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-001-fundamentos/README.md
new file mode 100644
index 0000000..16fe998
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-001-fundamentos/README.md
@@ -0,0 +1,21 @@
+# VT-001: Fundamentos
+
+**MΓ³dulo:** Fundamentos
+**Herencia:** 100% del ERP Core
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+MΓ³dulo base que hereda completamente del ERP Core. Proporciona autenticaciΓ³n, gestiΓ³n de usuarios, roles y multi-tenancy.
+
+## Componentes Heredados
+- MGN-001: Auth (JWT, OAuth2, 2FA)
+- MGN-002: Users (CRUD, perfiles)
+- MGN-003: Roles (RBAC)
+- MGN-004: Tenants (Multi-tenancy, RLS)
+
+## ConfiguraciΓ³n EspecΓfica
+- Roles por defecto: Operador, Supervisor, Gerente, Administrador
+- Permisos por mΓ³dulo de vidrio
+
+## Referencias
+- ERP Core: `apps/erp-core/`
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-002-cotizaciones/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-002-cotizaciones/README.md
new file mode 100644
index 0000000..d827ed3
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-002-cotizaciones/README.md
@@ -0,0 +1,26 @@
+# VT-002: Cotizaciones
+
+**MΓ³dulo:** Cotizaciones de Vidrio
+**Herencia:** 30% del ERP Core (sales)
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+Cotizador especializado para productos de vidrio. Calcula precios por dimensiones, tipo de vidrio, espesor y acabados.
+
+## Funcionalidades
+- CotizaciΓ³n por dimensiones (alto Γ ancho Γ espesor)
+- CatΓ‘logo de tipos de vidrio
+- Acabados y procesamientos adicionales
+- CΓ‘lculo automΓ‘tico de precios por mΒ²
+- GeneraciΓ³n de PDF
+- ConversiΓ³n a orden de producciΓ³n
+
+## Entidades
+- `quotes.quotes` - Cotizaciones
+- `quotes.quote_lines` - LΓneas de cotizaciΓ³n
+- `quotes.glass_types` - Tipos de vidrio
+- `quotes.finishes` - Acabados disponibles
+
+## SPECS Aplicables
+- SPEC-PRICING-RULES
+- SPEC-MAIL-THREAD-TRACKING
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-003-produccion/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-003-produccion/README.md
new file mode 100644
index 0000000..c1134fb
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-003-produccion/README.md
@@ -0,0 +1,33 @@
+# VT-003: ProducciΓ³n
+
+**MΓ³dulo:** Γrdenes de ProducciΓ³n
+**Herencia:** 20% del ERP Core (projects)
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+GestiΓ³n de Γ³rdenes de producciΓ³n desde la cotizaciΓ³n aprobada hasta el producto terminado.
+
+## Funcionalidades
+- CreaciΓ³n de Γ³rdenes desde cotizaciones
+- Estados de producciΓ³n
+- AsignaciΓ³n de recursos
+- ProgramaciΓ³n de producciΓ³n
+- Seguimiento de tiempos
+
+## Estados del Flujo
+1. `draft` - Borrador
+2. `scheduled` - Programado
+3. `cutting` - En corte
+4. `tempering` - En templado
+5. `quality` - Control de calidad
+6. `done` - Terminado
+7. `delivered` - Entregado
+
+## Entidades
+- `production.production_orders` - Γrdenes de producciΓ³n
+- `production.production_lines` - LΓneas de horno
+- `production.work_orders` - Γrdenes de trabajo
+
+## SPECS Aplicables
+- SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN
+- SPEC-TAREAS-RECURRENTES
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-004-inventario/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-004-inventario/README.md
new file mode 100644
index 0000000..3972aaa
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-004-inventario/README.md
@@ -0,0 +1,27 @@
+# VT-004: Inventario
+
+**MΓ³dulo:** Inventario de Vidrio
+**Herencia:** 70% del ERP Core (inventory)
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+Control de materia prima (lΓ‘minas de vidrio) y producto terminado con trazabilidad de lotes.
+
+## Funcionalidades
+- Control de lΓ‘minas de materia prima
+- Trazabilidad de lotes por proveedor
+- Producto terminado
+- Control de merma y desperdicio
+- Alertas de reorden
+- ValorizaciΓ³n FIFO/AVCO
+
+## Entidades
+- `glass.glass_inventory` - Inventario de vidrio
+- `glass.glass_lots` - Lotes de materia prima
+- `glass.raw_materials` - LΓ‘minas de vidrio
+- `glass.finished_products` - Producto terminado
+
+## SPECS Aplicables
+- SPEC-VALORACION-INVENTARIO
+- SPEC-TRAZABILIDAD-LOTES-SERIES
+- SPEC-INVENTARIOS-CICLICOS (opcional)
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-005-corte/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-005-corte/README.md
new file mode 100644
index 0000000..a6714bc
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-005-corte/README.md
@@ -0,0 +1,26 @@
+# VT-005: Corte
+
+**MΓ³dulo:** OptimizaciΓ³n de Corte
+**Herencia:** 0% - MΓ³dulo nuevo
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+MΓ³dulo especializado para optimizaciΓ³n de cortes de vidrio (nesting) que minimiza el desperdicio de materia prima.
+
+## Funcionalidades
+- Algoritmo de nesting para optimizar cortes
+- Planes de corte por lΓ‘mina
+- CΓ‘lculo de desperdicio
+- VisualizaciΓ³n de patrones de corte
+- IntegraciΓ³n con CNC (futuro)
+- HistΓ³rico de eficiencia
+
+## Entidades
+- `cutting.cutting_plans` - Planes de corte
+- `cutting.cutting_patterns` - Patrones optimizados
+- `cutting.waste_records` - Registro de desperdicio
+
+## Algoritmos
+- First Fit Decreasing (FFD)
+- Guillotine cuts
+- OptimizaciΓ³n por rotaciΓ³n de piezas
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-006-templado/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-006-templado/README.md
new file mode 100644
index 0000000..a12e964
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-006-templado/README.md
@@ -0,0 +1,28 @@
+# VT-006: Templado
+
+**MΓ³dulo:** Control de Hornos
+**Herencia:** 0% - MΓ³dulo nuevo
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+Control de hornos de templado con registro de parΓ‘metros y ciclos de producciΓ³n.
+
+## Funcionalidades
+- ProgramaciΓ³n de hornos
+- Registro de parΓ‘metros (temperatura, tiempo, velocidad)
+- Ciclos de templado por tipo de vidrio
+- Registro de logs de producciΓ³n
+- Mantenimiento preventivo
+- Alertas de parΓ‘metros fuera de rango
+
+## Entidades
+- `tempering.ovens` - Hornos de templado
+- `tempering.oven_schedules` - ProgramaciΓ³n
+- `tempering.tempering_cycles` - Ciclos de templado
+- `tempering.temperature_logs` - Logs de temperatura
+- `tempering.maintenance_records` - Mantenimientos
+
+## ParΓ‘metros de Control
+- Temperatura de calentamiento: 620-720Β°C
+- Tiempo en horno: segΓΊn espesor
+- Velocidad de enfriamiento: presiΓ³n de aire
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-007-calidad/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-007-calidad/README.md
new file mode 100644
index 0000000..cb69ed4
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-007-calidad/README.md
@@ -0,0 +1,28 @@
+# VT-007: Calidad
+
+**MΓ³dulo:** Control de Calidad
+**Herencia:** 40% del ERP Core (system)
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+Control de calidad para producto de vidrio templado, incluyendo inspecciones, pruebas de fragmentaciΓ³n y certificaciones.
+
+## Funcionalidades
+- Inspecciones de producto
+- Pruebas de fragmentaciΓ³n (NMX-R-2-1989)
+- Registro de no conformidades
+- Certificaciones de producto
+- Trazabilidad de defectos
+- Reportes de calidad
+
+## Entidades
+- `quality.inspections` - Inspecciones
+- `quality.fragmentation_tests` - Pruebas de fragmentaciΓ³n
+- `quality.non_conformities` - No conformidades
+- `quality.certifications` - Certificaciones
+- `quality.defect_types` - Tipos de defectos
+
+## Criterios de AceptaciΓ³n
+- FragmentaciΓ³n: mΓn 40 partΓculas en 5Γ5cm
+- Defectos visuales: segΓΊn tolerancias
+- Dimensiones: Β±2mm
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-008-despacho/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-008-despacho/README.md
new file mode 100644
index 0000000..9199f4d
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/02-definicion-modulos/VT-008-despacho/README.md
@@ -0,0 +1,31 @@
+# VT-008: Despacho
+
+**MΓ³dulo:** Despacho y LogΓstica
+**Herencia:** 50% del ERP Core (inventory, sales)
+**Estado:** PLANIFICADO
+
+## DescripciΓ³n
+GestiΓ³n de entregas de producto terminado, incluyendo rutas, confirmaciones y evidencia.
+
+## Funcionalidades
+- ProgramaciΓ³n de entregas
+- AsignaciΓ³n de rutas
+- ConfirmaciΓ³n de recepciΓ³n
+- Evidencia fotogrΓ‘fica
+- InstalaciΓ³n (opcional)
+- Actas de entrega
+
+## Entidades
+- `delivery.deliveries` - Entregas
+- `delivery.delivery_lines` - LΓneas de entrega
+- `delivery.routes` - Rutas
+- `delivery.confirmations` - Confirmaciones
+- `delivery.installations` - Instalaciones
+
+## Flujo de Entrega
+1. ProgramaciΓ³n de entrega
+2. AsignaciΓ³n de ruta y vehΓculo
+3. Carga de producto
+4. Entrega en sitio
+5. ConfirmaciΓ³n con evidencia
+6. Cierre de entrega
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/docs/08-epicas/EPIC-VT-001-fundamentos.md b/projects/erp-suite/apps/verticales/vidrio-templado/docs/08-epicas/EPIC-VT-001-fundamentos.md
new file mode 100644
index 0000000..b2700f7
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/docs/08-epicas/EPIC-VT-001-fundamentos.md
@@ -0,0 +1,65 @@
+# Γpica: Fundamentos del Sistema
+
+**CΓ³digo:** EPIC-VT-001
+**MΓ³dulos:** VT-001 a VT-002
+**Estado:** PLANIFICADO
+
+---
+
+## DescripciΓ³n
+
+ImplementaciΓ³n de los mΓ³dulos fundacionales del ERP Vidrio Templado, incluyendo la configuraciΓ³n inicial del sistema heredado del core y el mΓ³dulo de cotizaciones.
+
+---
+
+## Objetivos
+
+1. Configurar el ambiente de desarrollo heredando del ERP Core
+2. Implementar el cotizador de vidrio con cΓ‘lculo por mΒ²
+3. Establecer el catΓ‘logo de tipos de vidrio y acabados
+
+---
+
+## MΓ³dulos Incluidos
+
+| MΓ³dulo | DescripciΓ³n | SP Estimados |
+|--------|-------------|--------------|
+| VT-001 | Fundamentos (hereda core) | 0 |
+| VT-002 | Cotizaciones | 34 |
+
+---
+
+## User Stories Principales
+
+1. Como usuario, quiero iniciar sesiΓ³n en el sistema de vidrio templado
+2. Como vendedor, quiero crear una cotizaciΓ³n de vidrio por dimensiones
+3. Como vendedor, quiero calcular el precio automΓ‘tico por mΒ²
+4. Como vendedor, quiero generar un PDF de cotizaciΓ³n para el cliente
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] Sistema de autenticaciΓ³n funcional (heredado)
+- [ ] CRUD de cotizaciones implementado
+- [ ] CΓ‘lculo de precios por dimensiones correcto
+- [ ] GeneraciΓ³n de PDF funcional
+- [ ] CatΓ‘logo de tipos de vidrio completo
+
+---
+
+## Dependencias
+
+- ERP Core instalado y funcional
+- Base de datos configurada con schemas heredados
+
+---
+
+## Story Points Totales
+
+**34 SP** (excluyendo fundamentos heredados)
+
+---
+
+**Γpica fundacional**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md b/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
new file mode 100644
index 0000000..e5e5943
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/00-guidelines/HERENCIA-SPECS-CORE.md
@@ -0,0 +1,175 @@
+# Herencia de SPECS del Core - Vidrio Templado
+
+**Fecha:** 2025-12-08
+**VersiΓ³n:** 1.0
+**Vertical:** Vidrio Templado (VT)
+**Nivel:** 2B.2
+
+---
+
+## Resumen
+
+| MΓ©trica | Valor |
+|---------|-------|
+| SPECS Aplicables | 25/30 |
+| SPECS Obligatorias | 22 |
+| SPECS Opcionales | 3 |
+| SPECS No Aplican | 5 |
+| Estado ImplementaciΓ³n | 0% |
+
+---
+
+## SPECS Obligatorias (Deben Implementarse)
+
+### P0 - CrΓticas
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-SISTEMA-SECUENCIAS | ir.sequence | 8 | PENDIENTE | VT-001, VT-002 |
+| SPEC-VALORACION-INVENTARIO | FIFO/AVCO | 21 | PENDIENTE | VT-004 |
+| SPEC-SEGURIDAD-API-KEYS-PERMISOS | API Keys + ACL | 31 | PENDIENTE | VT-001 |
+| SPEC-REPORTES-FINANCIEROS | Balance/P&L SAT | 13 | PENDIENTE | VT-008 |
+| SPEC-PORTAL-PROVEEDORES | Portal RFQ | 13 | PENDIENTE | VT-004 |
+| SPEC-NOMINA-BASICA | hr_payroll | 21 | PENDIENTE | VT-001 |
+| SPEC-GASTOS-EMPLEADOS | hr_expense | 13 | PENDIENTE | VT-001 |
+| SPEC-TAREAS-RECURRENTES | project.task.recurrence | 13 | PENDIENTE | VT-003 |
+| SPEC-SCHEDULER-REPORTES | ir.cron + mail | 8 | PENDIENTE | VT-008 |
+
+### P1 - Complementarias
+
+| SPEC | Gap Original | SP | Estado | MΓ³dulos Afectados |
+|------|-------------|----:|--------|-------------------|
+| SPEC-CONTABILIDAD-ANALITICA | Centros de costo | 21 | PENDIENTE | VT-008 |
+| SPEC-CONCILIACION-BANCARIA | ConciliaciΓ³n | 21 | PENDIENTE | VT-008 |
+| SPEC-TWO-FACTOR-AUTHENTICATION | 2FA | 13 | PENDIENTE | VT-001 |
+| SPEC-TRAZABILIDAD-LOTES-SERIES | Lotes/Series | 13 | PENDIENTE | VT-004, VT-007 |
+| SPEC-PRICING-RULES | Reglas precio | 8 | PENDIENTE | VT-002 |
+| SPEC-BLANKET-ORDERS | Γrdenes marco | 13 | PENDIENTE | VT-004 |
+| SPEC-IMPUESTOS-AVANZADOS | IVA, ISR | 8 | PENDIENTE | VT-008 |
+| SPEC-PLANTILLAS-CUENTAS | Plan contable | 8 | PENDIENTE | VT-008 |
+| SPEC-TASAS-CAMBIO-AUTOMATICAS | Tipos cambio | 5 | PENDIENTE | VT-008 |
+| SPEC-ALERTAS-PRESUPUESTO | Alertas | 8 | PENDIENTE | VT-002, VT-003 |
+| SPEC-PRESUPUESTOS-REVISIONES | AprobaciΓ³n | 8 | PENDIENTE | VT-002 |
+| SPEC-RRHH-EVALUACIONES-SKILLS | Evaluaciones | 26 | PENDIENTE | VT-001 |
+| SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN | Burndown | 13 | PENDIENTE | VT-003 |
+| SPEC-LOCALIZACION-PAISES | LocalizaciΓ³n | 13 | PENDIENTE | VT-001 |
+
+### Patrones TΓ©cnicos
+
+| SPEC | PatrΓ³n | SP | Estado | AplicaciΓ³n |
+|------|--------|----:|--------|------------|
+| SPEC-MAIL-THREAD-TRACKING | mail.thread | 13 | PENDIENTE | Γrdenes producciΓ³n, Cotizaciones |
+| SPEC-WIZARD-TRANSIENT-MODEL | TransientModel | 8 | PENDIENTE | Wizards de corte, templado |
+
+---
+
+## SPECS Opcionales
+
+| SPEC | DescripciΓ³n | SP | DecisiΓ³n | RazΓ³n |
+|------|-------------|----:|----------|-------|
+| SPEC-FIRMA-ELECTRONICA-NOM151 | e.firma | 13 | EVALUAR | Para certificados de calidad |
+| SPEC-OAUTH2-SOCIAL-LOGIN | OAuth2 | 8 | DIFERIR | No prioritario |
+| SPEC-INVENTARIOS-CICLICOS | Conteo cΓclico | 13 | EVALUAR | Γtil para materia prima |
+
+---
+
+## SPECS No Aplicables
+
+| SPEC | RazΓ³n |
+|------|-------|
+| SPEC-INTEGRACION-CALENDAR | No requiere calendario externo |
+| SPEC-CONSOLIDACION-FINANCIERA | Negocio de una sola planta |
+
+---
+
+## Adaptaciones Requeridas
+
+### Mapeo de Conceptos Core β Vidrio
+
+| Concepto Core | Concepto Vidrio |
+|---------------|-----------------|
+| `sales.sale_orders` | Pedidos de vidrio |
+| `inventory.products` | Tipos de vidrio (templado, laminado, etc.) |
+| `inventory.lots` | Lotes de producciΓ³n |
+| `projects.projects` | Γrdenes de producciΓ³n |
+| `projects.tasks` | Etapas (corte, templado, inspecciΓ³n) |
+
+### Extensiones de Entidad
+
+```sql
+-- Tipos de vidrio
+glass.glass_types (
+ product_id β inventory.products,
+ tipo ENUM('templado', 'laminado', 'insulado', 'curvo'),
+ espesor_mm DECIMAL,
+ color VARCHAR,
+ propiedades JSONB
+)
+
+-- Γrdenes de producciΓ³n
+production.production_orders (
+ id UUID,
+ sale_order_id β sales.sale_orders,
+ tipo_vidrio_id β glass_types,
+ dimensiones JSONB,
+ cantidad INTEGER,
+ estado ENUM
+)
+
+-- ParΓ‘metros de horno
+production.oven_parameters (
+ production_order_id β production_orders,
+ temperatura_c INTEGER,
+ tiempo_minutos INTEGER,
+ velocidad_enfriamiento DECIMAL,
+ fecha_templado TIMESTAMPTZ
+)
+
+-- Inspecciones de calidad
+quality.inspections (
+ id UUID,
+ production_order_id β production_orders,
+ tipo_inspeccion ENUM,
+ resultado ENUM('aprobado', 'rechazado', 'condicional'),
+ observaciones TEXT
+)
+```
+
+---
+
+## Plan de ImplementaciΓ³n
+
+### Fase 1: Fundamentos (SP: 52)
+1. SPEC-SISTEMA-SECUENCIAS
+2. SPEC-SEGURIDAD-API-KEYS-PERMISOS
+3. SPEC-TWO-FACTOR-AUTHENTICATION
+
+### Fase 2: ProducciΓ³n (SP: 55)
+4. SPEC-VALORACION-INVENTARIO
+5. SPEC-TRAZABILIDAD-LOTES-SERIES
+6. SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN
+7. SPEC-PRICING-RULES
+
+### Fase 3: Operaciones (SP: 34)
+8. SPEC-MAIL-THREAD-TRACKING
+9. SPEC-WIZARD-TRANSIENT-MODEL
+10. SPEC-TAREAS-RECURRENTES
+
+### Fase 4: Financiero (SP: 65)
+11. SPEC-REPORTES-FINANCIEROS
+12. SPEC-CONTABILIDAD-ANALITICA
+13. SPEC-CONCILIACION-BANCARIA
+
+---
+
+## Referencias
+
+- Documento Core: `erp-core/docs/04-modelado/MAPEO-SPECS-VERTICALES.md`
+- SPECS del Core: `erp-core/docs/04-modelado/especificaciones-tecnicas/transversal/`
+- Herencia DB: `database/HERENCIA-ERP-CORE.md`
+- Directivas: `orchestration/directivas/`
+
+---
+
+**Documento de herencia de SPECS oficial**
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/inventarios/README.md b/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/inventarios/README.md
new file mode 100644
index 0000000..e52b12e
--- /dev/null
+++ b/projects/erp-suite/apps/verticales/vidrio-templado/orchestration/inventarios/README.md
@@ -0,0 +1,94 @@
+# Inventarios - ERP Vidrio Templado
+
+**Version:** 1.0.0
+**Fecha:** 2025-12-08
+**Nivel SIMCO:** 2B.2
+
+---
+
+## DescripciΓ³n
+
+Este directorio contiene los inventarios YAML que sirven como **Single Source of Truth (SSOT)** para el proyecto ERP Vidrio Templado. Estos archivos son la referencia canΓ³nica para mΓ©tricas, trazabilidad y componentes del sistema.
+
+---
+
+## Archivos de Inventario
+
+| Archivo | DescripciΓ³n | Estado |
+|---------|-------------|--------|
+| [MASTER_INVENTORY.yml](./MASTER_INVENTORY.yml) | Inventario maestro con mΓ©tricas globales | Completo |
+| [DATABASE_INVENTORY.yml](./DATABASE_INVENTORY.yml) | Inventario de objetos de base de datos | Planificado |
+| [BACKEND_INVENTORY.yml](./BACKEND_INVENTORY.yml) | Inventario de componentes backend | Planificado |
+| [FRONTEND_INVENTORY.yml](./FRONTEND_INVENTORY.yml) | Inventario de componentes frontend | Planificado |
+| [TRACEABILITY_MATRIX.yml](./TRACEABILITY_MATRIX.yml) | Matriz de trazabilidad RF->ET->US | Completo |
+| [DEPENDENCY_GRAPH.yml](./DEPENDENCY_GRAPH.yml) | Grafo de dependencias entre mΓ³dulos | Completo |
+
+---
+
+## Herencia del Core
+
+Este proyecto hereda del **ERP Core** (nivel 2B.1):
+
+| Aspecto | Heredado | EspecΓfico |
+|---------|----------|------------|
+| **Tablas DB** | ~100 | Planificado |
+| **Schemas** | 8+ | Planificado |
+| **Specs** | 3 | - |
+
+### Specs Heredadas
+
+1. SPEC-VALORACION-INVENTARIO.md
+2. SPEC-TRAZABILIDAD-LOTES-SERIES.md
+3. SPEC-INVENTARIOS-CICLICOS.md
+
+---
+
+## Resumen Ejecutivo
+
+### MΓ©tricas del Proyecto
+
+| MΓ©trica | Valor |
+|---------|-------|
+| **MΓ³dulos** | 5 (VT-001 a VT-005) |
+| **Estado** | PLANIFICACION_COMPLETA |
+| **Completitud** | 15% |
+
+### Dominio del Negocio
+
+- ProducciΓ³n de vidrio templado
+- Control de calidad
+- Trazabilidad de lotes
+- GestiΓ³n de hornos y procesos
+
+---
+
+## Directivas EspecΓficas
+
+1. [DIRECTIVA-PRODUCCION-VIDRIO.md](../directivas/DIRECTIVA-PRODUCCION-VIDRIO.md)
+2. [DIRECTIVA-CONTROL-CALIDAD.md](../directivas/DIRECTIVA-CONTROL-CALIDAD.md)
+
+---
+
+## ConfiguraciΓ³n de Puertos (Planificado)
+
+| Servicio | Puerto |
+|----------|--------|
+| Backend API | 3300 |
+| Frontend Web | 5176 |
+
+---
+
+## AlineaciΓ³n con ERP Core
+
+Estos inventarios siguen la misma estructura que:
+- `/erp-core/orchestration/inventarios/` (proyecto padre)
+
+### Referencias
+
+- Suite Master: `orchestration/inventarios/SUITE_MASTER_INVENTORY.yml`
+- Core: `apps/erp-core/orchestration/inventarios/`
+- Status Global: `orchestration/inventarios/STATUS.yml`
+
+---
+
+**Γltima actualizaciΓ³n:** 2025-12-08
diff --git a/projects/erp-suite/orchestration/inventarios/REFERENCIAS.yml b/projects/erp-suite/orchestration/inventarios/REFERENCIAS.yml
index 97d96ac..61e7ad5 100644
--- a/projects/erp-suite/orchestration/inventarios/REFERENCIAS.yml
+++ b/projects/erp-suite/orchestration/inventarios/REFERENCIAS.yml
@@ -123,39 +123,114 @@ referencias_erp_core:
referencias_verticales:
construccion:
ubicacion_base: apps/verticales/construccion/
- documentacion: docs/
+ nivel: 2B.2
+ estado: EN_DESARROLLO
+ completitud: 40%
+ documentacion: docs/ (449 archivos)
orchestration: orchestration/
- total_archivos: 403
-
- vidrio_templado:
- ubicacion_base: apps/verticales/vidrio-templado/
- documentacion: docs/
- orchestration: orchestration/
- estado: estructura_base
+ inventarios:
+ ubicacion: orchestration/inventarios/
+ archivos: 6
+ readme: true
+ database:
+ ubicacion: database/
+ herencia: database/HERENCIA-ERP-CORE.md
+ ddl_implementado: true
+ tablas_especificas: 33
+ backend:
+ porcentaje: 15%
+ entities: 12
+ services: 2
+ controllers: 2
+ directivas:
+ - directivas/DIRECTIVA-CONTROL-OBRA.md
+ - directivas/DIRECTIVA-ESTIMACIONES.md
+ - directivas/DIRECTIVA-INTEGRACION-INFONAVIT.md
mecanicas_diesel:
ubicacion_base: apps/verticales/mecanicas-diesel/
+ nivel: 2B.2
+ estado: DDL_IMPLEMENTADO
+ completitud: 20%
+ documentacion: docs/ (75 archivos)
+ orchestration: orchestration/
+ inventarios:
+ ubicacion: orchestration/inventarios/
+ archivos: 6
+ readme: true
+ database:
+ ubicacion: database/
+ herencia: database/HERENCIA-ERP-CORE.md
+ ddl_implementado: true
+ lineas_sql: 1561
+ directivas:
+ - directivas/DIRECTIVA-ORDENES-TRABAJO.md
+ - directivas/DIRECTIVA-INVENTARIO-REFACCIONES.md
+
+ vidrio_templado:
+ ubicacion_base: apps/verticales/vidrio-templado/
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
documentacion: docs/
orchestration: orchestration/
- estado: estructura_base
+ inventarios:
+ ubicacion: orchestration/inventarios/
+ archivos: 6
+ readme: true
+ database:
+ ubicacion: database/
+ herencia: database/HERENCIA-ERP-CORE.md
+ ddl_implementado: false
+ directivas:
+ - directivas/DIRECTIVA-PRODUCCION-VIDRIO.md
+ - directivas/DIRECTIVA-CONTROL-CALIDAD.md
retail:
ubicacion_base: apps/verticales/retail/
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
documentacion: docs/
orchestration: orchestration/
- estado: estructura_base
+ inventarios:
+ ubicacion: orchestration/inventarios/
+ archivos: 6
+ readme: true
+ database:
+ ubicacion: database/
+ herencia: database/HERENCIA-ERP-CORE.md
+ ddl_implementado: false
+ directivas:
+ - directivas/DIRECTIVA-PUNTO-VENTA.md
+ - directivas/DIRECTIVA-INVENTARIO-SUCURSALES.md
clinicas:
ubicacion_base: apps/verticales/clinicas/
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
documentacion: docs/
orchestration: orchestration/
- estado: estructura_base
+ inventarios:
+ ubicacion: orchestration/inventarios/
+ archivos: 6
+ readme: true
+ database:
+ ubicacion: database/
+ herencia: database/HERENCIA-ERP-CORE.md
+ ddl_implementado: false
+ directivas:
+ - directivas/DIRECTIVA-EXPEDIENTE-CLINICO.md
+ - directivas/DIRECTIVA-GESTION-CITAS.md
# ============================================================================
# MATRIZ DE HERENCIA (Verticales -> Core)
# ============================================================================
herencia_verticales:
descripcion: "Especificaciones del core que cada vertical debe heredar"
+ fecha_propagacion: 2025-12-08
+ estado_propagacion: COMPLETO
construccion:
specs_heredables:
@@ -165,32 +240,92 @@ herencia_verticales:
- SPEC-VALORACION-INVENTARIO.md
- SPEC-TRAZABILIDAD-LOTES-SERIES.md
- SPEC-TAREAS-RECURRENTES.md
- documentado: false
-
- vidrio_templado:
- specs_heredables:
- - SPEC-VALORACION-INVENTARIO.md
- - SPEC-TRAZABILIDAD-LOTES-SERIES.md
- - SPEC-INVENTARIOS-CICLICOS.md
- documentado: false
+ documentado: true
+ documento_herencia: apps/verticales/construccion/database/HERENCIA-ERP-CORE.md
+ tablas_heredadas: 124
+ tablas_especificas: 33
mecanicas_diesel:
specs_heredables:
- SPEC-VALORACION-INVENTARIO.md
- SPEC-TRAZABILIDAD-LOTES-SERIES.md
- SPEC-INVENTARIOS-CICLICOS.md
- documentado: false
+ - SPEC-MAIL-THREAD-TRACKING.md
+ - SPEC-TAREAS-RECURRENTES.md
+ documentado: true
+ documento_herencia: apps/verticales/mecanicas-diesel/database/HERENCIA-ERP-CORE.md
+ tablas_heredadas: 97
+ tablas_especificas: 30+
+
+ vidrio_templado:
+ specs_heredables:
+ - SPEC-VALORACION-INVENTARIO.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ - SPEC-INVENTARIOS-CICLICOS.md
+ documentado: true
+ documento_herencia: apps/verticales/vidrio-templado/database/HERENCIA-ERP-CORE.md
+ tablas_heredadas: ~97
+ tablas_especificas: ~25 (planificado)
retail:
specs_heredables:
- SPEC-PRICING-RULES.md
- SPEC-INVENTARIOS-CICLICOS.md
- SPEC-TRAZABILIDAD-LOTES-SERIES.md
- documentado: false
+ documentado: true
+ documento_herencia: apps/verticales/retail/database/HERENCIA-ERP-CORE.md
+ tablas_heredadas: ~102
+ tablas_especificas: ~30 (planificado)
clinicas:
specs_heredables:
- SPEC-RRHH-EVALUACIONES-SKILLS.md
- SPEC-INTEGRACION-CALENDAR.md
- SPEC-MAIL-THREAD-TRACKING.md
- documentado: false
+ documentado: true
+ documento_herencia: apps/verticales/clinicas/database/HERENCIA-ERP-CORE.md
+ tablas_heredadas: ~100
+ tablas_especificas: ~35 (planificado)
+
+# ============================================================================
+# VALIDACION DE PROPAGACION SIMCO
+# ============================================================================
+validacion_propagacion:
+ fecha: 2025-12-08
+ sistema: SIMCO v2.2.0
+
+ niveles:
+ suite_master:
+ nivel: 2B
+ inventarios: [SUITE_MASTER_INVENTORY.yml, STATUS.yml, REFERENCIAS.yml]
+ estado: COMPLETO
+
+ erp_core:
+ nivel: 2B.1
+ inventarios: 6
+ estado: COMPLETO
+ carga_limpia: EXITOSA
+
+ verticales:
+ nivel: 2B.2
+ total: 5
+ inventarios_por_vertical: 6
+ readme_por_vertical: 5/5
+ herencia_documentada: 5/5
+ directivas_por_vertical: 2-3
+
+ checklist:
+ - item: "SUITE_MASTER_INVENTORY actualizado"
+ estado: true
+ - item: "STATUS.yml sincronizado"
+ estado: true
+ - item: "REFERENCIAS.yml completo"
+ estado: true
+ - item: "README.md en todas las verticales"
+ estado: true
+ - item: "HERENCIA-ERP-CORE.md en todas las verticales"
+ estado: true
+ - item: "Directivas especΓficas por vertical"
+ estado: true
+ - item: "6 inventarios por proyecto"
+ estado: true
diff --git a/projects/erp-suite/orchestration/inventarios/STATUS.yml b/projects/erp-suite/orchestration/inventarios/STATUS.yml
index 9266f22..818fb6c 100644
--- a/projects/erp-suite/orchestration/inventarios/STATUS.yml
+++ b/projects/erp-suite/orchestration/inventarios/STATUS.yml
@@ -62,7 +62,7 @@ componentes:
nivel: "2B.2"
ultima_modificacion: "2025-12-08"
estado: "EN_DESARROLLO"
- completitud: "35%"
+ completitud: "40%"
capas:
documentacion:
estado: "AVANZADA"
@@ -73,10 +73,13 @@ componentes:
tablas_especificas: 33
schemas_especificos: ["construccion", "hr", "hse"]
backend:
- estado: "INICIAL"
- archivos_ts: 7
- entities: 2
- porcentaje: "5%"
+ estado: "EN_PROGRESO"
+ archivos_ts: 25
+ entities: 12
+ services: 2
+ controllers: 2
+ porcentaje: "15%"
+ modulos_funcionales: ["construction"]
frontend:
estado: "INICIAL"
archivos: 3
@@ -93,8 +96,9 @@ componentes:
- SPEC-TRAZABILIDAD-LOTES-SERIES.md
- SPEC-TAREAS-RECURRENTES.md
gap_analisis:
- documentacion_vs_codigo: "449 MD vs 10 cΓ³digo"
- ratio_implementacion: "2%"
+ documentacion_vs_codigo: "449 MD vs 25 cΓ³digo"
+ ratio_implementacion: "5.6%"
+ nota: "Gap corregido - entities base implementadas"
vidrio_templado:
nivel: "2B.2"
@@ -226,8 +230,8 @@ alertas:
fecha: "2025-12-08"
- componente: "construccion"
- tipo: "GAP"
- mensaje: "Gap significativo: 449 docs vs 10 archivos cΓ³digo (2% implementado)"
+ tipo: "EN_PROGRESO"
+ mensaje: "Gap corregido: 12 entities, 2 services, 2 controllers implementados"
fecha: "2025-12-08"
- componente: "mecanicas_diesel"
@@ -239,6 +243,16 @@ alertas:
# HISTORIAL DE CAMBIOS RECIENTES
# ========================================
historial:
+ - fecha: "2025-12-08"
+ componente: "construccion"
+ cambio: "IMPLEMENTACION GAP FIX - 12 entities, 2 services, 2 controllers creados"
+ agente: "System"
+ detalles:
+ - "Entities: Proyecto, Fraccionamiento, Employee, Puesto, Incidente, Capacitacion"
+ - "Services: ProyectoService, FraccionamientoService"
+ - "Controllers: ProyectoController, FraccionamientoController"
+ - "Backend 15% implementado (25 archivos TS)"
+
- fecha: "2025-12-08"
componente: "erp_core"
cambio: "CARGA LIMPIA EXITOSA - 124 tablas, 12 schemas, 6 seeds"
diff --git a/projects/erp-suite/orchestration/inventarios/SUITE_MASTER_INVENTORY.yml b/projects/erp-suite/orchestration/inventarios/SUITE_MASTER_INVENTORY.yml
index 79ec180..8830cf5 100644
--- a/projects/erp-suite/orchestration/inventarios/SUITE_MASTER_INVENTORY.yml
+++ b/projects/erp-suite/orchestration/inventarios/SUITE_MASTER_INVENTORY.yml
@@ -1,157 +1,422 @@
# Suite Master Inventory - ERP Suite
# Ultima actualizacion: 2025-12-08
# SSOT para metricas de toda la suite (core + verticales)
+# Sistema: SIMCO v2.2.0
+# Nivel: 2B (Suite Master)
suite:
nombre: ERP Suite
tipo: Multi-Vertical Suite
- version: 0.5.0
+ version: 0.6.0
nivel: 2B
estado: En Desarrollo
ultima_modificacion: 2025-12-08
+ # Inventarios de este nivel
+ inventarios_suite:
+ - SUITE_MASTER_INVENTORY.yml # Este archivo
+ - STATUS.yml # Estado de componentes
+ - REFERENCIAS.yml # Referencias cruzadas
+ - BACKEND_CONSOLIDATED.yml # Consolidado backend (referencia)
+ - FRONTEND_CONSOLIDATED.yml # Consolidado frontend (referencia)
+ - DEPENDENCY_SUITE.yml # Dependencias inter-proyecto
+
# ============================================================================
-# ERP CORE (Nivel 2B.1)
+# ERP CORE (Nivel 2B.1) - PROYECTO PADRE
# ============================================================================
erp_core:
path: apps/erp-core/
- estado: Gap Analysis COMPLETO
- version: 0.6.0
+ nivel: 2B.1
+ estado: DATABASE_COMPLETO
+ version: 1.1.0
ultima_modificacion: 2025-12-08
+ # Estado de capas
+ capas:
+ documentacion:
+ estado: COMPLETA
+ archivos: 680+
+ especificaciones: 30
+ workflows: 3
+
+ database:
+ estado: VALIDADO
+ tablas: 124
+ schemas: 12
+ ddl_archivos: 15
+ carga_limpia: EXITOSA
+ fecha_validacion: 2025-12-08
+
+ backend:
+ estado: PENDIENTE
+ endpoints_especificados: 148
+ services_especificados: 45+
+
+ frontend:
+ estado: PENDIENTE
+ componentes_especificados: 80+
+
+ # Inventarios del core (6 archivos estΓ‘ndar)
+ inventarios:
+ - MASTER_INVENTORY.yml
+ - DATABASE_INVENTORY.yml
+ - BACKEND_INVENTORY.yml
+ - FRONTEND_INVENTORY.yml
+ - DEPENDENCY_GRAPH.yml
+ - TRACEABILITY_MATRIX.yml
+ ubicacion: apps/erp-core/orchestration/inventarios/
+
+ # MΓ©tricas de documentaciΓ³n
metricas:
modulos_totales: 15
modulos_p0: 4
modulos_p1: 6
modulos_p2: 5
+ gap_analysis_cobertura: "100%"
+ story_points_cubiertos: 394
- documentacion:
- total_archivos: 680+
- especificaciones_transversales: 30
- workflows: 3
- requerimientos_funcionales: 46
- user_stories: 17
- test_plans: 4
-
- gap_analysis:
- gaps_p0_documentados: 18
- gaps_p1_documentados: 22
- patrones_tecnicos: 2
- cobertura: "100%"
- story_points_cubiertos: 394
-
- especificaciones_transversales:
+ # Especificaciones que heredan las verticales
+ especificaciones_heredables:
ubicacion: docs/04-modelado/especificaciones-tecnicas/transversal/
total: 30
- referencia: apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
+ lista_principales:
+ - SPEC-VALORACION-INVENTARIO.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ - SPEC-INVENTARIOS-CICLICOS.md
+ - SPEC-MAIL-THREAD-TRACKING.md
+ - SPEC-TAREAS-RECURRENTES.md
+ - SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN.md
+ - SPEC-INTEGRACION-CALENDAR.md
+ - SPEC-PRICING-RULES.md
+ - SPEC-RRHH-EVALUACIONES-SKILLS.md
- inventario_local: apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
- analisis_gaps: apps/erp-core/orchestration/01-analisis/ANALISIS-GAPS-CONSOLIDADO.md
+ referencias:
+ inventario_local: apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
+ analisis_gaps: apps/erp-core/orchestration/01-analisis/ANALISIS-GAPS-CONSOLIDADO.md
+ database_readme: apps/erp-core/database/README.md
# ============================================================================
-# VERTICALES (Nivel 2B.2)
+# VERTICALES (Nivel 2B.2) - PROYECTOS HIJOS
# ============================================================================
verticales:
total: 5
en_desarrollo: 1
- planificacion: 4
+ ddl_implementado: 1
+ planificacion: 3
+
+ # Inventarios estΓ‘ndar que debe tener cada vertical
+ inventarios_requeridos:
+ - MASTER_INVENTORY.yml
+ - DATABASE_INVENTORY.yml
+ - BACKEND_INVENTORY.yml
+ - FRONTEND_INVENTORY.yml
+ - DEPENDENCY_GRAPH.yml
+ - TRACEABILITY_MATRIX.yml
lista:
+ # -------------------------------------------------------------------------
+ # CONSTRUCCION - Vertical mΓ‘s avanzada
+ # -------------------------------------------------------------------------
- nombre: construccion
path: apps/verticales/construccion/
- estado: En Desarrollo
- completitud: 35%
- documentacion: 403+ archivos
- modulos: 15 (MAI-001 a MAI-018)
- epicas_fase2: 3 (MAE-014 a MAE-016)
- ultima_modificacion: 2025-12-05
- herencia_core:
- - SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN.md
- - SPEC-MAIL-THREAD-TRACKING.md
- - SPEC-WIZARD-TRANSIENT-MODEL.md
- - SPEC-VALORACION-INVENTARIO.md
- - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ nivel: 2B.2
+ estado: EN_DESARROLLO
+ completitud: 40%
+ ultima_modificacion: 2025-12-08
- - nombre: vidrio-templado
- path: apps/verticales/vidrio-templado/
- estado: Planificacion
- completitud: 0%
- documentacion: Estructura base
- ultima_modificacion: 2025-12-05
- herencia_core:
- - SPEC-VALORACION-INVENTARIO.md
- - SPEC-TRAZABILIDAD-LOTES-SERIES.md
- - SPEC-INVENTARIOS-CICLICOS.md
+ capas:
+ documentacion:
+ estado: AVANZADA
+ archivos: 449
+ database:
+ estado: DDL_COMPLETO
+ tablas_heredadas: 124
+ tablas_especificas: 33
+ schemas: [construccion, hr, hse]
+ backend:
+ estado: EN_PROGRESO
+ porcentaje: 15%
+ entities: 12
+ services: 2
+ controllers: 2
+ frontend:
+ estado: INICIAL
+ porcentaje: 2%
+ herencia_core:
+ specs_heredadas: 6
+ documento: database/HERENCIA-ERP-CORE.md
+ lista:
+ - SPEC-PROYECTOS-DEPENDENCIAS-BURNDOWN.md
+ - SPEC-MAIL-THREAD-TRACKING.md
+ - SPEC-WIZARD-TRANSIENT-MODEL.md
+ - SPEC-VALORACION-INVENTARIO.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ - SPEC-TAREAS-RECURRENTES.md
+
+ directivas_especificas:
+ - DIRECTIVA-CONTROL-OBRA.md
+ - DIRECTIVA-ESTIMACIONES.md
+ - DIRECTIVA-INTEGRACION-INFONAVIT.md
+
+ inventarios_ubicacion: orchestration/inventarios/
+
+ # -------------------------------------------------------------------------
+ # MECANICAS-DIESEL
+ # -------------------------------------------------------------------------
- nombre: mecanicas-diesel
path: apps/verticales/mecanicas-diesel/
- estado: Planificacion
- completitud: 0%
- documentacion: Estructura base
- ultima_modificacion: 2025-12-05
- herencia_core:
- - SPEC-VALORACION-INVENTARIO.md
- - SPEC-TRAZABILIDAD-LOTES-SERIES.md
- - SPEC-INVENTARIOS-CICLICOS.md
+ nivel: 2B.2
+ estado: DDL_IMPLEMENTADO
+ completitud: 20%
+ ultima_modificacion: 2025-12-08
+ capas:
+ documentacion:
+ estado: COMPLETA
+ archivos: 75
+ database:
+ estado: DDL_DEFINIDO
+ tablas_heredadas: 97
+ tablas_especificas: 30+
+ schemas: [service_management, parts_management, vehicle_management]
+ lineas_sql: 1561
+ backend:
+ estado: PENDIENTE
+ porcentaje: 0%
+ frontend:
+ estado: PENDIENTE
+ porcentaje: 0%
+
+ herencia_core:
+ specs_heredadas: 5
+ documento: database/HERENCIA-ERP-CORE.md
+ lista:
+ - SPEC-VALORACION-INVENTARIO.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ - SPEC-INVENTARIOS-CICLICOS.md
+ - SPEC-MAIL-THREAD-TRACKING.md
+ - SPEC-TAREAS-RECURRENTES.md
+
+ directivas_especificas:
+ - DIRECTIVA-ORDENES-TRABAJO.md
+ - DIRECTIVA-INVENTARIO-REFACCIONES.md
+
+ inventarios_ubicacion: orchestration/inventarios/
+
+ # -------------------------------------------------------------------------
+ # VIDRIO-TEMPLADO
+ # -------------------------------------------------------------------------
+ - nombre: vidrio-templado
+ path: apps/verticales/vidrio-templado/
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
+ ultima_modificacion: 2025-12-08
+
+ capas:
+ documentacion:
+ estado: ESTRUCTURA_BASE
+ database:
+ estado: PLANIFICADO
+ backend:
+ estado: PENDIENTE
+ frontend:
+ estado: PENDIENTE
+
+ herencia_core:
+ specs_heredadas: 3
+ lista:
+ - SPEC-VALORACION-INVENTARIO.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ - SPEC-INVENTARIOS-CICLICOS.md
+
+ directivas_especificas:
+ - DIRECTIVA-PRODUCCION-VIDRIO.md
+ - DIRECTIVA-CONTROL-CALIDAD.md
+
+ inventarios_ubicacion: orchestration/inventarios/
+
+ # -------------------------------------------------------------------------
+ # RETAIL
+ # -------------------------------------------------------------------------
- nombre: retail
path: apps/verticales/retail/
- estado: Planificacion
- completitud: 0%
- documentacion: Estructura base
- ultima_modificacion: 2025-12-05
- herencia_core:
- - SPEC-PRICING-RULES.md
- - SPEC-INVENTARIOS-CICLICOS.md
- - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
+ ultima_modificacion: 2025-12-08
+ capas:
+ documentacion:
+ estado: ESTRUCTURA_BASE
+ database:
+ estado: PLANIFICADO
+ backend:
+ estado: PENDIENTE
+ frontend:
+ estado: PENDIENTE
+
+ herencia_core:
+ specs_heredadas: 3
+ lista:
+ - SPEC-PRICING-RULES.md
+ - SPEC-INVENTARIOS-CICLICOS.md
+ - SPEC-TRAZABILIDAD-LOTES-SERIES.md
+
+ directivas_especificas:
+ - DIRECTIVA-PUNTO-VENTA.md
+ - DIRECTIVA-INVENTARIO-SUCURSALES.md
+
+ inventarios_ubicacion: orchestration/inventarios/
+
+ # -------------------------------------------------------------------------
+ # CLINICAS
+ # -------------------------------------------------------------------------
- nombre: clinicas
path: apps/verticales/clinicas/
- estado: Planificacion
- completitud: 0%
- documentacion: Estructura base
- ultima_modificacion: 2025-12-05
+ nivel: 2B.2
+ estado: PLANIFICACION_COMPLETA
+ completitud: 15%
+ ultima_modificacion: 2025-12-08
+
+ capas:
+ documentacion:
+ estado: ESTRUCTURA_BASE
+ database:
+ estado: PLANIFICADO
+ backend:
+ estado: PENDIENTE
+ frontend:
+ estado: PENDIENTE
+
herencia_core:
- - SPEC-RRHH-EVALUACIONES-SKILLS.md
- - SPEC-INTEGRACION-CALENDAR.md
- - SPEC-MAIL-THREAD-TRACKING.md
+ specs_heredadas: 3
+ lista:
+ - SPEC-RRHH-EVALUACIONES-SKILLS.md
+ - SPEC-INTEGRACION-CALENDAR.md
+ - SPEC-MAIL-THREAD-TRACKING.md
+
+ directivas_especificas:
+ - DIRECTIVA-EXPEDIENTE-CLINICO.md
+ - DIRECTIVA-GESTION-CITAS.md
+
+ inventarios_ubicacion: orchestration/inventarios/
# ============================================================================
-# SHARED LIBS
+# SHARED LIBS (Futuro)
# ============================================================================
shared_libs:
path: apps/shared-libs/
- estado: Planificado
- documentacion: Pendiente
+ nivel: 2B.3
+ estado: PLANIFICADO
+ documentacion: PENDIENTE
+ proposito: "Componentes compartidos entre verticales"
# ============================================================================
-# SAAS LAYER
+# SAAS LAYER (Futuro)
# ============================================================================
saas:
path: apps/saas/
- estado: Planificado
- documentacion: Pendiente
+ nivel: 2B.4
+ estado: PLANIFICADO
+ documentacion: PENDIENTE
+ proposito: "Capa de servicios multi-tenant cloud"
# ============================================================================
-# METRICAS CONSOLIDADAS
+# METRICAS CONSOLIDADAS DE LA SUITE
# ============================================================================
metricas_suite:
- total_archivos_docs: 1100+
- modulos_core: 15
- verticales: 5
- story_points_documentados: 734
- cobertura_gaps_core: 100%
+ fecha_actualizacion: 2025-12-08
+
+ documentacion:
+ total_archivos: 1200+
+ core: 680+
+ verticales: 520+
+
+ database:
+ tablas_core: 124
+ schemas_core: 12
+ verticales_con_ddl: 2
+ tablas_especificas_total: 63+ # construccion(33) + mecanicas(30+)
+
+ backend:
+ core_implementado: 0%
+ construccion_implementado: 15%
+ entities_totales: 12
+ services_totales: 2
+ controllers_totales: 2
+
+ frontend:
+ core_implementado: 0%
+ construccion_implementado: 2%
+
+ cobertura:
+ gap_analysis_core: "100%"
+ story_points_cubiertos: 734
+ specs_transversales: 30
+ workflows: 3
# ============================================================================
-# PROXIMA ACCION SUITE
+# PROPAGACION SIMCO
# ============================================================================
-proxima_accion:
- prioridad: ALTA
- descripcion: Implementar modulos P0 del core
- modulos:
- - MGN-001 Auth
- - MGN-002 Users
- - MGN-003 Roles
- - MGN-004 Tenants
- specs_disponibles: 30
- workflows_disponibles: 3
+propagacion:
+ sistema: SIMCO v2.2.0
+ niveles:
+ - nivel: 2B
+ nombre: Suite Master
+ ubicacion: orchestration/inventarios/
+ archivos: [SUITE_MASTER_INVENTORY.yml, STATUS.yml, REFERENCIAS.yml]
+
+ - nivel: 2B.1
+ nombre: ERP Core
+ ubicacion: apps/erp-core/orchestration/inventarios/
+ archivos: 6 # Inventarios estΓ‘ndar
+
+ - nivel: 2B.2
+ nombre: Verticales
+ ubicacion: apps/verticales/*/orchestration/inventarios/
+ archivos: 6 # Inventarios estΓ‘ndar por vertical
+ verticales: 5
+
+ herencia:
+ direccion: "Core -> Verticales"
+ documento_base: "HERENCIA-ERP-CORE.md"
+ specs_heredables: 30
+ propagacion_completada: true
+ fecha_propagacion: 2025-12-08
+
+ validacion:
+ inventarios_completos: true
+ directivas_propagadas: true
+ herencia_documentada: true
+ status_sincronizado: true
+
+# ============================================================================
+# PROXIMAS ACCIONES SUITE
+# ============================================================================
+proximas_acciones:
+ prioridad_1:
+ descripcion: "Completar backend construcciΓ³n"
+ modulos: [MAI-001, MAI-002, MAI-003]
+ porcentaje_actual: 15%
+ porcentaje_objetivo: 50%
+
+ prioridad_2:
+ descripcion: "Cargar DDL mecanicas-diesel"
+ prerequisito: "Validar DDL contra core"
+ estado: PENDIENTE
+
+ prioridad_3:
+ descripcion: "Iniciar DDL para verticales restantes"
+ verticales: [vidrio-templado, retail, clinicas]
+
+# ============================================================================
+# REFERENCIAS CRUZADAS
+# ============================================================================
+referencias:
+ status_global: orchestration/inventarios/STATUS.yml
+ referencias_herencia: orchestration/inventarios/REFERENCIAS.yml
+ core_master: apps/erp-core/orchestration/inventarios/MASTER_INVENTORY.yml
+ core_database: apps/erp-core/database/README.md
+ guidelines: orchestration/00-guidelines/
diff --git a/projects/platform_marketing_content/docs/00-vision-general/ARQUITECTURA-TECNICA.md b/projects/platform_marketing_content/docs/00-vision-general/ARQUITECTURA-TECNICA.md
new file mode 100644
index 0000000..b32f604
--- /dev/null
+++ b/projects/platform_marketing_content/docs/00-vision-general/ARQUITECTURA-TECNICA.md
@@ -0,0 +1,967 @@
+# Arquitectura Tθ
cnica - Platform Marketing Content
+
+**Versiθ΄Έn:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** Propuesta
+
+---
+
+## 1. Visiθ΄Έn de Arquitectura
+
+### 1.1 Principios Arquitectθ΄Έnicos
+
+```yaml
+Principios:
+ 1. API-First: Todo servicio expuesto via REST/GraphQL
+ 2. Modular: Componentes desacoplados por dominio
+ 3. Multi-tenant Ready: Aislamiento de datos por tenant
+ 4. Open Source First: Priorizar modelos auto-hosteados
+ 5. Escalabilidad Horizontal: Preparado para mη
€ltiples GPUs
+ 6. Event-Driven: Comunicaciθ΄Έn asιncrona entre servicios
+```
+
+### 1.2 Diagrama de Arquitectura de Alto Nivel
+
+```
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? CAPA DE PRESENTACIθ«N ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? Web App Admin ι? ι? Portal Cliente ι? ι?
+ι? ι? (React + Vite) ι? ι? (Opcional) ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι?
+ ι»?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? API GATEWAY ι?
+ι? (NestJS + JWT Auth) ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι? ι? ι? ι?
+ ι»? ι»? ι»? ι»?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? CAPA DE SERVICIOS ι?
+ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? CRM ι? ι? Projects ι? ι? Assets ι? ι? Auth ι? ι?
+ι? ι? Service ι? ι? Service ι? ι? Service ι? ι? Service ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? Generation ι? ι? Automation ι? ι?
+ι? ι? Service ι? ι? Service ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι? ι? ι? ι?
+ ι»? ι»? ι»? ι»?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? CAPA DE INFRAESTRUCTURA ι?
+ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? PostgreSQL ι? ι? Redis ι? ι? S3/MinIO ι? ι? ComfyUI ι? ι?
+ι? ι? 15+ ι? ι? (Cache) ι? ι? (Storage)ι? ι? (GPU) ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? n8n ι? ι? Bull/BullMQ ι? ι?
+ι? ι? (Workflows) ι? ι? (Job Queues) ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+```
+
+---
+
+## 2. Stack Tecnolθ΄Έgico Detallado
+
+### 2.1 Backend
+
+```yaml
+Framework: NestJS 10+
+Runtime: Node.js 20 LTS
+Lenguaje: TypeScript 5.x
+
+Dependencias Core:
+ - @nestjs/core
+ - @nestjs/platform-express
+ - @nestjs/typeorm
+ - @nestjs/jwt
+ - @nestjs/passport
+ - @nestjs/bull
+ - class-validator
+ - class-transformer
+
+ORM/Database:
+ - TypeORM 0.3+
+ - pg (PostgreSQL driver)
+
+Queues:
+ - bull / bullmq
+ - @nestjs/bull
+
+Caching:
+ - ioredis
+ - @nestjs/cache-manager
+
+HTTP Client:
+ - axios (llamadas a ComfyUI)
+
+File Storage:
+ - @aws-sdk/client-s3 (o minio compatible)
+
+Logging:
+ - winston
+ - @nestjs/winston
+```
+
+### 2.2 Frontend
+
+```yaml
+Framework: React 18
+Build Tool: Vite 5+
+Lenguaje: TypeScript 5.x
+
+UI Framework:
+ - TailwindCSS 3.x
+ - Shadcn/UI (componentes)
+ - Radix UI (primitivos)
+
+State Management:
+ - Zustand (global state)
+ - React Query / TanStack Query (server state)
+
+Routing:
+ - React Router 6
+
+Forms:
+ - React Hook Form
+ - Zod (validaciθ΄Έn)
+
+Charts/Visualizaciθ΄Έn:
+ - Recharts
+ - Apache ECharts (opcional)
+
+Utilities:
+ - date-fns
+ - lodash-es
+```
+
+### 2.3 Motor de Generaciθ΄Έn IA
+
+```yaml
+Orquestador Principal: ComfyUI
+ - Interfaz de nodos para workflows
+ - Soporte para mη
€ltiples modelos
+ - Custom nodes extensibles
+
+Exposiciθ΄Έn API: ComfyDeploy
+ - Convierte workflows en APIs HTTP
+ - Manejo de colas integrado
+ - Webhooks para resultados
+
+Modelos Base:
+ Text-to-Image:
+ - Stable Diffusion XL 1.0
+ - SD 1.5 / 2.1 (fallback para menos VRAM)
+
+ Checkpoints Especializados:
+ - Realistic Vision (rostros)
+ - Product Photography (e-commerce)
+ - Juggernaut XL (general alta calidad)
+
+ ControlNets:
+ - OpenPose (control de poses)
+ - Canny (bordes)
+ - Depth (profundidad)
+ - Segmentation (mθ°©scaras)
+
+ Upscalers:
+ - RealESRGAN x4
+ - SwinIR
+ - SDXL refiner
+
+ Inpainting:
+ - SDXL Inpaint model
+ - SD 1.5 Inpaint (fallback)
+
+Requisitos Hardware:
+ Mιnimo: NVIDIA GPU 12GB VRAM (RTX 3060 12GB)
+ Recomendado: NVIDIA GPU 24GB VRAM (RTX 4090, L4, A5000)
+ θ«ptimo: Mη
€ltiples GPUs para colas paralelas
+```
+
+### 2.4 Base de Datos
+
+```yaml
+Motor: PostgreSQL 15+
+
+Schemas:
+ - auth: Usuarios, sesiones, permisos
+ - crm: Clientes, contactos, marcas, productos
+ - projects: Proyectos, campaεΈ½as, briefs
+ - assets: Imθ°©genes, copys, metadatos
+ - generation: Jobs, workflows, resultados
+ - config: Configuraciθ΄Έn por tenant
+
+Extensiones:
+ - uuid-ossp (UUIDs)
+ - pgcrypto (encriptaciθ΄Έn)
+ - pg_trgm (bη
€squeda fuzzy)
+
+Estrategia Multi-tenant:
+ - Discriminador: tenant_id en todas las tablas
+ - Row-Level Security (RLS) por tenant
+ - Contexto de sesiθ΄Έn: app.current_tenant_id
+```
+
+### 2.5 Automatizaciθ΄Έn
+
+```yaml
+Orquestador: n8n (self-hosted)
+
+Triggers Soportados:
+ - Webhooks desde backend
+ - Cron / schedules
+ - Eventos de base de datos
+
+Integraciones:
+ - HTTP/REST (cualquier API)
+ - PostgreSQL queries
+ - S3/MinIO operations
+ - Email (SMTP)
+ - Slack/Discord (opcional)
+```
+
+---
+
+## 3. Estructura de Mθ΄Έdulos Backend
+
+### 3.1 Organizaciθ΄Έn de Cθ΄Έdigo
+
+```
+apps/backend/src/
+ιζΊζ’ι? modules/
+ι? ιζΊζ’ι? auth/
+ι? ι? ιζΊζ’ι? controllers/
+ι? ι? ιζΊζ’ι? services/
+ι? ι? ιζΊζ’ι? entities/
+ι? ι? ιζΊζ’ι? dto/
+ι? ι? ιζΊζ’ι? guards/
+ι? ι? ιζΊζ’ι? strategies/
+ι? ι? ιζΊζ’ι? auth.module.ts
+ι? ι?
+ι? ιζΊζ’ι? crm/
+ι? ι? ιζΊζ’ι? controllers/
+ι? ι? ι? ιζΊζ’ι? clients.controller.ts
+ι? ι? ι? ιζΊζ’ι? brands.controller.ts
+ι? ι? ι? ιζΊζ’ι? products.controller.ts
+ι? ι? ι? ιζΊζ’ι? contacts.controller.ts
+ι? ι? ιζΊζ’ι? services/
+ι? ι? ιζΊζ’ι? entities/
+ι? ι? ιζΊζ’ι? dto/
+ι? ι? ιζΊζ’ι? crm.module.ts
+ι? ι?
+ι? ιζΊζ’ι? projects/
+ι? ι? ιζΊζ’ι? controllers/
+ι? ι? ι? ιζΊζ’ι? projects.controller.ts
+ι? ι? ι? ιζΊζ’ι? campaigns.controller.ts
+ι? ι? ι? ιζΊζ’ι? briefs.controller.ts
+ι? ι? ιζΊζ’ι? services/
+ι? ι? ιζΊζ’ι? entities/
+ι? ι? ιζΊζ’ι? dto/
+ι? ι? ιζΊζ’ι? projects.module.ts
+ι? ι?
+ι? ιζΊζ’ι? generation/
+ι? ι? ιζΊζ’ι? controllers/
+ι? ι? ι? ιζΊζ’ι? generation.controller.ts
+ι? ι? ι? ιζΊζ’ι? workflows.controller.ts
+ι? ι? ιζΊζ’ι? services/
+ι? ι? ι? ιζΊζ’ι? generation.service.ts
+ι? ι? ι? ιζΊζ’ι? comfyui.service.ts
+ι? ι? ι? ιζΊζ’ι? llm.service.ts
+ι? ι? ιζΊζ’ι? processors/
+ι? ι? ι? ιζΊζ’ι? generation.processor.ts
+ι? ι? ιζΊζ’ι? entities/
+ι? ι? ιζΊζ’ι? dto/
+ι? ι? ιζΊζ’ι? generation.module.ts
+ι? ι?
+ι? ιζΊζ’ι? assets/
+ι? ι? ιζΊζ’ι? controllers/
+ι? ι? ιζΊζ’ι? services/
+ι? ι? ιζΊζ’ι? entities/
+ι? ι? ιζΊζ’ι? dto/
+ι? ι? ιζΊζ’ι? assets.module.ts
+ι? ι?
+ι? ιζΊζ’ι? admin/
+ι? ιζΊζ’ι? controllers/
+ι? ιζΊζ’ι? services/
+ι? ιζΊζ’ι? admin.module.ts
+ι?
+ιζΊζ’ι? shared/
+ι? ιζΊζ’ι? decorators/
+ι? ιζΊζ’ι? guards/
+ι? ι? ιζΊζ’ι? tenant.guard.ts
+ι? ι? ιζΊζ’ι? roles.guard.ts
+ι? ιζΊζ’ι? interceptors/
+ι? ι? ιζΊζ’ι? tenant-context.interceptor.ts
+ι? ιζΊζ’ι? filters/
+ι? ιζΊζ’ι? pipes/
+ι? ιζΊζ’ι? utils/
+ι?
+ιζΊζ’ι? config/
+ι? ιζΊζ’ι? database.config.ts
+ι? ιζΊζ’ι? redis.config.ts
+ι? ιζΊζ’ι? storage.config.ts
+ι? ιζΊζ’ι? comfyui.config.ts
+ι?
+ιζΊζ’ι? app.module.ts
+ιζΊζ’ι? main.ts
+```
+
+### 3.2 API Endpoints (Borrador)
+
+```yaml
+Auth:
+ POST /api/v1/auth/login
+ POST /api/v1/auth/register
+ POST /api/v1/auth/refresh
+ POST /api/v1/auth/logout
+ GET /api/v1/auth/me
+
+CRM - Clients:
+ GET /api/v1/crm/clients
+ POST /api/v1/crm/clients
+ GET /api/v1/crm/clients/:id
+ PATCH /api/v1/crm/clients/:id
+ DELETE /api/v1/crm/clients/:id
+
+CRM - Brands:
+ GET /api/v1/crm/brands
+ POST /api/v1/crm/brands
+ GET /api/v1/crm/brands/:id
+ PATCH /api/v1/crm/brands/:id
+ GET /api/v1/crm/brands/:id/products
+
+CRM - Products:
+ GET /api/v1/crm/products
+ POST /api/v1/crm/products
+ GET /api/v1/crm/products/:id
+ PATCH /api/v1/crm/products/:id
+
+Projects:
+ GET /api/v1/projects
+ POST /api/v1/projects
+ GET /api/v1/projects/:id
+ PATCH /api/v1/projects/:id
+ GET /api/v1/projects/:id/campaigns
+ GET /api/v1/projects/:id/assets
+
+Campaigns:
+ GET /api/v1/campaigns
+ POST /api/v1/campaigns
+ GET /api/v1/campaigns/:id
+ PATCH /api/v1/campaigns/:id
+ POST /api/v1/campaigns/:id/generate
+ GET /api/v1/campaigns/:id/assets
+
+Generation:
+ POST /api/v1/generation/image
+ POST /api/v1/generation/copy
+ GET /api/v1/generation/jobs/:id
+ GET /api/v1/generation/workflows
+ POST /api/v1/generation/workflows/:id/execute
+
+Assets:
+ GET /api/v1/assets
+ GET /api/v1/assets/:id
+ PATCH /api/v1/assets/:id
+ DELETE /api/v1/assets/:id
+ POST /api/v1/assets/:id/approve
+ GET /api/v1/assets/:id/download
+
+Admin:
+ GET /api/v1/admin/users
+ POST /api/v1/admin/users
+ GET /api/v1/admin/tenants
+ GET /api/v1/admin/metrics
+```
+
+---
+
+## 4. Modelo de Datos (Entidades Principales)
+
+### 4.1 Schema: auth
+
+```sql
+-- Tabla: auth.users
+CREATE TABLE auth.users (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ email VARCHAR(255) NOT NULL,
+ password_hash VARCHAR(255) NOT NULL,
+ first_name VARCHAR(100),
+ last_name VARCHAR(100),
+ role VARCHAR(50) NOT NULL DEFAULT 'user',
+ status VARCHAR(20) NOT NULL DEFAULT 'active',
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ UNIQUE(tenant_id, email)
+);
+
+-- Tabla: auth.sessions
+CREATE TABLE auth.sessions (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID NOT NULL REFERENCES auth.users(id),
+ refresh_token VARCHAR(500) NOT NULL,
+ expires_at TIMESTAMPTZ NOT NULL,
+ ip_address VARCHAR(45),
+ user_agent TEXT,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+```
+
+### 4.2 Schema: crm
+
+```sql
+-- Tabla: crm.clients
+CREATE TABLE crm.clients (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ name VARCHAR(255) NOT NULL,
+ industry VARCHAR(100),
+ status VARCHAR(20) NOT NULL DEFAULT 'active',
+ notes TEXT,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: crm.brands
+CREATE TABLE crm.brands (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ client_id UUID NOT NULL REFERENCES crm.clients(id),
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ tone_of_voice VARCHAR(100),
+ color_palette JSONB,
+ restrictions JSONB,
+ logo_url VARCHAR(500),
+ lora_model_id UUID,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: crm.products
+CREATE TABLE crm.products (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ brand_id UUID NOT NULL REFERENCES crm.brands(id),
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ category VARCHAR(100),
+ reference_images JSONB,
+ lora_model_id UUID,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: crm.contacts
+CREATE TABLE crm.contacts (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ client_id UUID REFERENCES crm.clients(id),
+ first_name VARCHAR(100) NOT NULL,
+ last_name VARCHAR(100),
+ email VARCHAR(255),
+ phone VARCHAR(50),
+ position VARCHAR(100),
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+```
+
+### 4.3 Schema: projects
+
+```sql
+-- Tabla: projects.projects
+CREATE TABLE projects.projects (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ client_id UUID REFERENCES crm.clients(id),
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ status VARCHAR(20) NOT NULL DEFAULT 'draft',
+ start_date DATE,
+ end_date DATE,
+ created_by UUID REFERENCES auth.users(id),
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: projects.campaigns
+CREATE TABLE projects.campaigns (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ project_id UUID NOT NULL REFERENCES projects.projects(id),
+ brand_id UUID REFERENCES crm.brands(id),
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(50) NOT NULL,
+ status VARCHAR(20) NOT NULL DEFAULT 'draft',
+ channels JSONB,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: projects.briefs
+CREATE TABLE projects.briefs (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ campaign_id UUID NOT NULL REFERENCES projects.campaigns(id),
+ objective TEXT NOT NULL,
+ target_audience TEXT,
+ tone_of_voice VARCHAR(100),
+ key_messages JSONB,
+ restrictions JSONB,
+ reference_images JSONB,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+```
+
+### 4.4 Schema: assets
+
+```sql
+-- Tabla: assets.assets
+CREATE TABLE assets.assets (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ campaign_id UUID REFERENCES projects.campaigns(id),
+ type VARCHAR(20) NOT NULL,
+ name VARCHAR(255),
+ status VARCHAR(20) NOT NULL DEFAULT 'draft',
+ file_url VARCHAR(500),
+ file_size INTEGER,
+ mime_type VARCHAR(100),
+ width INTEGER,
+ height INTEGER,
+ metadata JSONB,
+ version INTEGER NOT NULL DEFAULT 1,
+ parent_id UUID REFERENCES assets.assets(id),
+ created_by UUID REFERENCES auth.users(id),
+ approved_by UUID REFERENCES auth.users(id),
+ approved_at TIMESTAMPTZ,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: assets.tags
+CREATE TABLE assets.tags (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ name VARCHAR(100) NOT NULL,
+ UNIQUE(tenant_id, name)
+);
+
+-- Tabla: assets.asset_tags
+CREATE TABLE assets.asset_tags (
+ asset_id UUID NOT NULL REFERENCES assets.assets(id),
+ tag_id UUID NOT NULL REFERENCES assets.tags(id),
+ PRIMARY KEY (asset_id, tag_id)
+);
+```
+
+### 4.5 Schema: generation
+
+```sql
+-- Tabla: generation.jobs
+CREATE TABLE generation.jobs (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID NOT NULL REFERENCES config.tenants(id),
+ campaign_id UUID REFERENCES projects.campaigns(id),
+ workflow_id VARCHAR(100) NOT NULL,
+ type VARCHAR(20) NOT NULL,
+ status VARCHAR(20) NOT NULL DEFAULT 'pending',
+ priority INTEGER NOT NULL DEFAULT 0,
+ input_params JSONB NOT NULL,
+ result JSONB,
+ error_message TEXT,
+ started_at TIMESTAMPTZ,
+ completed_at TIMESTAMPTZ,
+ created_by UUID REFERENCES auth.users(id),
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: generation.workflows
+CREATE TABLE generation.workflows (
+ id VARCHAR(100) PRIMARY KEY,
+ tenant_id UUID REFERENCES config.tenants(id),
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ type VARCHAR(50) NOT NULL,
+ comfyui_workflow JSONB NOT NULL,
+ input_schema JSONB,
+ is_system BOOLEAN NOT NULL DEFAULT false,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+
+-- Tabla: generation.models
+CREATE TABLE generation.models (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tenant_id UUID REFERENCES config.tenants(id),
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(50) NOT NULL,
+ file_path VARCHAR(500),
+ description TEXT,
+ training_images JSONB,
+ is_system BOOLEAN NOT NULL DEFAULT false,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+```
+
+---
+
+## 5. Flujo de Generaciθ΄Έn de Contenido
+
+### 5.1 Secuencia de Generaciθ΄Έn de Imagen
+
+```
+1. Usuario solicita generaciθ΄Έn
+ ι»?
+ Frontend ι«? POST /api/v1/generation/image
+ {
+ "campaign_id": "uuid",
+ "workflow_id": "product_photography",
+ "params": {
+ "prompt": "...",
+ "product_id": "uuid",
+ "style": "commercial"
+ }
+ }
+
+2. Backend crea Job
+ ι»?
+ GenerationService.createJob()
+ ι«? Valida permisos
+ ι«? Crea registro en generation.jobs
+ ι«? Encola job en Bull queue
+
+3. Worker procesa Job
+ ι»?
+ GenerationProcessor.process()
+ ι«? Obtiene workflow de ComfyUI
+ ι«? Inyecta parθ°©metros (prompt, LoRA, etc.)
+ ι«? Envιa a ComfyUI API
+ ι«? Espera resultado (webhook o polling)
+
+4. ComfyUI ejecuta workflow
+ ι»?
+ ι«? Carga modelo SDXL
+ ι«? Aplica LoRAs (si hay)
+ ι«? Ejecuta pipeline de difusiθ΄Έn
+ ι«? Aplica upscaling
+ ι«? Retorna imagen
+
+5. Worker procesa resultado
+ ι»?
+ ι«? Descarga imagen de ComfyUI
+ ι«? Sube a S3/MinIO
+ ι«? Crea registro en assets.assets
+ ι«? Actualiza job como completado
+ ι«? Emite evento (webhook a n8n)
+
+6. Frontend recibe notificaciθ΄Έn
+ ι»?
+ WebSocket / Polling ι«? Job completado
+ ι«? Muestra imagen al usuario
+```
+
+### 5.2 Integraciθ΄Έn con ComfyUI
+
+```typescript
+// services/comfyui.service.ts
+
+interface ComfyUIWorkflowParams {
+ prompt: string;
+ negativePrompt?: string;
+ width?: number;
+ height?: number;
+ steps?: number;
+ cfg?: number;
+ seed?: number;
+ loraModels?: string[];
+ controlNet?: {
+ type: string;
+ image: string;
+ strength: number;
+ };
+}
+
+@Injectable()
+export class ComfyUIService {
+ constructor(
+ private httpService: HttpService,
+ @Inject('COMFYUI_CONFIG') private config: ComfyUIConfig,
+ ) {}
+
+ async executeWorkflow(
+ workflowId: string,
+ params: ComfyUIWorkflowParams,
+ ): Promise {
+ // 1. Cargar workflow template
+ const workflow = await this.getWorkflowTemplate(workflowId);
+
+ // 2. Inyectar parθ°©metros
+ const modifiedWorkflow = this.injectParams(workflow, params);
+
+ // 3. Enviar a ComfyUI
+ const response = await this.httpService.post(
+ `${this.config.baseUrl}/prompt`,
+ { prompt: modifiedWorkflow },
+ ).toPromise();
+
+ return response.data.prompt_id;
+ }
+
+ async getResult(promptId: string): Promise {
+ // Polling o webhook para obtener resultado
+ const history = await this.httpService.get(
+ `${this.config.baseUrl}/history/${promptId}`,
+ ).toPromise();
+
+ const outputNode = this.findOutputNode(history.data);
+ const imageUrl = `${this.config.baseUrl}/view?filename=${outputNode.filename}`;
+
+ const imageResponse = await this.httpService.get(imageUrl, {
+ responseType: 'arraybuffer',
+ }).toPromise();
+
+ return Buffer.from(imageResponse.data);
+ }
+}
+```
+
+---
+
+## 6. Seguridad
+
+### 6.1 Autenticaciθ΄Έn
+
+```yaml
+Mθ
todo: JWT (JSON Web Tokens)
+
+Access Token:
+ - Expiraciθ΄Έn: 15 minutos
+ - Payload: userId, tenantId, role
+ - Almacenamiento: Memory (frontend)
+
+Refresh Token:
+ - Expiraciθ΄Έn: 7 dιas
+ - Almacenamiento: HTTP-only cookie
+ - Rotaciθ΄Έn en cada uso
+```
+
+### 6.2 Autorizaciθ΄Έn (RBAC)
+
+```yaml
+Roles:
+ super_admin:
+ - Acceso total a todos los tenants
+ - Configuraciθ΄Έn global
+ - Gestiθ΄Έn de modelos del sistema
+
+ admin:
+ - Gestiθ΄Έn de usuarios del tenant
+ - Configuraciθ΄Έn del tenant
+ - Aprobaciθ΄Έn de workflows
+
+ manager:
+ - CRUD completo de proyectos/campaεΈ½as
+ - Aprobaciθ΄Έn de assets
+ - Acceso a analιticas
+
+ creative:
+ - Crear proyectos y campaεΈ½as
+ - Generar contenido
+ - Editar assets propios
+
+ viewer:
+ - Solo lectura
+ - Descargar assets aprobados
+```
+
+### 6.3 Multi-tenancy
+
+```sql
+-- Polιtica RLS ejemplo
+CREATE POLICY "crm_clients_tenant_isolation" ON crm.clients
+ FOR ALL
+ TO authenticated
+ USING (tenant_id::text = current_setting('app.current_tenant_id', true))
+ WITH CHECK (tenant_id::text = current_setting('app.current_tenant_id', true));
+```
+
+---
+
+## 7. Despliegue
+
+### 7.1 Docker Compose (Desarrollo/Staging)
+
+```yaml
+version: '3.8'
+
+services:
+ backend:
+ build: ./apps/backend
+ ports:
+ - "3000:3000"
+ environment:
+ - DATABASE_URL=postgresql://...
+ - REDIS_URL=redis://redis:6379
+ - COMFYUI_URL=http://comfyui:8188
+ - S3_ENDPOINT=http://minio:9000
+ depends_on:
+ - postgres
+ - redis
+ - minio
+
+ frontend:
+ build: ./apps/frontend
+ ports:
+ - "5173:80"
+ depends_on:
+ - backend
+
+ postgres:
+ image: postgres:15-alpine
+ volumes:
+ - postgres_data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_DB=pmc
+ - POSTGRES_USER=pmc
+ - POSTGRES_PASSWORD=${DB_PASSWORD}
+
+ redis:
+ image: redis:7-alpine
+ volumes:
+ - redis_data:/data
+
+ minio:
+ image: minio/minio
+ ports:
+ - "9000:9000"
+ - "9001:9001"
+ volumes:
+ - minio_data:/data
+ command: server /data --console-address ":9001"
+
+ comfyui:
+ image: comfyui/comfyui:latest
+ ports:
+ - "8188:8188"
+ volumes:
+ - comfyui_models:/models
+ - comfyui_output:/output
+ deploy:
+ resources:
+ reservations:
+ devices:
+ - driver: nvidia
+ count: 1
+ capabilities: [gpu]
+
+ n8n:
+ image: n8nio/n8n
+ ports:
+ - "5678:5678"
+ volumes:
+ - n8n_data:/home/node/.n8n
+
+volumes:
+ postgres_data:
+ redis_data:
+ minio_data:
+ comfyui_models:
+ comfyui_output:
+ n8n_data:
+```
+
+### 7.2 Requisitos de Hardware (Producciθ΄Έn)
+
+```yaml
+Backend + Frontend:
+ CPU: 4 cores
+ RAM: 8 GB
+ Storage: 50 GB SSD
+
+PostgreSQL:
+ CPU: 2 cores
+ RAM: 8 GB
+ Storage: 100 GB SSD
+
+ComfyUI (GPU Server):
+ CPU: 8 cores
+ RAM: 32 GB
+ GPU: NVIDIA RTX 4090 (24GB) o similar
+ Storage: 500 GB NVMe (modelos)
+
+Storage (S3/MinIO):
+ Storage: 1 TB+ (escalable)
+```
+
+---
+
+## 8. Monitoreo y Observabilidad
+
+### 8.1 Logs
+
+```yaml
+Backend:
+ - Winston con formato JSON estructurado
+ - Niveles: error, warn, info, debug
+ - Rotaciθ΄Έn diaria
+
+Agregaciθ΄Έn:
+ - ELK Stack (Elasticsearch, Logstash, Kibana)
+ - O alternativa: Loki + Grafana
+```
+
+### 8.2 Mθ
tricas
+
+```yaml
+Application Metrics:
+ - API response times (p50, p95, p99)
+ - Queue depths y processing times
+ - Generation success rate
+ - Error rates por tipo
+
+Business Metrics:
+ - Assets generados por dιa
+ - Tiempo promedio de generaciθ΄Έn
+ - Assets aprobados vs rechazados
+ - Uso por tenant/usuario
+
+Infrastructure:
+ - CPU, RAM, disk usage
+ - GPU utilization
+ - Network I/O
+```
+
+### 8.3 Alertas
+
+```yaml
+Crιticas:
+ - API down > 1 min
+ - GPU unavailable
+ - Queue backlog > 100 jobs
+ - Error rate > 5%
+
+Advertencias:
+ - Response time p95 > 2s
+ - Disk usage > 80%
+ - Queue processing slow
+```
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/00-vision-general/GLOSARIO.md b/projects/platform_marketing_content/docs/00-vision-general/GLOSARIO.md
new file mode 100644
index 0000000..57aab86
--- /dev/null
+++ b/projects/platform_marketing_content/docs/00-vision-general/GLOSARIO.md
@@ -0,0 +1,199 @@
+# Glosario - Platform Marketing Content
+
+**Versiθ΄Έn:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## Tθ
rminos del Dominio
+
+### A
+
+**Asset**
+: Recurso digital generado o almacenado en la plataforma (imagen, copy, video, etc.).
+
+**Avatar Virtual / Influencer Virtual**
+: Personaje generado por IA que mantiene consistencia visual a travθ
s de mη
€ltiples imθ°©genes/videos. Ejemplo: Aitana Lθ΄Έpez.
+
+### B
+
+**Brief**
+: Documento estructurado que define los parθ°©metros de una campaεΈ½a o generaciθ΄Έn: objetivo, pη
€blico, tono, canales, restricciones.
+
+### C
+
+**CampaεΈ½a**
+: Iniciativa de marketing con objetivo especιfico que agrupa mη
€ltiples assets generados para diferentes canales.
+
+**Checkpoint**
+: Versiθ΄Έn guardada de un modelo de IA entrenado. Puede ser especializado (fotografιa de producto, rostros, etc.).
+
+**ComfyUI**
+: Interfaz de nodos para construir flujos de generaciθ΄Έn con Stable Diffusion y otros modelos. Permite encadenar procesos de forma visual.
+
+**ComfyDeploy**
+: Herramienta que permite exponer workflows de ComfyUI como APIs HTTP para consumo desde aplicaciones.
+
+**Consistencia de Personaje**
+: Capacidad de mantener los mismos rasgos faciales y caracterιsticas visuales de un personaje a travθ
s de mη
€ltiples generaciones.
+
+**ControlNet**
+: Adaptador para modelos de difusiθ΄Έn que permite controlar la generaciθ΄Έn mediante guιas visuales (poses, bordes, profundidad, segmentaciθ΄Έn).
+
+**Copy**
+: Texto publicitario generado para acompaεΈ½ar imθ°©genes (tιtulos, descripciones, hashtags, CTAs).
+
+**CRM (Customer Relationship Management)**
+: Sistema de gestiθ΄Έn de relaciones con clientes. En esta plataforma, integrado con el motor de generaciθ΄Έn.
+
+### D
+
+**DAM (Digital Asset Management)**
+: Sistema de gestiθ΄Έn de activos digitales. Repositorio centralizado para almacenar, organizar y buscar contenido generado.
+
+**Difusiθ΄Έn / Diffusion**
+: Tθ
cnica de IA generativa que crea imθ°©genes partiendo de ruido aleatorio y eliminando ruido gradualmente siguiendo indicaciones de texto.
+
+**DreamBooth**
+: Tθ
cnica de fine-tuning que permite personalizar un modelo con pocas imθ°©genes de un sujeto especιfico.
+
+### F
+
+**Fine-tuning**
+: Proceso de re-entrenar un modelo pre-existente con datos especιficos para especializarlo en un dominio o estilo particular.
+
+**Fotografιa Sintθ
tica**
+: Imθ°©genes generadas por IA que simulan fotografιas reales de productos, personas o escenas.
+
+### G
+
+**Generaciθ΄Έn de Contenido**
+: Proceso de crear imθ°©genes, textos u otros medios mediante modelos de IA.
+
+### I
+
+**Image Prompt**
+: Imagen de referencia utilizada como entrada adicional al texto para guiar la generaciθ΄Έn hacia un estilo o sujeto especιfico.
+
+**Inpainting**
+: Tθ
cnica de ediciθ΄Έn que permite regenerar solo una porciθ΄Έn seleccionada de una imagen manteniendo el resto intacto.
+
+**IP-Adapter**
+: Adaptador que permite inyectar caracterιsticas de una imagen de referencia en la generaciθ΄Έn, logrando consistencia visual.
+
+### L
+
+**LLM (Large Language Model)**
+: Modelo de lenguaje de gran escala usado para generar texto (GPT-4, Claude, Llama, etc.).
+
+**LoRA (Low-Rank Adaptation)**
+: Tθ
cnica de fine-tuning eficiente que permite personalizar un modelo con pocos recursos. Crea archivos pequeεΈ½os que modifican el comportamiento del modelo base.
+
+### M
+
+**Multi-tenant**
+: Arquitectura donde una sola instancia del software sirve a mη
€ltiples clientes (tenants) con datos aislados.
+
+### N
+
+**n8n**
+: Plataforma de automatizaciθ΄Έn de workflows que conecta diferentes servicios y APIs mediante flujos visuales.
+
+### O
+
+**Orquestador**
+: Sistema que coordina la ejecuciθ΄Έn de mη
€ltiples tareas o servicios en un flujo definido.
+
+### P
+
+**Plantilla / Template**
+: Workflow predefinido de generaciθ΄Έn que puede ser reutilizado para crear contenido con parθ°©metros especιficos.
+
+**Prompt**
+: Texto de instrucciθ΄Έn que guιa al modelo de IA sobre quθ
generar. Puede incluir descripciθ΄Έn de la imagen, estilo, elementos a incluir/excluir.
+
+### R
+
+**RBAC (Role-Based Access Control)**
+: Sistema de permisos basado en roles donde los usuarios heredan permisos segη
€n su rol asignado.
+
+**Rollout**
+: Despliegue gradual de una funcionalidad a grupos de usuarios.
+
+### S
+
+**SaaS (Software as a Service)**
+: Modelo de distribuciθ΄Έn de software donde la aplicaciθ΄Έn se aloja en la nube y se accede vιa web bajo suscripciθ΄Έn.
+
+**SDXL (Stable Diffusion XL)**
+: Versiθ΄Έn avanzada de Stable Diffusion con mayor resoluciθ΄Έn y mejor comprensiθ΄Έn de prompts.
+
+**Stable Diffusion**
+: Modelo de difusiθ΄Έn de cθ΄Έdigo abierto para generaciθ΄Έn de imθ°©genes a partir de texto.
+
+### T
+
+**Tenant**
+: Cliente/organizaciθ΄Έn en una arquitectura multi-tenant. Cada tenant tiene sus datos aislados.
+
+**Text-to-Image (T2I)**
+: Proceso de generar imθ°©genes a partir de descripciones textuales.
+
+**Textual Inversion**
+: Tθ
cnica que permite enseεΈ½ar a un modelo un nuevo concepto asociado a una palabra clave especιfica.
+
+### U
+
+**Upscaling**
+: Proceso de aumentar la resoluciθ΄Έn de una imagen utilizando tθ
cnicas de IA para mantener o mejorar la calidad.
+
+### V
+
+**VRAM (Video RAM)**
+: Memoria dedicada de la tarjeta grθ°©fica. Los modelos de difusiθ΄Έn requieren 8-24GB VRAM para funcionar.
+
+### W
+
+**Workflow**
+: Flujo de trabajo que define una secuencia de pasos para completar un proceso (ej: generaciθ΄Έn de imθ°©genes con postprocesado).
+
+---
+
+## Acrθ΄Έnimos Comunes
+
+| Acrθ΄Έnimo | Significado |
+|----------|-------------|
+| **API** | Application Programming Interface |
+| **CRM** | Customer Relationship Management |
+| **DAM** | Digital Asset Management |
+| **GPU** | Graphics Processing Unit |
+| **JWT** | JSON Web Token |
+| **LLM** | Large Language Model |
+| **LoRA** | Low-Rank Adaptation |
+| **MVP** | Minimum Viable Product |
+| **NLP** | Natural Language Processing |
+| **RBAC** | Role-Based Access Control |
+| **RLS** | Row-Level Security |
+| **SaaS** | Software as a Service |
+| **SDXL** | Stable Diffusion XL |
+| **T2I** | Text-to-Image |
+| **VRAM** | Video Random Access Memory |
+
+---
+
+## Modelos de IA Relevantes
+
+| Modelo | Tipo | Descripciθ΄Έn |
+|--------|------|-------------|
+| **Stable Diffusion XL** | Text-to-Image | Modelo base open-source de alta calidad |
+| **Fooocus** | Frontend SDXL | Interfaz simplificada para SDXL |
+| **Gemini 3 Pro Image** | Text-to-Image | Modelo de Google con texto perfecto en imθ°©genes |
+| **Seedream 4.0** | Multimodal | Modelo de ByteDance con imagen, video y avatares |
+| **DeepFloyd IF** | Text-to-Image | Especializado en renderizado de texto |
+| **GPT-4** | LLM | Modelo de OpenAI para generaciθ΄Έn de texto |
+| **Claude** | LLM | Modelo de Anthropic para generaciθ΄Έn de texto |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/00-vision-general/InvestigaciΓ³n Profunda_ Plataforma de GeneraciΓ³n de Contenido de Morfeo Academy y Desarrollo de una .pdf b/projects/platform_marketing_content/docs/00-vision-general/InvestigaciΓ³n Profunda_ Plataforma de GeneraciΓ³n de Contenido de Morfeo Academy y Desarrollo de una .pdf
new file mode 100644
index 0000000..ad26fe8
Binary files /dev/null and b/projects/platform_marketing_content/docs/00-vision-general/InvestigaciΓ³n Profunda_ Plataforma de GeneraciΓ³n de Contenido de Morfeo Academy y Desarrollo de una .pdf differ
diff --git a/projects/platform_marketing_content/docs/00-vision-general/MVP_Plataforma_SaaS_Contenido_CRM.md b/projects/platform_marketing_content/docs/00-vision-general/MVP_Plataforma_SaaS_Contenido_CRM.md
new file mode 100644
index 0000000..1c2e7b6
--- /dev/null
+++ b/projects/platform_marketing_content/docs/00-vision-general/MVP_Plataforma_SaaS_Contenido_CRM.md
@@ -0,0 +1,327 @@
+
+# MVP β Plataforma SaaS de GeneraciΓ³n de Contenido y CRM Creativo
+*(Basada en la investigaciΓ³n de la plataforma tipo Morfeo Academy y tecnologΓas open source)*
+
+---
+
+## 1. Objetivo General del MVP
+
+Construir una **plataforma SaaS interna** (modo βSaaS para uso propioβ) para una **agencia de publicidad y generaciΓ³n de contenido**, que permita:
+
+- Generar contenido visual y textual (imΓ‘genes, piezas publicitarias, posts para redes, etc.) con IA.
+- Gestionar campaΓ±as, clientes y oportunidades desde un **CRM integrado**.
+- Automatizar flujos creativos y procesos operativos (desde brief β contenido β aprobaciΓ³n β publicaciΓ³n/entrega).
+- Operar bajo un **admin con uso ilimitado** + roles internos, con base tΓ©cnica preparada para futura multi-empresa/multi-tenant.
+
+La prioridad del MVP es usar **modelos open source auto-hosteados** y, cuando sea estrictamente necesario, **APIs de terceros** para capacidades avanzadas (texto perfecto en imΓ‘genes, video/avatares, etc.).
+
+---
+
+## 2. Alcance del MVP
+
+### 2.1 Incluido
+
+- NΓΊcleo de generaciΓ³n de **imΓ‘genes** + **copys** para marketing.
+- GestiΓ³n bΓ‘sica de **clientes, marcas, productos y campaΓ±as**.
+- MΓ³dulo para **workflows creativos predefinidos** (plantillas de generaciΓ³n).
+- **AutomatizaciΓ³n bΓ‘sica**: triggers desde CRM hacia el motor de generaciΓ³n.
+- **GestiΓ³n de usuarios internos** (equipo de la agencia) con permisos por rol.
+- Panel de **administraciΓ³n SaaS** para el sΓΊper admin (configuraciΓ³n global, lΓmites, monitoreo).
+
+### 2.2 Fuera de alcance inmediato (para fases posteriores)
+
+- GeneraciΓ³n de video avanzada (SORA, Seedream, etc.) como core.
+- Entrenamiento auto-servicio 100% self-service de LoRAs por parte del cliente final (en MVP serΓ‘ gestionado por el equipo tΓ©cnico).
+- Integraciones profundas con mΓΊltiples CRMs externos (inicialmente solo 1 CRM interno y 1 integraciΓ³n externa simple).
+- Marketplace pΓΊblico multi-tenant con planes comerciales complejos.
+
+---
+
+## 3. Perfiles de Usuario
+
+1. **SΓΊper Admin SaaS (DueΓ±o/CTO)**
+ - Acceso ilimitado a todos los mΓ³dulos y recursos (sin restricciones de uso).
+ - Configura parΓ‘metros globales de infraestructura, colas de tareas y modelos.
+ - Gestiona planes/limitaciones (aunque en MVP sΓ³lo se usa el plan interno βilimitadoβ).
+
+2. **Admin de Agencia**
+ - Configura clientes, marcas, equipos y usuarios internos.
+ - Define plantillas y workflows creativos estΓ‘ndar.
+ - Aprueba solicitudes de entrenamiento de modelos personalizados (LoRAs, estilos).
+
+3. **Creativo/Media Buyer**
+ - Crea proyectos y campaΓ±as.
+ - Lanza generaciones de contenido (imΓ‘genes y copys) usando plantillas.
+ - Solicita entrenamiento de modelos personalizados (avatar de marca, producto, estilo).
+ - InteractΓΊa con el sistema para iterar versiones.
+
+4. **Analista/CRM**
+ - Administra leads, contactos, oportunidades y campaΓ±as en CRM.
+ - Dispara automatizaciones (por ejemplo, al crear un nuevo producto).
+ - Consulta mΓ©tricas de campaΓ±as y uso de contenido.
+
+5. **Cliente (externo) β Modo opcional MVP**
+ - Acceso restringido (portal ligero): revisar piezas generadas, aprobar/rechazar, descargar assets.
+ - No lanza generaciones directamente en MVP (esto puede aΓ±adirse en una fase posterior).
+
+---
+
+## 4. MΓ³dulos Funcionales del MVP
+
+### 4.1 MΓ³dulo de GestiΓ³n de Cuentas y Tenants
+
+> Aunque el uso principal es interno, la arquitectura debe soportar **multi-tenant** futuro.
+
+- **Tenant βAgencia Propiaβ** como tenant principal.
+- Estructuras para futuros tenants (clientes/agencias externas) aunque en MVP solo haya uno.
+- ConfiguraciΓ³n por tenant:
+ - Nombre, branding (logo, colores base).
+ - LΓmites de uso (imΓ‘genes mensuales, entrenamientos, etc.) β aunque el tenant interno tenga lΓmites desactivados.
+ - Conexiones a CRM interno y/o externo.
+
+### 4.2 MΓ³dulo CRM Integrado
+
+- **Entidades bΓ‘sicas**:
+ - Contactos (personas).
+ - Empresas / Clientes.
+ - Productos / Servicios.
+ - Oportunidades / Deals.
+ - CampaΓ±as de marketing.
+
+- **Funcionalidades**:
+ - Alta/ediciΓ³n de clientes y contactos.
+ - Registro de oportunidades asociadas a campaΓ±as.
+ - SegmentaciΓ³n bΓ‘sica de leads (por industria, tamaΓ±o, estado, etc.).
+ - Historial de interacciones (notas, actividades, tareas).
+ - Campos clave para conectar con generaciΓ³n de contenido (ej. tipo de producto, fotos de referencia, identidad de marca, tono de comunicaciΓ³n).
+
+- **IntegraciΓ³n**:
+ - API interna para conectarse con el motor de generaciΓ³n (ej. βnuevo producto β generar pack de 5 imΓ‘genes de catΓ‘logo y 3 posts de redesβ).
+ - IntegraciΓ³n mΓnima con 1 CRM externo (ej. webhooks/REST) para sincronizar datos bΓ‘sicos (opcional en MVP).
+
+### 4.3 MΓ³dulo de Proyectos y CampaΓ±as
+
+- **Proyectos**:
+ - Agrupan campaΓ±as y assets por cliente o iniciativa interna.
+ - Estados: Borrador, En curso, En revisiΓ³n, Cerrado.
+
+- **CampaΓ±as**:
+ - Tipos: redes sociales, performance ads, catΓ‘logos, landing pages, etc.
+ - Brief estructurado:
+ - Objetivo de la campaΓ±a.
+ - PΓΊblico objetivo.
+ - Tono de voz.
+ - Canales (IG, FB, TikTok, Google Ads, etc.).
+ - Restricciones (palabras prohibidas, colores de marca, etc.).
+
+- **Flujos del MVP**:
+ - Crear campaΓ±a β seleccionar plantillas de generaciΓ³n (ej. pack de 10 imΓ‘genes + 10 copys).
+ - Disparar generaciΓ³n β monitorizar estado β revisiΓ³n interna β aprobaciΓ³n/entrega.
+
+### 4.4 MΓ³dulo de Motor de GeneraciΓ³n de Contenido (IA)
+
+#### 4.4.1 NΓΊcleo de Modelos y Runtime
+
+- **Modelos locales (open source, auto-hosteados)**:
+ - Modelo principal **text-to-image** tipo **Stable Diffusion XL** o similar, optimizado para marketing.
+ - Checkpoints especializados:
+ - FotografΓa de producto (e-commerce, fondo blanco/contextos comerciales).
+ - Rostros humanos realistas / lifestyle.
+ - Estilos ilustrados (diseΓ±o publicitario, vintage, cartoon, etc.).
+ - **ControlNets / Adaptadores**:
+ - Pose humana (OpenPose) para controlar poses de modelos/influencers.
+ - SegmentaciΓ³n (fondo/primer plano).
+ - Otros de utilidad (canny, depth) para composiciΓ³n y ajustes.
+ - Modelos de **upscaling** para entregar imΓ‘genes en alta resoluciΓ³n (2xβ4x).
+ - Modelos de **inpainting** para correcciones localizadas (ej. arreglar manos, insertar elementos).
+
+- **Modelos de texto (NLP)**:
+ - IntegraciΓ³n con **modelo de lenguaje** (open source o API external) para:
+ - Generar copys, tΓtulos, descripciones, hashtags.
+ - Ajustar tono segΓΊn el brief.
+ - El MVP puede usar un modelo de OpenAI vΓa API para texto, dado su bajo costo relativo.
+
+#### 4.4.2 Workflows de GeneraciΓ³n (ComfyUI / Orquestador)
+
+- Uso de **ComfyUI** como base de construcciΓ³n de flujos de generaciΓ³n y automatizaciΓ³n creativa.
+- DiseΓ±o de varios workflows estΓ‘ndar:
+ 1. **FotografΓa sintΓ©tica de producto**
+ - Entrada: fotos de referencia (opcional), descripciΓ³n de producto, estilo o contexto.
+ - Salida: pack de imΓ‘genes listas para catΓ‘logo y redes.
+ 2. **Post de redes sociales (imagen + copy)**
+ - Entrada: brief corto, producto/servicio, canal objetivo.
+ - Salida: 1βN imΓ‘genes + textos sugeridos.
+ 3. **Influencer virtual / avatar de marca** (ver mΓ‘s abajo).
+ 4. **Variaciones de anuncio**
+ - GeneraciΓ³n de mΓΊltiples variantes (colores, encuadres, fondos) para pruebas A/B.
+
+- ExposiciΓ³n de estos workflows como **APIs internas** (ComfyDeploy u otro mecanismo) para que el backend los consuma.
+
+#### 4.4.3 PersonalizaciΓ³n de Identidad Visual y Avatares
+
+- **LoRAs / Fine-tuning**:
+ - Entrenamiento dirigido por el equipo tΓ©cnico de:
+ - Estilos de marca.
+ - Productos especΓficos (lΓneas completas de producto).
+ - Avatares e influencers virtuales (rostros/personajes consistentes).
+ - Interfaz para:
+ - Registrar un βModelo personalizadoβ (LoRA/Checkpoint).
+ - Asignarlo a una marca/cliente.
+ - Seleccionarlo en plantillas de generaciΓ³n.
+
+- **Consistencia de personajes**:
+ - Uso de image prompts, IP-Adapters y nodos tipo Consistent Characters para mantener la misma apariencia a travΓ©s de mΓΊltiples piezas.
+ - Flujos de βreciclaje de referenciaβ: la ΓΊltima imagen aprobada de un avatar se reutiliza como referencia para nuevas generaciones.
+
+#### 4.4.4 GeneraciΓ³n con Texto Integrado en la Imagen
+
+- **Modo base (open source)**:
+ - Mejor esfuerzo con SDXL + tΓ©cnicas complementarias (inpainting, ControlNet, postprocesado).
+ - Alternativa hΓbrida: generar imagen base y superponer texto con capa vectorial (HTML/CSS/Canvas) desde el front.
+
+- **Modo premium vΓa API (opcional)**:
+ - IntegraciΓ³n con algΓΊn modelo propietario tipo **Gemini 3 Pro Image (Nano Banana Pro)** u otro similar para casos en que se requiera texto perfectamente legible integrado (posters densos, infografΓas).
+ - Expuesto al usuario como opciΓ³n βCalidad premium de textoβ.
+
+#### 4.4.5 Contenido Animado y Video (MVP reducido)
+
+- MVP:
+ - CreaciΓ³n de **GIFs/cinemagraphs** a partir de secuencias de imΓ‘genes generadas.
+ - Pipeline bΓ‘sico de βfotogramas clave + interpolaciΓ³nβ (usando herramientas IA cuando sea viable).
+
+- Futuro (fuera del MVP, pero preparado en arquitectura):
+ - IntegraciΓ³n con APIs de texto-a-video (Runway, Seedream, SORA, etc.).
+ - IntegraciΓ³n con servicios de avatares parlantes (HeyGen u otros).
+
+---
+
+### 4.5 MΓ³dulo de AutomatizaciΓ³n Creativa y Flujos (OrquestaciΓ³n)
+
+- IntegraciΓ³n con un orquestador tipo **n8n** o similar para automatizar tareas entre:
+ - CRM interno.
+ - Motor de generaciΓ³n de contenido.
+ - Sistemas externos (por ejemplo, herramientas de email marketing, redes sociales).
+
+- Flujos MVP:
+ 1. **Nuevo producto en CRM β Generar Kit de Assets**
+ - Dispara workflow de fotografΓa de producto + posts base.
+ 2. **Nueva campaΓ±a β Generar lote de creatividades**
+ - Crea assets iniciales para revisiΓ³n interna.
+ 3. **Cambio de estado de campaΓ±a (Aprobada) β NotificaciΓ³n/Entrega**
+ - Notifica a responsables; genera zip descargable o publica en espacio compartido.
+
+- Sistema de **colas de tareas**:
+ - DistribuciΓ³n de trabajos en GPU(s).
+ - Manejo de prioridades (trabajos urgentes vs batch).
+
+---
+
+### 4.6 MΓ³dulo de Biblioteca de Activos (DAM)
+
+- Repositorio central de:
+ - ImΓ‘genes generadas.
+ - Copys, prompts y briefs.
+ - Modelos personalizados (LoRAs, checkpoints, presets de workflows).
+
+- Funciones:
+ - BΓΊsqueda avanzada (por cliente, campaΓ±a, tags, tipo de contenido, fecha).
+ - Versionado de assets (iteraciones sobre una misma pieza).
+ - Estados: borrador, en revisiΓ³n, aprobado, publicado.
+ - Descarga individual o en paquetes.
+
+---
+
+### 4.7 MΓ³dulo de AdministraciΓ³n SaaS y ConfiguraciΓ³n
+
+- GestiΓ³n de:
+ - Usuarios, roles y permisos.
+ - Tenants (al menos el tenant βAgencia Propiaβ en el MVP).
+ - ParΓ‘metros globales:
+ - LΓmites de tamaΓ±o/formatos de salida.
+ - Modelos activos/inactivos.
+ - PolΓtica de retenciΓ³n de assets.
+
+- AuditorΓa bΓ‘sica:
+ - Log de acciones relevantes (generaciones, entrenamientos, cambios de configuraciΓ³n).
+ - MΓ©tricas de uso por usuario y campaΓ±a (nΓΊmero de imΓ‘genes generadas, GPU time estimado, etc.).
+
+- PreparaciΓ³n para **planes de suscripciΓ³n** (aunque en MVP no se comercializa externamente):
+ - Estructura para planes (Free, Pro, Enterprise, Interno Ilimitado).
+ - ParΓ‘metros por plan: generaciones/mes, entrenamientos, acceso a modo premium de texto, etc.
+
+---
+
+### 4.8 MΓ³dulo de AnalΓtica y Reporting
+
+- **Dashboards bΓ‘sicos**:
+ - Volumen de contenido generado por periodo, cliente, campaΓ±a.
+ - Tiempo promedio de generaciΓ³n y aprobaciΓ³n.
+ - Uso de modelos personalizados (cuΓ‘ntas campaΓ±as usan cada LoRA/estilo).
+ - RelaciΓ³n entre campaΓ±as y assets generados (para anΓ‘lisis posterior de performance).
+
+- **KPI iniciales**:
+ - NΒΊ de campaΓ±as activas.
+ - NΒΊ de assets por campaΓ±a.
+ - Porcentaje de assets aprobados en primera iteraciΓ³n.
+
+- ExportaciΓ³n:
+ - Descarga de reportes en CSV/Excel.
+ - API para integraciΓ³n con herramientas de BI.
+
+---
+
+### 4.9 MΓ³dulo de Seguridad, Permisos y Cumplimiento
+
+- **AutenticaciΓ³n y autorizaciΓ³n**:
+ - Login con email + password (mΓ‘s adelante SSO/OAuth).
+ - Roles y permisos por mΓ³dulo/acciΓ³n (RBAC).
+
+- **Aislamiento lΓ³gico por tenant** pese a que inicialmente sΓ³lo se use uno.
+- **GestiΓ³n de datos sensibles**:
+ - Cifrado en trΓ‘nsito (HTTPS).
+ - Buenas prΓ‘cticas de manejo de imΓ‘genes de personas (consentimiento, uso de datos, etc.).
+
+---
+
+## 5. Requisitos TΓ©cnicos de Alto Nivel
+
+### 5.1 Infraestructura
+
+- Servidor con **GPU dedicada** (idealmente 12β24 GB VRAM) para ejecutar los modelos de imagen (SDXL, LoRAs, ControlNets, upscaling).
+- Arquitectura con:
+ - **Backend monolΓtico** (API REST/GraphQL) para lΓ³gica de negocio, colas y orquestaciΓ³n.
+ - **Servicio(s) de inferencia** (ComfyUI/Deploy, pipelines Diffusers, etc.) comunicados vΓa HTTP/ gRPC.
+ - **Base de datos** relacional para CRM, proyectos, campaΓ±as, usuarios, configuraciΓ³n.
+ - Almacenamiento de archivos (local o S3-compatible) para assets e imΓ‘genes generadas.
+
+- Sistema de **colado y scheduling de tareas**:
+ - GestiΓ³n eficiente de jobs de generaciΓ³n y entrenamiento.
+ - Posibilidad de aΓ±adir mΓ‘s GPUs/instancias a futuro.
+
+### 5.2 Integraciones Clave
+
+- Orquestador (n8n u otro) para flujos entre mΓ³dulos.
+- APIs externas **opcionales**:
+ - Modelos de texto avanzados (LLMs).
+ - Modelos de imΓ‘genes con texto perfecto (Gemini/Seedream u otros) β sΓ³lo para casos premium.
+ - Servicios de video/avatares (etapa futura).
+
+---
+
+## 6. Roadmap de EvoluciΓ³n (en alto nivel)
+
+> No forma parte estricta del MVP, pero orienta el desglose posterior.
+
+1. **Fase 1 β Core MVP**
+ - MΓ³dulos: usuarios/roles, CRM bΓ‘sico, proyectos y campaΓ±as, motor de generaciΓ³n de imΓ‘genes + copys, DAM bΓ‘sico.
+ - Workflows estΓ‘ndar de generaciΓ³n de producto y posts.
+
+2. **Fase 2 β PersonalizaciΓ³n Avanzada**
+ - Entrenamiento recurrente de LoRAs/estilos.
+ - Avatares/influencers virtuales consistentes.
+ - IntegraciΓ³n mΓ‘s profunda con CRM e orquestador.
+
+3. **Fase 3 β Contenido Enriquecido y Multi-tenant Comercial**
+ - Video, avatares parlantes, modos premium con APIs externas.
+ - Apertura a clientes externos (modo SaaS completo).
+ - Planes de suscripciΓ³n y lΓmites de uso.
diff --git a/projects/platform_marketing_content/docs/00-vision-general/VISION-GENERAL.md b/projects/platform_marketing_content/docs/00-vision-general/VISION-GENERAL.md
new file mode 100644
index 0000000..33ce7df
--- /dev/null
+++ b/projects/platform_marketing_content/docs/00-vision-general/VISION-GENERAL.md
@@ -0,0 +1,466 @@
+# Platform Marketing Content - Plataforma SaaS de Generaciθ΄Έn de Contenido y CRM Creativo
+
+**Versiθ΄Έn:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** Fase de Anθ°©lisis y Documentaciθ΄Έn
+**Modelo de Negocio:** SaaS Multi-tenant (uso interno inicial)
+
+---
+
+## 1. Resumen Ejecutivo
+
+### 1.1 Visiθ΄Έn del Producto
+
+**Platform Marketing Content** es una plataforma SaaS interna para **agencias de publicidad y generaciθ΄Έn de contenido** que combina:
+
+1. **Motor de Generaciθ΄Έn de Contenido con IA** - Imθ°©genes, copys, posts para redes sociales
+2. **CRM Integrado** - Gestiθ΄Έn de clientes, marcas, campaεΈ½as y oportunidades
+3. **Automatizaciθ΄Έn Creativa** - Flujos desde brief ι«? contenido ι«? aprobaciθ΄Έn ι«? entrega
+4. **DAM (Digital Asset Management)** - Biblioteca centralizada de activos generados
+
+### 1.2 Propuesta de Valor
+
+| Problema Actual | Soluciθ΄Έn Propuesta |
+|-----------------|-------------------|
+| Creaciθ΄Έn manual de contenido visual costosa y lenta | Generaciθ΄Έn automθ°©tica con IA (Stable Diffusion, ComfyUI) |
+| Dependencia de fotθ΄Έgrafos y sets fιsicos | Fotografιa sintθ
tica de productos hiperrealista |
+| Inconsistencia de marca entre campaεΈ½as | LoRAs entrenados por marca/producto |
+| Gestiθ΄Έn fragmentada de clientes y campaεΈ½as | CRM integrado con motor de generaciθ΄Έn |
+| Costos elevados por APIs comerciales (Midjourney, DALL-E) | Modelos open-source auto-hosteados |
+| Flujos manuales de aprobaciθ΄Έn | Automatizaciθ΄Έn con n8n + workflows predefinidos |
+
+### 1.3 Diferenciadores Clave
+
+```
+ι? Modelos Open Source + Auto-hosting = Costos controlados
+ι? LoRAs personalizados por marca = Consistencia visual
+ι? CRM + Generaciθ΄Έn integrados = Flujo end-to-end
+ι? ComfyUI como orquestador = Workflows visuales y escalables
+ι? Arquitectura preparada para multi-tenant = Escalabilidad futura
+```
+
+---
+
+## 2. Objetivos del MVP
+
+### 2.1 Objetivos de Negocio
+
+| Objetivo | Mθ
trica de θ‘xito | Plazo |
+|----------|------------------|-------|
+| Reducir tiempo de creaciθ΄Έn de contenido | -70% tiempo vs proceso manual | MVP |
+| Eliminar dependencia de servicios externos | 100% generaciθ΄Έn local | MVP |
+| Centralizar gestiθ΄Έn de clientes y campaεΈ½as | 1 plataforma unificada | MVP |
+| Habilitar personalizaciθ΄Έn por marca | LoRAs entrenados por cliente | Fase 2 |
+
+### 2.2 Objetivos Tθ
cnicos
+
+| Objetivo | Descripciθ΄Έn |
+|----------|-------------|
+| **Auto-hosting** | Ejecutar modelos en GPU dedicada (12-24GB VRAM) |
+| **Arquitectura modular** | Separaciθ΄Έn clara: CRM, Motor IA, DAM, Automatizaciθ΄Έn |
+| **Multi-tenant ready** | Estructura preparada para mη
€ltiples tenants |
+| **API-first** | Todos los servicios expuestos vιa REST/GraphQL |
+| **Escalabilidad** | Colas de tareas, distribuciθ΄Έn en GPUs |
+
+---
+
+## 3. Alcance del MVP
+
+### 3.1 Incluido en MVP (Fase 1)
+
+| Mθ΄Έdulo | Funcionalidades Core |
+|--------|---------------------|
+| **CRM Integrado** | Clientes, marcas, productos, campaεΈ½as, oportunidades |
+| **Motor de Generaciθ΄Έn** | Text-to-image (SDXL), copys con LLM, upscaling |
+| **Workflows Creativos** | Fotografιa de producto, posts para redes, variaciones |
+| **DAM Bθ°©sico** | Repositorio de imθ°©genes, bη
€squeda, estados (borrador/aprobado) |
+| **Automatizaciθ΄Έn Bθ°©sica** | Triggers CRM ι«? Generaciθ΄Έn |
+| **Admin SaaS** | Usuarios, roles, configuraciθ΄Έn global |
+
+### 3.2 Fuera de Alcance MVP (Fases Posteriores)
+
+| Feature | Fase Planificada |
+|---------|------------------|
+| Generaciθ΄Έn de video avanzada (SORA, Seedream) | Fase 3 |
+| Entrenamiento self-service de LoRAs | Fase 2 |
+| Marketplace multi-tenant pη
€blico | Fase 4 |
+| Integraciones profundas con CRMs externos | Fase 2 |
+| Avatares parlantes (HeyGen, etc.) | Fase 3 |
+| Texto perfecto en imθ°©genes (Gemini API) | Fase 2 (opcional) |
+
+---
+
+## 4. Perfiles de Usuario
+
+### 4.1 Usuarios Internos (MVP)
+
+| Perfil | Descripciθ΄Έn | Permisos Principales |
+|--------|-------------|---------------------|
+| **Sη
€per Admin SaaS** | DueεΈ½o/CTO de la plataforma | Acceso ilimitado, configuraciθ΄Έn global, modelos |
+| **Admin de Agencia** | Configura clientes, equipos, plantillas | Gestiθ΄Έn de usuarios, workflows, aprobaciones |
+| **Creativo/Media Buyer** | Lanza generaciones, itera versiones | Crear proyectos, generar contenido, solicitar LoRAs |
+| **Analista/CRM** | Gestiona leads, campaεΈ½as, mθ
tricas | CRM completo, triggers de automatizaciθ΄Έn |
+
+### 4.2 Usuarios Externos (Opcional MVP)
+
+| Perfil | Descripciθ΄Έn | Permisos |
+|--------|-------------|----------|
+| **Cliente (portal ligero)** | Revisa piezas, aprueba/rechaza | Solo lectura + aprobaciθ΄Έn |
+
+---
+
+## 5. Mθ΄Έdulos Funcionales
+
+### 5.1 Mθ΄Έdulo 1: Gestiθ΄Έn de Cuentas y Tenants (PMC-001)
+
+**Objetivo:** Arquitectura multi-tenant preparada para escalar.
+
+```yaml
+Funcionalidades:
+ - Tenant principal "Agencia Propia"
+ - Estructura para futuros tenants externos
+ - Configuraciθ΄Έn por tenant: branding, lιmites, conexiones
+ - Lιmites de uso (imθ°©genes/mes, entrenamientos)
+```
+
+### 5.2 Mθ΄Έdulo 2: CRM Integrado (PMC-002)
+
+**Objetivo:** Gestionar clientes, marcas y campaεΈ½as con conexiθ΄Έn directa al motor de generaciθ΄Έn.
+
+```yaml
+Entidades:
+ - Contactos (personas)
+ - Empresas/Clientes
+ - Marcas (brand identity, tono, restricciones)
+ - Productos/Servicios
+ - Oportunidades/Deals
+ - CampaεΈ½as de Marketing
+
+Funcionalidades:
+ - Alta/ediciθ΄Έn de clientes y contactos
+ - Segmentaciθ΄Έn de leads
+ - Historial de interacciones
+ - Campos para generaciθ΄Έn: fotos referencia, identidad marca, tono
+ - API interna ι«? motor de generaciθ΄Έn
+```
+
+### 5.3 Mθ΄Έdulo 3: Proyectos y CampaεΈ½as (PMC-003)
+
+**Objetivo:** Organizar el trabajo creativo por iniciativa.
+
+```yaml
+Proyectos:
+ - Agrupan campaεΈ½as y assets por cliente
+ - Estados: Borrador, En curso, En revisiθ΄Έn, Cerrado
+
+CampaεΈ½as:
+ - Tipos: redes sociales, performance ads, catθ°©logos, landing pages
+ - Brief estructurado:
+ - Objetivo de campaεΈ½a
+ - Pη
€blico objetivo
+ - Tono de voz
+ - Canales (IG, FB, TikTok, Google Ads)
+ - Restricciones (palabras prohibidas, colores marca)
+
+Flujos:
+ - Crear campaεΈ½a ι«? seleccionar plantillas ι«? disparar generaciθ΄Έn ι«? revisiθ΄Έn ι«? entrega
+```
+
+### 5.4 Mθ΄Έdulo 4: Motor de Generaciθ΄Έn de Contenido IA (PMC-004)
+
+**Objetivo:** Nη
€cleo de generaciθ΄Έn de imθ°©genes y copys.
+
+```yaml
+4.1 Modelos Locales (Open Source):
+ Imagen:
+ - Stable Diffusion XL (principal)
+ - Checkpoints especializados:
+ - Fotografιa de producto (e-commerce)
+ - Rostros humanos realistas
+ - Estilos ilustrados (publicidad, vintage)
+ - ControlNets: OpenPose, segmentaciθ΄Έn, canny, depth
+ - Upscaling: 2x-4x
+ - Inpainting: correcciones localizadas
+
+ Texto (NLP):
+ - LLM para copys, tιtulos, hashtags
+ - Ajuste de tono segη
€n brief
+ - OpenAI API (bajo costo) o modelo local
+
+4.2 Workflows ComfyUI:
+ Predefinidos:
+ - Fotografιa sintθ
tica de producto
+ - Post redes sociales (imagen + copy)
+ - Variaciones de anuncio (A/B testing)
+ - Influencer virtual / avatar de marca
+
+ Caracterιsticas:
+ - Exposiciθ΄Έn como APIs internas (ComfyDeploy)
+ - Workflows personalizables por usuario
+
+4.3 Personalizaciθ΄Έn (LoRAs):
+ - Entrenamiento dirigido por equipo tθ
cnico:
+ - Estilos de marca
+ - Productos especιficos
+ - Avatares/influencers virtuales
+ - Interfaz para registrar y asignar modelos personalizados
+ - Consistencia de personajes (IP-Adapters, Consistent Characters)
+
+4.4 Texto en Imθ°©genes:
+ Modo base:
+ - SDXL + tθ
cnicas complementarias
+ - Superposiciθ΄Έn vectorial (HTML/CSS/Canvas)
+ Modo premium (opcional):
+ - API Gemini 3 Pro Image para tipografιa perfecta
+```
+
+### 5.5 Mθ΄Έdulo 5: Automatizaciθ΄Έn Creativa (PMC-005)
+
+**Objetivo:** Conectar CRM con motor de generaciθ΄Έn mediante flujos automatizados.
+
+```yaml
+Orquestador: n8n (o similar)
+
+Flujos MVP:
+ 1. Nuevo producto en CRM ι«? Generar Kit de Assets
+ - Dispara workflow de fotografιa + posts base
+
+ 2. Nueva campaεΈ½a ι«? Generar lote de creatividades
+ - Crea assets iniciales para revisiθ΄Έn
+
+ 3. Cambio estado campaεΈ½a (Aprobada) ι«? Notificaciθ΄Έn/Entrega
+ - Notifica responsables
+ - Genera zip descargable
+
+Sistema de Colas:
+ - Distribuciθ΄Έn de jobs en GPU(s)
+ - Manejo de prioridades (urgente vs batch)
+```
+
+### 5.6 Mθ΄Έdulo 6: Biblioteca de Activos DAM (PMC-006)
+
+**Objetivo:** Repositorio central de contenido generado.
+
+```yaml
+Contenido:
+ - Imθ°©genes generadas
+ - Copys, prompts, briefs
+ - Modelos personalizados (LoRAs, checkpoints, presets)
+
+Funciones:
+ - Bη
€squeda avanzada (cliente, campaεΈ½a, tags, tipo, fecha)
+ - Versionado de assets
+ - Estados: borrador, en revisiθ΄Έn, aprobado, publicado
+ - Descarga individual o en paquetes
+```
+
+### 5.7 Mθ΄Έdulo 7: Administraciθ΄Έn SaaS (PMC-007)
+
+**Objetivo:** Panel de control de la plataforma.
+
+```yaml
+Gestiθ΄Έn:
+ - Usuarios, roles, permisos (RBAC)
+ - Tenants (al menos "Agencia Propia" en MVP)
+ - Parθ°©metros globales:
+ - Lιmites de tamaεΈ½o/formatos
+ - Modelos activos/inactivos
+ - Polιtica de retenciθ΄Έn de assets
+
+Auditorιa:
+ - Log de acciones (generaciones, entrenamientos, cambios)
+ - Mθ
tricas de uso por usuario y campaεΈ½a
+
+Preparaciθ΄Έn para planes:
+ - Estructura: Free, Pro, Enterprise, Interno Ilimitado
+ - Parθ°©metros por plan: generaciones/mes, entrenamientos, etc.
+```
+
+### 5.8 Mθ΄Έdulo 8: Analιtica y Reporting (PMC-008)
+
+**Objetivo:** Visibilidad del rendimiento y uso.
+
+```yaml
+Dashboards:
+ - Volumen generado por periodo/cliente/campaεΈ½a
+ - Tiempo promedio de generaciθ΄Έn y aprobaciθ΄Έn
+ - Uso de modelos personalizados
+ - Relaciθ΄Έn campaεΈ½as-assets
+
+KPIs Iniciales:
+ - Nη
€mero de campaεΈ½as activas
+ - Assets por campaεΈ½a
+ - % assets aprobados en primera iteraciθ΄Έn
+
+Exportaciθ΄Έn:
+ - CSV/Excel
+ - API para herramientas BI
+```
+
+---
+
+## 6. Requisitos Tθ
cnicos
+
+### 6.1 Stack Tecnolθ΄Έgico
+
+```yaml
+Backend:
+ - Node.js 20+ / NestJS + TypeScript
+ - PostgreSQL 15+ (multi-tenant ready)
+ - Redis (caching, colas)
+ - Bull/BullMQ (jobs de generaciθ΄Έn)
+
+Frontend:
+ - React 18 + Vite + TypeScript
+ - TailwindCSS / Shadcn UI
+ - React Query (data fetching)
+
+Motor IA:
+ - ComfyUI (orquestaciθ΄Έn de workflows)
+ - ComfyDeploy (API de inferencia)
+ - Stable Diffusion XL + checkpoints
+ - Python 3.10+ / Diffusers (alternativa)
+
+Automatizaciθ΄Έn:
+ - n8n (flujos entre mθ΄Έdulos)
+
+Almacenamiento:
+ - S3 / MinIO (assets e imθ°©genes)
+ - PostgreSQL (metadata, CRM)
+
+Infraestructura:
+ - Docker / Docker Compose
+ - GPU: NVIDIA 12-24GB VRAM (L4, RTX 3090/4090, A5000)
+```
+
+### 6.2 Arquitectura de Alto Nivel
+
+```
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? Frontend (React + Vite) ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι?
+ ι»?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? Backend API (NestJS) ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ι? ι? CRM ι? ι? Projectsι? ι? Assets ι? ι?
+ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι? ι? ι?
+ ι»? ι»? ι»?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ι? PostgreSQL ι? ι? ComfyUI ι? ι? n8n ι?
+ι? + Redis ι? ι? (GPU GPU) ι? ι? (Workflows) ι?
+ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι? ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι?
+ ι»?
+ ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+ ι? S3/MinIO ι?
+ ι? (Assets) ι?
+ ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ιζΊζ’ι?
+```
+
+### 6.3 Integraciones Clave
+
+| Integraciθ΄Έn | Prioridad | Descripciθ΄Έn |
+|-------------|-----------|-------------|
+| ComfyUI / ComfyDeploy | Alta | Motor de workflows de generaciθ΄Έn |
+| n8n | Alta | Orquestaciθ΄Έn de automatizaciones |
+| OpenAI API | Media | LLM para generaciθ΄Έn de copys |
+| Gemini API | Baja | Texto perfecto en imθ°©genes (opcional) |
+| CRM Externo | Baja | Sincronizaciθ΄Έn bθ°©sica via webhooks |
+
+---
+
+## 7. Roadmap
+
+### Fase 1: MVP Core (Semanas 1-8)
+
+```yaml
+Entregables:
+ - Arquitectura base (backend + frontend)
+ - CRM bθ°©sico (clientes, marcas, productos)
+ - Motor de generaciθ΄Έn con 2-3 workflows
+ - DAM bθ°©sico
+ - Admin de usuarios y roles
+
+Mθ
trica de θ‘xito:
+ - Generar 100 imθ°©genes de producto
+ - 3 campaεΈ½as completas end-to-end
+```
+
+### Fase 2: Personalizaciθ΄Έn Avanzada (Semanas 9-14)
+
+```yaml
+Entregables:
+ - Entrenamiento de LoRAs por marca
+ - Avatares/influencers virtuales consistentes
+ - Integraciθ΄Έn profunda CRM ι«? Generaciθ΄Έn
+ - Workflows adicionales
+
+Mθ
trica de θ‘xito:
+ - 5 LoRAs entrenados por marca
+ - 90% consistencia en personajes
+```
+
+### Fase 3: Contenido Enriquecido (Semanas 15-22)
+
+```yaml
+Entregables:
+ - GIFs/cinemagraphs
+ - Integraciθ΄Έn de video bθ°©sico
+ - APIs premium opcionales (Gemini para texto)
+ - Portal cliente externo
+
+Mθ
trica de θ‘xito:
+ - 50% de campaεΈ½as con contenido animado
+ - 3 clientes externos usando portal
+```
+
+### Fase 4: Multi-tenant Comercial (Semanas 23+)
+
+```yaml
+Entregables:
+ - Apertura a clientes externos (SaaS completo)
+ - Planes de suscripciθ΄Έn y lιmites
+ - Marketplace de extensiones
+
+Mθ
trica de θ‘xito:
+ - 10 tenants activos
+ - MRR positivo
+```
+
+---
+
+## 8. Riesgos y Mitigaciones
+
+| Riesgo | Impacto | Probabilidad | Mitigaciθ΄Έn |
+|--------|---------|--------------|------------|
+| Calidad de generaciθ΄Έn insuficiente | Alto | Media | Checkpoints especializados, postprocesado |
+| Requisitos de GPU elevados | Medio | Alta | Optimizaciθ΄Έn de modelos, colas de prioridad |
+| Texto ilegible en imθ°©genes | Medio | Alta | Modo hιbrido (IA + superposiciθ΄Έn) |
+| Inconsistencia de personajes | Medio | Media | LoRAs + IP-Adapters + image prompts |
+| Complejidad de ComfyUI | Medio | Media | Workflows pre-construidos, documentaciθ΄Έn |
+
+---
+
+## 9. Referencias
+
+### 9.1 Documentaciθ΄Έn del Proyecto
+
+- [MVP Original](./MVP_Plataforma_SaaS_Contenido_CRM.md) - Definiciθ΄Έn inicial
+- [Investigaciθ΄Έn Morfeo Academy](./Investigaciθ΄Έn%20Profunda_%20Plataforma%20de%20Generaciθ΄Έn%20de%20Contenido%20de%20Morfeo%20Academy%20y%20Desarrollo%20de%20una%20.pdf) - Anθ°©lisis de referencia
+
+### 9.2 Tecnologιas de Referencia
+
+- [Morfeo Academy](https://www.morfeoacademy.com/) - Referencia de plataforma similar
+- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - Motor de workflows
+- [ComfyDeploy](https://www.comfydeploy.com/) - API de inferencia
+- [Stable Diffusion XL](https://stability.ai/) - Modelo base de generaciθ΄Έn
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
+**Prθ΄Έxima revisiθ΄Έn:** Al completar Fase 1
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-001-TENANTS.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-001-TENANTS.md
new file mode 100644
index 0000000..986b4c9
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-001-TENANTS.md
@@ -0,0 +1,275 @@
+# 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: PatrΓ³n base multi-tenancy (adaptar)
+
+Dependencias de MΓ³dulos:
+ - PMC-007 Admin: GestiΓ³n de planes y configuraciΓ³n global
+
+Servicios Externos:
+ - Ninguno requerido
+```
+
+---
+
+## 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](../../../core/catalog/modules/multi-tenancy/)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-002-CRM.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-002-CRM.md
new file mode 100644
index 0000000..ed3ce07
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-002-CRM.md
@@ -0,0 +1,387 @@
+# PMC-002: MΓ³dulo CRM
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Alta
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo CRM (Customer Relationship Management) gestiona clientes, marcas, productos y la relaciΓ³n entre estos elementos. EstΓ‘ diseΓ±ado para integrarse directamente con el motor de generaciΓ³n de contenido IA.
+
+---
+
+## Objetivos
+
+1. Gestionar clientes y contactos de la agencia
+2. Organizar marcas y productos por cliente
+3. Almacenar identidad visual y lineamientos de marca
+4. Registrar oportunidades comerciales
+5. Conectar datos de CRM con generaciΓ³n de contenido
+
+---
+
+## Entidades del Dominio
+
+### Client
+
+```yaml
+Entidad: Client
+DescripciΓ³n: Empresa/organizaciΓ³n cliente de la agencia
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - legal_name: string
+ - tax_id: string (RFC/NIF)
+ - industry: string
+ - size: enum [micro, small, medium, large, enterprise]
+ - website: string
+ - status: enum [prospect, active, inactive, churned]
+ - notes: text
+ - metadata: JSONB
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - 1:N con Contact
+ - 1:N con Brand
+ - 1:N con Opportunity
+ - 1:N con Project
+```
+
+### Contact
+
+```yaml
+Entidad: Contact
+DescripciΓ³n: Persona de contacto en un cliente
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - client_id: UUID (FK)
+ - first_name: string
+ - last_name: string
+ - email: string
+ - phone: string
+ - position: string
+ - department: string
+ - is_primary: boolean
+ - status: enum [active, inactive]
+ - metadata: JSONB
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Client
+ - N:1 con Tenant
+```
+
+### Brand
+
+```yaml
+Entidad: Brand
+DescripciΓ³n: Marca de un cliente con su identidad visual
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - client_id: UUID (FK)
+ - name: string
+ - description: text
+ - status: enum [active, inactive]
+ - identity: JSONB
+ - logo_url: string
+ - logo_variations: array
+ - primary_color: string
+ - secondary_colors: array
+ - typography: object
+ - tone_of_voice: string (formal, casual, playful, etc.)
+ - keywords: array
+ - forbidden_words: array
+ - visual_style: string
+ - lora_models: array[UUID] (referencias a modelos entrenados)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Client
+ - N:1 con Tenant
+ - 1:N con Product
+ - 1:N con Campaign
+ - N:N con CustomModel (LoRAs)
+```
+
+### Product
+
+```yaml
+Entidad: Product
+DescripciΓ³n: Producto o servicio de una marca
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - brand_id: UUID (FK)
+ - name: string
+ - sku: string
+ - description: text
+ - category: string
+ - status: enum [active, discontinued, coming_soon]
+ - attributes: JSONB
+ - price: decimal
+ - features: array
+ - target_audience: string
+ - use_cases: array
+ - reference_images: array[string] (URLs)
+ - lora_model_id: UUID (modelo especΓfico del producto)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Brand
+ - N:1 con Tenant
+ - 1:N con Asset (imΓ‘genes generadas)
+```
+
+### Opportunity
+
+```yaml
+Entidad: Opportunity
+DescripciΓ³n: Oportunidad de negocio/deal
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - client_id: UUID (FK)
+ - contact_id: UUID (FK, opcional)
+ - name: string
+ - description: text
+ - value: decimal
+ - currency: string
+ - stage: enum [lead, qualified, proposal, negotiation, won, lost]
+ - probability: integer (0-100)
+ - expected_close_date: date
+ - actual_close_date: date
+ - lost_reason: string
+ - notes: text
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Client
+ - N:1 con Contact
+ - N:1 con Tenant
+ - 1:N con Project (al convertirse)
+```
+
+---
+
+## Funcionalidades
+
+### F-002.1: GestiΓ³n de Clientes
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-002.1.1 | CRUD Clientes | Alta, ediciΓ³n, listado, eliminaciΓ³n | Alta |
+| F-002.1.2 | BΓΊsqueda y filtros | Por nombre, industria, estado | Alta |
+| F-002.1.3 | Vista de cliente | Dashboard con marcas, contactos, proyectos | Alta |
+| F-002.1.4 | Historial | Timeline de actividades y cambios | Media |
+
+### F-002.2: GestiΓ³n de Contactos
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-002.2.1 | CRUD Contactos | GestiΓ³n de personas de contacto | Alta |
+| F-002.2.2 | Contacto primario | Marcar contacto principal por cliente | Media |
+| F-002.2.3 | Directorio | Vista consolidada de todos los contactos | Media |
+
+### F-002.3: GestiΓ³n de Marcas
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-002.3.1 | CRUD Marcas | Alta y gestiΓ³n de marcas | Alta |
+| F-002.3.2 | Identidad visual | Definir colores, tipografΓa, tono | Alta |
+| F-002.3.3 | Brand guidelines | Subir y almacenar guΓas de marca | Media |
+| F-002.3.4 | Asociar LoRAs | Vincular modelos entrenados a marca | Alta |
+
+### F-002.4: GestiΓ³n de Productos
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-002.4.1 | CRUD Productos | Alta y gestiΓ³n de productos | Alta |
+| F-002.4.2 | ImΓ‘genes referencia | Subir fotos del producto real | Alta |
+| F-002.4.3 | CatΓ‘logo | Vista de productos por marca | Media |
+| F-002.4.4 | Trigger generaciΓ³n | BotΓ³n "Generar pack de imΓ‘genes" | Alta |
+
+### F-002.5: Pipeline de Ventas
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-002.5.1 | CRUD Oportunidades | GestiΓ³n de deals | Media |
+| F-002.5.2 | Kanban pipeline | Vista drag & drop por etapas | Media |
+| F-002.5.3 | Convertir a proyecto | Crear proyecto desde oportunidad ganada | Media |
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-002.1:
+ DescripciΓ³n: Cliente debe tener al menos un contacto
+ ValidaciΓ³n: Warning si no hay contactos, no bloquea
+
+RN-002.2:
+ DescripciΓ³n: Marca requiere identidad visual mΓnima
+ ValidaciΓ³n: Al menos logo_url o primary_color definido
+
+RN-002.3:
+ DescripciΓ³n: Producto hereda identidad de su marca
+ Comportamiento: Si no tiene LoRA propio, usa el de la marca
+
+RN-002.4:
+ DescripciΓ³n: Oportunidad ganada puede generar proyecto
+ AcciΓ³n: BotΓ³n "Crear proyecto" disponible en stage=won
+
+RN-002.5:
+ DescripciΓ³n: Datos de marca se inyectan en generaciΓ³n
+ Comportamiento: Al generar contenido, se cargan automΓ‘ticamente colores, tono, keywords
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/crm
+
+# Clients
+POST /clients
+GET /clients
+GET /clients/:id
+PUT /clients/:id
+DELETE /clients/:id
+GET /clients/:id/brands
+GET /clients/:id/contacts
+GET /clients/:id/projects
+
+# Contacts
+POST /contacts
+GET /contacts
+GET /contacts/:id
+PUT /contacts/:id
+DELETE /contacts/:id
+
+# Brands
+POST /brands
+GET /brands
+GET /brands/:id
+PUT /brands/:id
+DELETE /brands/:id
+GET /brands/:id/products
+POST /brands/:id/loras # Asociar LoRA
+DELETE /brands/:id/loras/:loraId # Desasociar LoRA
+
+# Products
+POST /products
+GET /products
+GET /products/:id
+PUT /products/:id
+DELETE /products/:id
+POST /products/:id/generate # Trigger generaciΓ³n
+
+# Opportunities
+POST /opportunities
+GET /opportunities
+GET /opportunities/:id
+PUT /opportunities/:id
+DELETE /opportunities/:id
+POST /opportunities/:id/convert # Convertir a proyecto
+```
+
+---
+
+## Integraciones
+
+### Con Motor de GeneraciΓ³n (PMC-004)
+
+```yaml
+Trigger: POST /products/:id/generate
+Payload:
+ product_id: UUID
+ brand_id: UUID
+ workflow_template: string
+ options:
+ quantity: number
+ formats: array
+
+Comportamiento:
+ 1. Cargar datos de producto (nombre, descripciΓ³n, referencias)
+ 2. Cargar identidad de marca (colores, tono, LoRAs)
+ 3. Encolar job de generaciΓ³n con parΓ‘metros combinados
+```
+
+### Con Proyectos (PMC-003)
+
+```yaml
+Trigger: POST /opportunities/:id/convert
+Crea:
+ - Proyecto vinculado al cliente
+ - CampaΓ±a inicial (opcional)
+ - Copia brief de la oportunidad
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: Aislamiento de datos
+ - PMC-003 Projects: ConversiΓ³n de oportunidades
+ - PMC-004 Generation: Trigger de generaciΓ³n
+ - PMC-006 Assets: Almacenamiento de logos y referencias
+
+Servicios Externos:
+ - Storage (S3/MinIO): Logos, imΓ‘genes de referencia
+```
+
+---
+
+## UI/UX Consideraciones
+
+```yaml
+Vistas principales:
+ - Lista de clientes con filtros y bΓΊsqueda
+ - Ficha de cliente con tabs (info, contactos, marcas, proyectos)
+ - Lista de marcas con preview de identidad
+ - Ficha de producto con galerΓa de referencias
+ - Pipeline kanban de oportunidades
+
+Acciones rΓ‘pidas:
+ - Desde producto: "Generar contenido"
+ - Desde cliente: "Nueva marca", "Nuevo proyecto"
+ - Desde oportunidad: "Convertir a proyecto"
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] CRUD completo para Clients, Contacts, Brands, Products, Opportunities
+- [ ] Identidad de marca se almacena y muestra correctamente
+- [ ] Trigger de generaciΓ³n funciona desde producto
+- [ ] Pipeline de oportunidades permite drag & drop
+- [ ] ConversiΓ³n de oportunidad crea proyecto
+- [ ] BΓΊsqueda y filtros funcionan en todas las listas
+- [ ] RLS aΓsla datos por tenant
+
+---
+
+## Referencias
+
+- [VISION-GENERAL.md](../00-vision-general/VISION-GENERAL.md)
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-003-PROJECTS.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-003-PROJECTS.md
new file mode 100644
index 0000000..16d9ab8
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-003-PROJECTS.md
@@ -0,0 +1,381 @@
+# PMC-003: MΓ³dulo de Projects
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Alta
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Projects gestiona proyectos y campaΓ±as de marketing. Cada proyecto agrupa mΓΊltiples campaΓ±as, y cada campaΓ±a contiene un brief estructurado que guΓa la generaciΓ³n de contenido.
+
+---
+
+## Objetivos
+
+1. Organizar el trabajo por proyectos y campaΓ±as
+2. Estructurar briefs creativos para generaciΓ³n de contenido
+3. Gestionar estados y flujos de aprobaciΓ³n
+4. Vincular proyectos con clientes y marcas del CRM
+5. Coordinar entregas de assets generados
+
+---
+
+## Entidades del Dominio
+
+### Project
+
+```yaml
+Entidad: Project
+DescripciΓ³n: Contenedor de campaΓ±as para un cliente/iniciativa
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - client_id: UUID (FK)
+ - name: string
+ - description: text
+ - code: string (identificador corto, ej: "PRJ-2025-001")
+ - status: enum [draft, active, on_hold, completed, cancelled]
+ - start_date: date
+ - end_date: date
+ - budget: decimal
+ - currency: string
+ - owner_id: UUID (FK a User, responsable)
+ - team_members: array[UUID] (usuarios asignados)
+ - settings: JSONB
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con Client
+ - N:1 con User (owner)
+ - 1:N con Campaign
+ - 1:N con Asset (assets del proyecto)
+```
+
+### Campaign
+
+```yaml
+Entidad: Campaign
+DescripciΓ³n: CampaΓ±a de marketing con brief y assets
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - project_id: UUID (FK)
+ - brand_id: UUID (FK)
+ - name: string
+ - description: text
+ - type: enum [social_media, performance_ads, catalog, landing, email, other]
+ - status: enum [draft, briefing, in_production, review, approved, published, archived]
+ - brief: JSONB (ver estructura abajo)
+ - channels: array[string] (instagram, facebook, tiktok, google_ads, etc.)
+ - start_date: date
+ - end_date: date
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Project
+ - N:1 con Brand
+ - N:1 con Tenant
+ - 1:N con GenerationJob
+ - 1:N con Asset
+```
+
+### Brief (JSONB Structure)
+
+```yaml
+Estructura: Campaign.brief
+Campos:
+ objective:
+ description: string (objetivo de la campaΓ±a)
+ kpis: array[string] (mΓ©tricas de Γ©xito)
+
+ audience:
+ demographics: string
+ psychographics: string
+ pain_points: array[string]
+ desires: array[string]
+
+ messaging:
+ main_message: string
+ tone_of_voice: string (override del brand)
+ call_to_action: string
+ hashtags: array[string]
+
+ visual:
+ style: string (fotogrΓ‘fico, ilustrado, minimalista, etc.)
+ mood: string (energΓ©tico, sereno, profesional, etc.)
+ color_palette: array[string] (override o adicionales)
+ references: array[string] (URLs de referencias visuales)
+
+ constraints:
+ forbidden_words: array[string]
+ forbidden_elements: array[string]
+ legal_disclaimers: array[string]
+ brand_guidelines_url: string
+
+ deliverables:
+ formats: array[object]
+ - type: string (post, story, banner, etc.)
+ dimensions: string (1080x1080, 1080x1920, etc.)
+ quantity: number
+ total_images: number
+ total_copies: number
+ variations_per_piece: number
+```
+
+### CampaignAsset
+
+```yaml
+Entidad: CampaignAsset (tabla pivote)
+DescripciΓ³n: RelaciΓ³n entre campaΓ±a y assets generados
+Atributos:
+ - id: UUID (PK)
+ - campaign_id: UUID (FK)
+ - asset_id: UUID (FK)
+ - status: enum [pending, approved, rejected, revision_requested]
+ - feedback: text
+ - approved_by: UUID (FK a User)
+ - approved_at: timestamp
+ - created_at: timestamp
+```
+
+---
+
+## Funcionalidades
+
+### F-003.1: GestiΓ³n de Proyectos
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-003.1.1 | CRUD Proyectos | Alta, ediciΓ³n, listado, archivado | Alta |
+| F-003.1.2 | Dashboard proyecto | Vista general con campaΓ±as y progreso | Alta |
+| F-003.1.3 | Asignar equipo | Agregar/quitar miembros al proyecto | Media |
+| F-003.1.4 | Timeline | VisualizaciΓ³n de fechas y milestones | Media |
+
+### F-003.2: GestiΓ³n de CampaΓ±as
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-003.2.1 | CRUD CampaΓ±as | Alta, ediciΓ³n, listado | Alta |
+| F-003.2.2 | Editor de brief | Formulario estructurado | Alta |
+| F-003.2.3 | Plantillas de brief | Briefs predefinidos por tipo | Media |
+| F-003.2.4 | Duplicar campaΓ±a | Clonar con modificaciones | Media |
+
+### F-003.3: Flujo de Trabajo
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-003.3.1 | Cambio de estado | Transiciones controladas | Alta |
+| F-003.3.2 | Notificaciones | Alertar cambios de estado | Media |
+| F-003.3.3 | AprobaciΓ³n de assets | Aprobar/rechazar contenido | Alta |
+| F-003.3.4 | Solicitar revisiΓ³n | Pedir cambios con feedback | Alta |
+
+### F-003.4: GeneraciΓ³n de Contenido
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-003.4.1 | Lanzar generaciΓ³n | Desde brief, iniciar jobs | Alta |
+| F-003.4.2 | Seleccionar plantillas | Elegir workflows de generaciΓ³n | Alta |
+| F-003.4.3 | Monitor de progreso | Ver estado de generaciones | Alta |
+| F-003.4.4 | Regenerar | Volver a generar con ajustes | Media |
+
+---
+
+## MΓ‘quina de Estados
+
+### Project Status
+
+```
+draft ββββββββββββββββββββββΊ active
+ β β
+ β βββββΊ on_hold ββββΊ active
+ β β
+ β βββββΊ completed
+ β
+ ββββββββββββββββββββββββββββββββββΊ cancelled
+```
+
+### Campaign Status
+
+```
+draft ββββΊ briefing ββββΊ in_production ββββΊ review ββββΊ approved ββββΊ published
+ β β β β β
+ β β ββββββββββββββββββ β
+ β β (revision_requested) β
+ β β β
+ βββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββ΄ββββΊ archived
+```
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-003.1:
+ DescripciΓ³n: Proyecto requiere cliente asignado
+ ValidaciΓ³n: client_id NOT NULL
+
+RN-003.2:
+ DescripciΓ³n: CampaΓ±a requiere brief mΓnimo para pasar a producciΓ³n
+ ValidaciΓ³n: brief.objective y brief.deliverables definidos
+
+RN-003.3:
+ DescripciΓ³n: Solo owner o admin puede cambiar estado del proyecto
+ AutorizaciΓ³n: Verificar rol del usuario
+
+RN-003.4:
+ DescripciΓ³n: Assets aprobados no pueden eliminarse
+ ValidaciΓ³n: Bloquear DELETE si status=approved
+
+RN-003.5:
+ DescripciΓ³n: Brief hereda identidad de la marca
+ Comportamiento: Cargar colores, tono, etc. de Brand al crear campaΓ±a
+
+RN-003.6:
+ DescripciΓ³n: CampaΓ±a solo puede publicarse si tiene assets aprobados
+ ValidaciΓ³n: Al menos 1 asset con status=approved
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/projects
+
+# Projects
+POST /projects
+GET /projects
+GET /projects/:id
+PUT /projects/:id
+DELETE /projects/:id
+PATCH /projects/:id/status
+GET /projects/:id/campaigns
+GET /projects/:id/assets
+POST /projects/:id/team # Agregar miembro
+DELETE /projects/:id/team/:userId
+
+# Campaigns
+POST /campaigns
+GET /campaigns
+GET /campaigns/:id
+PUT /campaigns/:id
+DELETE /campaigns/:id
+PATCH /campaigns/:id/status
+PUT /campaigns/:id/brief
+GET /campaigns/:id/assets
+POST /campaigns/:id/generate # Lanzar generaciΓ³n
+
+# Campaign Assets
+POST /campaigns/:id/assets/:assetId/approve
+POST /campaigns/:id/assets/:assetId/reject
+POST /campaigns/:id/assets/:assetId/request-revision
+
+# Brief Templates
+GET /brief-templates
+GET /brief-templates/:id
+POST /brief-templates # Admin only
+PUT /brief-templates/:id
+DELETE /brief-templates/:id
+```
+
+---
+
+## Integraciones
+
+### Con CRM (PMC-002)
+
+```yaml
+RelaciΓ³n: Proyecto vinculado a Cliente y Marca
+Datos heredados:
+ - Identidad visual de Brand
+ - InformaciΓ³n de productos
+ - Contactos para notificaciones
+```
+
+### Con Motor de GeneraciΓ³n (PMC-004)
+
+```yaml
+Trigger: POST /campaigns/:id/generate
+Payload:
+ campaign_id: UUID
+ workflow_templates: array[string]
+ options:
+ use_brand_lora: boolean
+ quality: string
+
+Respuesta:
+ job_ids: array[UUID]
+ estimated_time: number
+```
+
+### Con DAM (PMC-006)
+
+```yaml
+Assets generados se almacenan en DAM
+VinculaciΓ³n automΓ‘tica campaign_id β asset
+Metadatos del brief copiados al asset
+```
+
+### Con AutomatizaciΓ³n (PMC-005)
+
+```yaml
+Eventos disparados:
+ - campaign.status_changed β Notificaciones
+ - campaign.approved β Preparar entrega
+ - assets.all_approved β Trigger siguiente paso
+```
+
+---
+
+## UI/UX Consideraciones
+
+```yaml
+Vistas principales:
+ - Lista de proyectos con filtros (cliente, estado, fecha)
+ - Board kanban de campaΓ±as por estado
+ - Editor de brief con preview
+ - GalerΓa de assets de campaΓ±a con acciones
+
+Acciones rΓ‘pidas:
+ - "Nueva campaΓ±a" desde proyecto
+ - "Generar contenido" desde campaΓ±a
+ - "Aprobar todo" en vista de revisiΓ³n
+ - "Descargar pack" de assets aprobados
+
+Componentes:
+ - BriefEditor: Formulario estructurado con secciones colapsables
+ - AssetReviewer: GalerΓa con zoom, comparaciΓ³n, acciones
+ - ProgressTracker: Timeline visual de estado de campaΓ±a
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] CRUD completo para Projects y Campaigns
+- [ ] Editor de brief funcional con todas las secciones
+- [ ] Transiciones de estado respetan reglas
+- [ ] GeneraciΓ³n se lanza correctamente desde campaΓ±a
+- [ ] Flujo de aprobaciΓ³n de assets funciona
+- [ ] Assets rechazados permiten regeneraciΓ³n
+- [ ] Notificaciones se disparan en cambios de estado
+- [ ] Plantillas de brief funcionan correctamente
+
+---
+
+## Referencias
+
+- [VISION-GENERAL.md](../00-vision-general/VISION-GENERAL.md)
+- [PMC-002-CRM.md](./PMC-002-CRM.md)
+- [PMC-004-GENERATION.md](./PMC-004-GENERATION.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-004-GENERATION.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-004-GENERATION.md
new file mode 100644
index 0000000..f8f3c8b
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-004-GENERATION.md
@@ -0,0 +1,489 @@
+# PMC-004: MΓ³dulo de Generation
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Alta
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Generation es el nΓΊcleo de la plataforma. Gestiona la generaciΓ³n de contenido mediante IA, incluyendo imΓ‘genes con Stable Diffusion/ComfyUI y textos con LLMs. Orquesta workflows, colas de tareas, y la integraciΓ³n con modelos personalizados (LoRAs).
+
+---
+
+## Objetivos
+
+1. Generar imΓ‘genes de alta calidad para marketing
+2. Generar copys y textos publicitarios
+3. Ejecutar workflows predefinidos de ComfyUI
+4. Gestionar modelos personalizados (LoRAs, checkpoints)
+5. Mantener consistencia de marca en generaciones
+6. Procesar tareas en cola con prioridades
+
+---
+
+## Entidades del Dominio
+
+### GenerationJob
+
+```yaml
+Entidad: GenerationJob
+DescripciΓ³n: Tarea de generaciΓ³n en cola
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - campaign_id: UUID (FK, opcional)
+ - product_id: UUID (FK, opcional)
+ - user_id: UUID (FK, quien solicitΓ³)
+ - type: enum [image, text, image_batch, mixed]
+ - status: enum [queued, processing, completed, failed, cancelled]
+ - priority: integer (1-10, mayor = mΓ‘s urgente)
+ - workflow_id: UUID (FK a WorkflowTemplate)
+ - input_params: JSONB (parΓ‘metros de entrada)
+ - output_assets: array[UUID] (assets generados)
+ - error_message: text
+ - progress: integer (0-100)
+ - started_at: timestamp
+ - completed_at: timestamp
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con Campaign
+ - N:1 con Product
+ - N:1 con User
+ - N:1 con WorkflowTemplate
+ - 1:N con Asset (outputs)
+```
+
+### WorkflowTemplate
+
+```yaml
+Entidad: WorkflowTemplate
+DescripciΓ³n: Plantilla de workflow de generaciΓ³n
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK, null = global)
+ - name: string
+ - description: text
+ - type: enum [product_photo, social_post, banner, avatar, variation, custom]
+ - category: string (para organizaciΓ³n)
+ - comfyui_workflow: JSONB (definiciΓ³n del workflow)
+ - input_schema: JSONB (parΓ‘metros esperados)
+ - output_config: JSONB
+ - format: string (png, jpg, webp)
+ - dimensions: array[string]
+ - quantity_default: number
+ - models_required: array[string] (checkpoints, LoRAs requeridos)
+ - estimated_time_seconds: integer
+ - is_active: boolean
+ - is_system: boolean (plantilla del sistema vs personalizada)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant (opcional)
+ - 1:N con GenerationJob
+```
+
+### CustomModel
+
+```yaml
+Entidad: CustomModel
+DescripciΓ³n: Modelo personalizado (LoRA, checkpoint, embedding)
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - brand_id: UUID (FK, opcional)
+ - name: string
+ - type: enum [lora, checkpoint, embedding, controlnet]
+ - purpose: string (product, avatar, style, character)
+ - description: text
+ - file_path: string (ruta en storage)
+ - file_size: bigint
+ - status: enum [training, ready, failed, archived]
+ - training_params: JSONB
+ - base_model: string
+ - steps: number
+ - learning_rate: number
+ - training_images: array[string]
+ - trigger_word: string (palabra para activar en prompt)
+ - preview_images: array[string]
+ - metadata: JSONB
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con Brand (opcional)
+ - N:N con WorkflowTemplate
+```
+
+### TextGeneration
+
+```yaml
+Entidad: TextGeneration
+DescripciΓ³n: GeneraciΓ³n de texto/copy
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - job_id: UUID (FK a GenerationJob, opcional)
+ - campaign_id: UUID (FK, opcional)
+ - type: enum [copy, title, description, hashtags, cta, full_post]
+ - prompt: text (instrucciΓ³n al LLM)
+ - context: JSONB (datos de marca, producto, brief)
+ - output: text
+ - variations: array[text] (si se generaron mΓΊltiples)
+ - model_used: string
+ - tokens_used: integer
+ - status: enum [pending, completed, failed]
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con GenerationJob
+ - N:1 con Campaign
+```
+
+---
+
+## Funcionalidades
+
+### F-004.1: GeneraciΓ³n de ImΓ‘genes
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-004.1.1 | Text-to-Image | Generar imagen desde prompt | Alta |
+| F-004.1.2 | Image-to-Image | Transformar imagen existente | Alta |
+| F-004.1.3 | Inpainting | Editar partes de una imagen | Media |
+| F-004.1.4 | Upscaling | Aumentar resoluciΓ³n | Alta |
+| F-004.1.5 | Batch generation | Generar mΓΊltiples variaciones | Alta |
+
+### F-004.2: GeneraciΓ³n de Texto
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-004.2.1 | Copy generation | Generar textos publicitarios | Alta |
+| F-004.2.2 | Hashtag generation | Sugerir hashtags relevantes | Media |
+| F-004.2.3 | Title generation | Crear tΓtulos/headlines | Alta |
+| F-004.2.4 | Tone adaptation | Ajustar tono segΓΊn brief | Alta |
+
+### F-004.3: Workflows
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-004.3.1 | Plantillas predefinidas | Workflows listos para usar | Alta |
+| F-004.3.2 | Ejecutar workflow | Correr workflow con parΓ‘metros | Alta |
+| F-004.3.3 | Crear plantillas | Admin puede crear nuevos workflows | Media |
+| F-004.3.4 | Previsualizar | Ver ejemplo antes de ejecutar | Media |
+
+### F-004.4: Modelos Personalizados
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-004.4.1 | Registrar LoRA | Subir modelo entrenado | Alta |
+| F-004.4.2 | Entrenar LoRA | Iniciar entrenamiento (bΓ‘sico) | Media |
+| F-004.4.3 | Asociar a marca | Vincular modelo con brand | Alta |
+| F-004.4.4 | Selector de modelos | Elegir LoRAs en generaciΓ³n | Alta |
+
+### F-004.5: Cola de Tareas
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-004.5.1 | Encolar job | Agregar tarea a la cola | Alta |
+| F-004.5.2 | Priorizar | Ajustar prioridad de jobs | Media |
+| F-004.5.3 | Monitor | Ver estado de cola | Alta |
+| F-004.5.4 | Cancelar | Cancelar job pendiente | Media |
+| F-004.5.5 | Reintentar | Re-ejecutar job fallido | Media |
+
+---
+
+## Workflows Predefinidos (MVP)
+
+### WF-001: FotografΓa SintΓ©tica de Producto
+
+```yaml
+Nombre: product_photo_synthetic
+DescripciΓ³n: Genera fotos de producto en contextos comerciales
+Inputs:
+ - product_description: string
+ - reference_images: array[string] (opcional)
+ - background: string (white, lifestyle, custom)
+ - style: string (minimalist, premium, casual)
+ - brand_colors: array[string]
+ - lora_id: UUID (opcional)
+
+Outputs:
+ - 5 variaciones del producto
+ - Formato: PNG 1024x1024
+ - Fondo transparente disponible
+
+ComfyUI Nodes:
+ - SDXL Base
+ - ControlNet (si hay referencia)
+ - IP-Adapter (consistencia)
+ - Background Removal
+ - Upscaler
+```
+
+### WF-002: Post para Redes Sociales
+
+```yaml
+Nombre: social_media_post
+DescripciΓ³n: Genera imagen + copy para redes
+Inputs:
+ - brief: object (objetivo, audiencia, tono)
+ - product_id: UUID (opcional)
+ - channel: string (instagram, facebook, linkedin)
+ - format: string (post, story, carousel)
+ - brand_id: UUID
+
+Outputs:
+ - 3-5 variaciones de imagen
+ - Copy sugerido por variaciΓ³n
+ - Hashtags recomendados
+
+Proceso:
+ 1. Cargar identidad de marca
+ 2. Generar imagen base con SDXL + LoRA
+ 3. Aplicar composiciΓ³n segΓΊn formato
+ 4. Generar copy con LLM
+ 5. Combinar outputs
+```
+
+### WF-003: Variaciones de Anuncio
+
+```yaml
+Nombre: ad_variations
+DescripciΓ³n: Genera mΓΊltiples versiones para A/B testing
+Inputs:
+ - base_image: string (URL o asset_id)
+ - variations_count: number
+ - variation_type: string (color, background, composition)
+
+Outputs:
+ - N variaciones segΓΊn configuraciΓ³n
+ - Metadatos de diferencias
+
+Uso:
+ - Testing de creatividades
+ - Adaptaciones por canal
+```
+
+### WF-004: Avatar/Influencer Virtual
+
+```yaml
+Nombre: virtual_avatar
+DescripciΓ³n: Genera imΓ‘genes consistentes de un personaje
+Inputs:
+ - character_lora_id: UUID
+ - pose: string (standing, sitting, action)
+ - outfit: string
+ - background: string
+ - expression: string
+
+Outputs:
+ - Imagen del avatar
+ - Consistencia facial garantizada
+
+TΓ©cnicas:
+ - IP-Adapter para consistencia
+ - ControlNet OpenPose para poses
+ - LoRA especΓfico del personaje
+```
+
+---
+
+## Arquitectura de IntegraciΓ³n ComfyUI
+
+```yaml
+Componentes:
+ Backend (NestJS):
+ - GenerationService: LΓ³gica de negocio
+ - QueueService: GestiΓ³n de cola (Bull)
+ - ComfyUIClient: Cliente HTTP para ComfyUI
+
+ ComfyUI Server:
+ - API REST nativa o ComfyDeploy
+ - Websocket para progreso
+ - Storage compartido para outputs
+
+Flujo:
+ 1. Backend recibe solicitud de generaciΓ³n
+ 2. Valida permisos y lΓmites del tenant
+ 3. Construye payload del workflow
+ 4. Encola job en Bull/Redis
+ 5. Worker toma job y llama a ComfyUI
+ 6. ComfyUI ejecuta workflow
+ 7. Worker recibe resultado y crea Asset
+ 8. Notifica completion via websocket
+```
+
+### Ejemplo de Llamada a ComfyUI
+
+```typescript
+interface ComfyUIRequest {
+ workflow_id: string;
+ inputs: {
+ positive_prompt: string;
+ negative_prompt: string;
+ seed: number;
+ steps: number;
+ cfg_scale: number;
+ width: number;
+ height: number;
+ lora_name?: string;
+ lora_strength?: number;
+ controlnet_image?: string;
+ };
+ webhook_url: string;
+}
+
+// Respuesta
+interface ComfyUIResponse {
+ job_id: string;
+ status: 'queued' | 'processing' | 'completed' | 'failed';
+ outputs?: {
+ images: string[]; // URLs
+ };
+ error?: string;
+}
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/generation
+
+# Jobs
+POST /jobs # Crear job de generaciΓ³n
+GET /jobs # Listar jobs del usuario
+GET /jobs/:id # Detalle de job
+DELETE /jobs/:id # Cancelar job
+POST /jobs/:id/retry # Reintentar job fallido
+
+# Quick Generate (shortcuts)
+POST /generate/image # GeneraciΓ³n rΓ‘pida de imagen
+POST /generate/text # GeneraciΓ³n rΓ‘pida de texto
+POST /generate/batch # Batch de imΓ‘genes
+
+# Workflows
+GET /workflows # Listar plantillas disponibles
+GET /workflows/:id # Detalle de plantilla
+POST /workflows # Crear plantilla (admin)
+PUT /workflows/:id # Editar plantilla
+POST /workflows/:id/execute # Ejecutar workflow
+
+# Custom Models
+GET /models # Listar modelos del tenant
+GET /models/:id # Detalle de modelo
+POST /models # Registrar modelo
+DELETE /models/:id # Eliminar modelo
+POST /models/train # Iniciar entrenamiento
+
+# Queue Management (admin)
+GET /queue/status # Estado de la cola
+GET /queue/jobs # Jobs en cola
+POST /queue/jobs/:id/priority # Cambiar prioridad
+```
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-004.1:
+ DescripciΓ³n: Generaciones limitadas por plan del tenant
+ ValidaciΓ³n: Verificar cuota antes de encolar
+ AcciΓ³n: Rechazar si lΓmite alcanzado
+
+RN-004.2:
+ DescripciΓ³n: LoRA de marca se aplica automΓ‘ticamente
+ Comportamiento: Si brand tiene LoRA y no se especifica otro, usar el de marca
+
+RN-004.3:
+ DescripciΓ³n: Jobs prioritarios para planes premium
+ CΓ‘lculo: priority_base + plan_bonus
+
+RN-004.4:
+ DescripciΓ³n: Outputs se almacenan 30 dΓas mΓnimo
+ PolΓtica: Assets generados tienen retenciΓ³n mΓnima
+
+RN-004.5:
+ DescripciΓ³n: Entrenamiento requiere mΓnimo 10 imΓ‘genes
+ ValidaciΓ³n: Verificar cantidad antes de iniciar
+
+RN-004.6:
+ DescripciΓ³n: Negative prompts por defecto
+ Comportamiento: Agregar prompts negativos estΓ‘ndar de calidad
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: LΓmites y cuotas
+ - PMC-002 CRM: Datos de marca y producto
+ - PMC-003 Projects: Contexto de campaΓ±a
+ - PMC-006 Assets: Almacenamiento de outputs
+
+Servicios Externos:
+ - ComfyUI: Motor de generaciΓ³n de imΓ‘genes
+ - OpenAI/Claude API: GeneraciΓ³n de texto
+ - Redis: Cola de tareas
+ - S3/MinIO: Almacenamiento de modelos y outputs
+
+Dependencias del CatΓ‘logo:
+ - @CATALOG_RATELIMIT: Rate limiting por tenant
+```
+
+---
+
+## Consideraciones de Performance
+
+```yaml
+Optimizaciones:
+ - Cola con workers paralelos segΓΊn GPUs disponibles
+ - Cache de modelos frecuentes en VRAM
+ - Batch processing cuando sea posible
+ - CompresiΓ³n de outputs antes de storage
+
+Monitoreo:
+ - Tiempo promedio por tipo de workflow
+ - UtilizaciΓ³n de GPU
+ - Cola depth y wait time
+ - Tasa de errores
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] GeneraciΓ³n de imagen funciona con SDXL base
+- [ ] Workflows predefinidos ejecutan correctamente
+- [ ] LoRAs se cargan y aplican correctamente
+- [ ] Cola procesa jobs en orden de prioridad
+- [ ] Progreso se reporta via websocket
+- [ ] Jobs fallidos permiten reintento
+- [ ] LΓmites de tenant se respetan
+- [ ] Outputs se almacenan como Assets
+- [ ] GeneraciΓ³n de texto produce copys coherentes
+
+---
+
+## Referencias
+
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [ComfyUI Documentation](https://github.com/comfyanonymous/ComfyUI)
+- [ComfyDeploy](https://www.comfydeploy.com/)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-005-AUTOMATION.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-005-AUTOMATION.md
new file mode 100644
index 0000000..c171cd7
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-005-AUTOMATION.md
@@ -0,0 +1,447 @@
+# PMC-005: MΓ³dulo de Automation
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Media
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Automation gestiona flujos automatizados entre los diferentes componentes de la plataforma. Utiliza n8n como orquestador principal para conectar CRM, motor de generaciΓ³n, notificaciones y sistemas externos.
+
+---
+
+## Objetivos
+
+1. Automatizar flujos creativos desde brief hasta entrega
+2. Integrar CRM con motor de generaciΓ³n
+3. Disparar acciones basadas en eventos del sistema
+4. Conectar con servicios externos (email, redes, etc.)
+5. Reducir tareas manuales repetitivas
+
+---
+
+## Entidades del Dominio
+
+### AutomationFlow
+
+```yaml
+Entidad: AutomationFlow
+DescripciΓ³n: DefiniciΓ³n de un flujo automatizado
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - description: text
+ - type: enum [trigger_based, scheduled, manual]
+ - trigger_event: string (evento que dispara el flujo)
+ - n8n_workflow_id: string (ID del workflow en n8n)
+ - is_active: boolean
+ - last_run: timestamp
+ - run_count: integer
+ - config: JSONB
+ - retry_on_failure: boolean
+ - max_retries: number
+ - timeout_seconds: number
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - 1:N con AutomationRun
+```
+
+### AutomationRun
+
+```yaml
+Entidad: AutomationRun
+DescripciΓ³n: EjecuciΓ³n de un flujo automatizado
+Atributos:
+ - id: UUID (PK)
+ - flow_id: UUID (FK)
+ - tenant_id: UUID (FK)
+ - status: enum [running, completed, failed, cancelled]
+ - trigger_data: JSONB (datos del evento que disparΓ³)
+ - output_data: JSONB (resultados)
+ - error_message: text
+ - started_at: timestamp
+ - completed_at: timestamp
+ - duration_ms: integer
+
+Relaciones:
+ - N:1 con AutomationFlow
+ - N:1 con Tenant
+```
+
+### WebhookEndpoint
+
+```yaml
+Entidad: WebhookEndpoint
+DescripciΓ³n: Endpoint para recibir eventos externos
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - slug: string (parte de la URL)
+ - secret_key: string (para validaciΓ³n)
+ - target_flow_id: UUID (FK)
+ - is_active: boolean
+ - last_called: timestamp
+ - call_count: integer
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con AutomationFlow
+```
+
+---
+
+## Eventos del Sistema
+
+### Eventos Disponibles para Triggers
+
+```yaml
+CRM Events:
+ - client.created
+ - client.updated
+ - brand.created
+ - brand.updated
+ - product.created
+ - product.updated
+ - opportunity.stage_changed
+ - opportunity.won
+ - opportunity.lost
+
+Project Events:
+ - project.created
+ - project.status_changed
+ - campaign.created
+ - campaign.status_changed
+ - campaign.brief_completed
+ - campaign.approved
+
+Generation Events:
+ - job.completed
+ - job.failed
+ - batch.completed
+ - model.training_completed
+
+Asset Events:
+ - asset.created
+ - asset.approved
+ - asset.rejected
+ - all_assets.approved (todos los assets de campaΓ±a)
+
+User Events:
+ - user.created
+ - user.invited
+ - user.activated
+```
+
+---
+
+## Flujos Predefinidos (MVP)
+
+### FLOW-001: Nuevo Producto β Generar Kit de Assets
+
+```yaml
+Nombre: product_asset_kit
+Trigger: product.created
+DescripciΓ³n: Al crear producto, genera pack de imΓ‘genes automΓ‘ticamente
+
+Pasos:
+ 1. Recibir evento product.created
+ 2. Cargar datos del producto y su marca
+ 3. Verificar si tiene imΓ‘genes de referencia
+ 4. Llamar a GenerationService con workflow "product_photo_synthetic"
+ 5. Esperar completaciΓ³n del job
+ 6. Notificar al usuario creador
+
+ConfiguraciΓ³n:
+ images_count: 5
+ auto_approve: false
+ notify_on_complete: true
+```
+
+### FLOW-002: Nueva CampaΓ±a β Generar Lote Inicial
+
+```yaml
+Nombre: campaign_initial_batch
+Trigger: campaign.brief_completed
+DescripciΓ³n: Al completar brief, genera creatividades iniciales
+
+Pasos:
+ 1. Recibir evento campaign.brief_completed
+ 2. Extraer deliverables del brief
+ 3. Para cada formato solicitado:
+ - Llamar a GenerationService
+ - Generar imΓ‘genes segΓΊn especificaciones
+ 4. Generar copys con LLM
+ 5. Vincular assets a la campaΓ±a
+ 6. Cambiar estado campaΓ±a a "in_production"
+ 7. Notificar al equipo asignado
+
+ConfiguraciΓ³n:
+ parallel_generations: true
+ generate_copies: true
+ auto_link_assets: true
+```
+
+### FLOW-003: CampaΓ±a Aprobada β Preparar Entrega
+
+```yaml
+Nombre: campaign_delivery_prep
+Trigger: campaign.approved
+DescripciΓ³n: Prepara paquete de entrega al aprobar campaΓ±a
+
+Pasos:
+ 1. Recibir evento campaign.approved
+ 2. Recopilar todos los assets aprobados
+ 3. Generar ZIP con estructura organizada
+ 4. Crear enlace de descarga temporal
+ 5. Si cliente tiene acceso al portal:
+ - Crear notificaciΓ³n en portal
+ 6. Enviar email al contacto del cliente
+ 7. Registrar entrega en historial
+
+ConfiguraciΓ³n:
+ zip_structure: "by_format" | "flat"
+ include_copies: true
+ link_expiry_days: 7
+ notify_client: true
+```
+
+### FLOW-004: Job Fallido β Notificar y Reintentar
+
+```yaml
+Nombre: job_failure_handler
+Trigger: job.failed
+DescripciΓ³n: Maneja fallos de generaciΓ³n
+
+Pasos:
+ 1. Recibir evento job.failed
+ 2. Evaluar tipo de error
+ 3. Si error transitorio (GPU, timeout):
+ - Reintentar hasta max_retries
+ 4. Si error persistente:
+ - Notificar al usuario
+ - Crear ticket/tarea de revisiΓ³n
+ 5. Registrar en logs de auditorΓa
+
+ConfiguraciΓ³n:
+ max_retries: 3
+ retry_delay_seconds: 60
+ notify_on_permanent_failure: true
+```
+
+---
+
+## Funcionalidades
+
+### F-005.1: GestiΓ³n de Flujos
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-005.1.1 | Listar flujos | Ver flujos disponibles y activos | Alta |
+| F-005.1.2 | Activar/Desactivar | Toggle de flujos | Alta |
+| F-005.1.3 | Configurar | Ajustar parΓ‘metros de flujo | Media |
+| F-005.1.4 | Ver historial | Ejecuciones pasadas | Media |
+
+### F-005.2: EjecuciΓ³n Manual
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-005.2.1 | Ejecutar ahora | Disparar flujo manualmente | Media |
+| F-005.2.2 | Test run | Ejecutar en modo prueba | Baja |
+| F-005.2.3 | Cancelar | Detener ejecuciΓ³n en curso | Media |
+
+### F-005.3: Webhooks
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-005.3.1 | Crear endpoint | Generar URL de webhook | Media |
+| F-005.3.2 | Validar payload | Verificar firma/secret | Media |
+| F-005.3.3 | Ver logs | Historial de llamadas | Baja |
+
+### F-005.4: Integraciones Externas
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-005.4.1 | Email | EnvΓo de notificaciones | Alta |
+| F-005.4.2 | Slack | Notificaciones a canales | Media |
+| F-005.4.3 | CRM externo | Sync bidireccional | Baja |
+
+---
+
+## Arquitectura de IntegraciΓ³n n8n
+
+```yaml
+Componentes:
+ Backend (NestJS):
+ - EventEmitter: Emite eventos del sistema
+ - WebhookController: Recibe llamadas de n8n
+ - AutomationService: Gestiona flujos y ejecuciones
+
+ n8n Server:
+ - Workflows definidos
+ - Credenciales de integraciΓ³n
+ - Webhooks de entrada/salida
+
+ComunicaciΓ³n:
+ Backend β n8n: Webhooks HTTP POST
+ n8n β Backend: API calls con auth token
+
+Flujo:
+ 1. Evento ocurre en Backend (ej: product.created)
+ 2. EventEmitter notifica a AutomationService
+ 3. AutomationService busca flujos suscritos al evento
+ 4. Para cada flujo activo:
+ - POST a webhook de n8n con datos del evento
+ 5. n8n ejecuta workflow
+ 6. n8n llama a API del Backend para acciones
+ 7. n8n reporta resultado via webhook de completion
+```
+
+### Ejemplo de Webhook Payload
+
+```json
+{
+ "event": "product.created",
+ "timestamp": "2025-12-08T10:30:00Z",
+ "tenant_id": "uuid-tenant",
+ "data": {
+ "product_id": "uuid-product",
+ "brand_id": "uuid-brand",
+ "name": "Producto X",
+ "description": "...",
+ "reference_images": ["url1", "url2"]
+ },
+ "metadata": {
+ "user_id": "uuid-user",
+ "source": "api"
+ }
+}
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/automation
+
+# Flows
+GET /flows # Listar flujos
+GET /flows/:id # Detalle de flujo
+POST /flows/:id/activate # Activar flujo
+POST /flows/:id/deactivate # Desactivar flujo
+PUT /flows/:id/config # Configurar flujo
+POST /flows/:id/execute # Ejecutar manualmente
+
+# Runs
+GET /runs # Historial de ejecuciones
+GET /runs/:id # Detalle de ejecuciΓ³n
+POST /runs/:id/cancel # Cancelar ejecuciΓ³n
+
+# Webhooks
+GET /webhooks # Listar endpoints
+POST /webhooks # Crear endpoint
+DELETE /webhooks/:id # Eliminar endpoint
+POST /webhooks/:id/regenerate # Regenerar secret
+
+# Incoming webhooks (public, con autenticaciΓ³n por secret)
+POST /hooks/:tenant_slug/:webhook_slug
+```
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-005.1:
+ DescripciΓ³n: Flujos desactivados no procesan eventos
+ Comportamiento: Eventos ignorados si flow.is_active = false
+
+RN-005.2:
+ DescripciΓ³n: Reintentos con backoff exponencial
+ CΓ‘lculo: delay = retry_delay * (2 ^ attempt_number)
+
+RN-005.3:
+ DescripciΓ³n: Ejecuciones fallidas notifican a admins
+ AcciΓ³n: Email + notificaciΓ³n in-app a usuarios con rol admin
+
+RN-005.4:
+ DescripciΓ³n: Webhooks requieren validaciΓ³n de secret
+ ValidaciΓ³n: HMAC-SHA256 del payload con secret key
+
+RN-005.5:
+ DescripciΓ³n: LΓmite de ejecuciones por hora
+ ValidaciΓ³n: Rate limit segΓΊn plan del tenant
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: ConfiguraciΓ³n y lΓmites
+ - PMC-002 CRM: Eventos de clientes/productos
+ - PMC-003 Projects: Eventos de campaΓ±as
+ - PMC-004 Generation: Llamadas a generaciΓ³n
+ - PMC-006 Assets: GestiΓ³n de outputs
+
+Servicios Externos:
+ - n8n: Orquestador de workflows
+ - SMTP/SendGrid: EnvΓo de emails
+ - Slack API: Notificaciones (opcional)
+```
+
+---
+
+## Consideraciones de Seguridad
+
+```yaml
+AutenticaciΓ³n:
+ - Webhooks internos usan JWT del sistema
+ - Webhooks externos usan HMAC con secret por endpoint
+ - n8n autenticado con API key exclusiva
+
+Aislamiento:
+ - Flujos aislados por tenant
+ - Eventos solo visible para el tenant que los genera
+
+ValidaciΓ³n:
+ - Payload size mΓ‘ximo: 1MB
+ - Rate limiting por endpoint
+ - Timeout de ejecuciΓ³n: 5 minutos
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] Flujos predefinidos funcionan correctamente
+- [ ] Eventos del sistema disparan flujos suscritos
+- [ ] n8n recibe y procesa webhooks
+- [ ] Ejecuciones se registran con estado y resultado
+- [ ] Reintentos automΓ‘ticos funcionan en errores transitorios
+- [ ] Webhooks externos validan correctamente el secret
+- [ ] Notificaciones se envΓan segΓΊn configuraciΓ³n
+- [ ] Rate limiting funciona segΓΊn plan
+
+---
+
+## Referencias
+
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [n8n Documentation](https://docs.n8n.io/)
+- [PMC-004-GENERATION.md](./PMC-004-GENERATION.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-006-ASSETS.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-006-ASSETS.md
new file mode 100644
index 0000000..557bb5d
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-006-ASSETS.md
@@ -0,0 +1,449 @@
+# PMC-006: MΓ³dulo de Assets (DAM)
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Alta
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Assets implementa un Digital Asset Management (DAM) simplificado para almacenar, organizar y gestionar todos los recursos digitales generados o subidos a la plataforma: imΓ‘genes, copys, videos, modelos IA, y documentos.
+
+---
+
+## Objetivos
+
+1. Centralizar todos los activos digitales del tenant
+2. Organizar assets por cliente, campaΓ±a, tipo
+3. Gestionar versiones y estados de aprobaciΓ³n
+4. Facilitar bΓΊsqueda y descubrimiento de assets
+5. Controlar acceso y permisos por rol
+
+---
+
+## Entidades del Dominio
+
+### Asset
+
+```yaml
+Entidad: Asset
+DescripciΓ³n: Recurso digital almacenado en la plataforma
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - description: text
+ - type: enum [image, copy, video, document, model, template]
+ - mime_type: string
+ - file_path: string (ruta en storage)
+ - file_size: bigint (bytes)
+ - dimensions: JSONB (width, height para imΓ‘genes/videos)
+ - duration: integer (segundos, para video/audio)
+ - status: enum [draft, pending_review, approved, rejected, archived]
+ - visibility: enum [private, team, client]
+ - source: enum [generated, uploaded, imported]
+ - generation_job_id: UUID (FK, si fue generado)
+ - metadata: JSONB
+ - prompt: string (si fue generado)
+ - model_used: string
+ - seed: number
+ - parameters: object
+ - tags: array[string]
+ - created_by: UUID (FK a User)
+ - created_at: timestamp
+ - updated_at: timestamp
+ - deleted_at: timestamp (soft delete)
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con User (creator)
+ - N:1 con GenerationJob
+ - N:N con Campaign
+ - N:N con Collection
+ - 1:N con AssetVersion
+```
+
+### AssetVersion
+
+```yaml
+Entidad: AssetVersion
+DescripciΓ³n: VersiΓ³n histΓ³rica de un asset
+Atributos:
+ - id: UUID (PK)
+ - asset_id: UUID (FK)
+ - version_number: integer
+ - file_path: string
+ - file_size: bigint
+ - changes_description: text
+ - created_by: UUID (FK)
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Asset
+ - N:1 con User
+```
+
+### Collection
+
+```yaml
+Entidad: Collection
+DescripciΓ³n: AgrupaciΓ³n lΓ³gica de assets
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - description: text
+ - type: enum [manual, smart, campaign, brand]
+ - smart_filters: JSONB (criterios para smart collections)
+ - cover_asset_id: UUID (FK, opcional)
+ - is_public: boolean
+ - created_by: UUID (FK)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:N con Asset
+ - N:1 con User
+```
+
+### AssetComment
+
+```yaml
+Entidad: AssetComment
+DescripciΓ³n: Comentario o feedback sobre un asset
+Atributos:
+ - id: UUID (PK)
+ - asset_id: UUID (FK)
+ - user_id: UUID (FK)
+ - content: text
+ - position: JSONB (x, y para comentarios en imagen)
+ - is_resolved: boolean
+ - parent_id: UUID (FK, para respuestas)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Asset
+ - N:1 con User
+ - Self-referencial (parent/children)
+```
+
+### Download
+
+```yaml
+Entidad: Download
+DescripciΓ³n: Registro de descargas de assets
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - asset_id: UUID (FK, opcional - puede ser colecciΓ³n)
+ - collection_id: UUID (FK, opcional)
+ - user_id: UUID (FK)
+ - download_type: enum [single, batch, collection]
+ - format: string (original, converted)
+ - ip_address: string
+ - user_agent: string
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Asset
+ - N:1 con Collection
+ - N:1 con User
+```
+
+---
+
+## Funcionalidades
+
+### F-006.1: GestiΓ³n de Assets
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-006.1.1 | Upload | Subir archivos manualmente | Alta |
+| F-006.1.2 | Ver asset | Detalle con preview y metadata | Alta |
+| F-006.1.3 | Editar metadata | Nombre, descripciΓ³n, tags | Alta |
+| F-006.1.4 | Eliminar | Soft delete con papelera | Alta |
+| F-006.1.5 | Restaurar | Recuperar de papelera | Media |
+
+### F-006.2: OrganizaciΓ³n
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-006.2.1 | Colecciones | Agrupar assets manualmente | Alta |
+| F-006.2.2 | Smart collections | Colecciones automΓ‘ticas por criterios | Media |
+| F-006.2.3 | Tags | Etiquetar assets | Alta |
+| F-006.2.4 | Filtros | Filtrar por tipo, estado, fecha, etc. | Alta |
+
+### F-006.3: BΓΊsqueda
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-006.3.1 | BΓΊsqueda texto | Por nombre, descripciΓ³n, tags | Alta |
+| F-006.3.2 | Filtros avanzados | Combinar mΓΊltiples criterios | Alta |
+| F-006.3.3 | BΓΊsqueda por similar | Encontrar imΓ‘genes similares | Baja |
+
+### F-006.4: Versiones y AprobaciΓ³n
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-006.4.1 | Versionar | Subir nueva versiΓ³n de asset | Media |
+| F-006.4.2 | Comparar versiones | Ver diferencias | Baja |
+| F-006.4.3 | Aprobar/Rechazar | Cambiar estado de revisiΓ³n | Alta |
+| F-006.4.4 | Comentarios | Feedback sobre assets | Alta |
+
+### F-006.5: Descargas y ExportaciΓ³n
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-006.5.1 | Descargar individual | Bajar un asset | Alta |
+| F-006.5.2 | Descargar batch | Bajar mΓΊltiples como ZIP | Alta |
+| F-006.5.3 | Convertir formato | Descargar en formato diferente | Media |
+| F-006.5.4 | Enlace temporal | URL con expiraciΓ³n | Media |
+
+---
+
+## Tipos de Assets Soportados
+
+```yaml
+ImΓ‘genes:
+ Formatos: PNG, JPG, JPEG, WebP, GIF, SVG
+ Max size: 50MB
+ Procesamiento:
+ - GeneraciΓ³n de thumbnails
+ - ExtracciΓ³n de dimensiones
+ - OptimizaciΓ³n automΓ‘tica
+
+Copys/Textos:
+ Tipos: Copy publicitario, tΓtulo, descripciΓ³n, hashtags
+ Almacenamiento: En BD + archivo .txt opcional
+ Metadata: Tone, language, character count
+
+Videos:
+ Formatos: MP4, MOV, WebM
+ Max size: 500MB
+ Procesamiento:
+ - GeneraciΓ³n de thumbnail
+ - ExtracciΓ³n de duraciΓ³n
+ - Preview de baja resoluciΓ³n
+
+Documentos:
+ Formatos: PDF, DOC, DOCX
+ Max size: 100MB
+ Uso: Brand guidelines, briefs, contratos
+
+Modelos IA:
+ Tipos: LoRA (.safetensors), Checkpoint, Embedding
+ Max size: 10GB
+ Metadata: Base model, trigger word, training params
+
+Templates:
+ Tipos: Workflow ComfyUI, plantillas de brief
+ Formato: JSON
+```
+
+---
+
+## Storage Structure
+
+```yaml
+S3/MinIO Bucket Structure:
+ {bucket}/
+ βββ {tenant_slug}/
+ β βββ assets/
+ β β βββ images/
+ β β β βββ {year}/
+ β β β β βββ {month}/
+ β β β β β βββ {asset_id}/
+ β β β β β β βββ original.{ext}
+ β β β β β β βββ thumb_200.jpg
+ β β β β β β βββ thumb_800.jpg
+ β β β β β β βββ versions/
+ β β β β β β βββ v1.{ext}
+ β β β β β β βββ v2.{ext}
+ β β βββ videos/
+ β β βββ documents/
+ β β βββ copies/
+ β βββ models/
+ β β βββ loras/
+ β β βββ checkpoints/
+ β β βββ embeddings/
+ β βββ temp/
+ β βββ (archivos temporales, limpiados periΓ³dicamente)
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/assets
+
+# Assets CRUD
+POST /assets/upload # Subir archivo(s)
+GET /assets # Listar con filtros y paginaciΓ³n
+GET /assets/:id # Detalle de asset
+PUT /assets/:id # Actualizar metadata
+DELETE /assets/:id # Soft delete
+
+# Bulk operations
+POST /assets/bulk/move # Mover a colecciΓ³n
+POST /assets/bulk/tag # Agregar tags
+POST /assets/bulk/delete # Eliminar mΓΊltiples
+POST /assets/bulk/status # Cambiar estado
+
+# Versions
+GET /assets/:id/versions # Listar versiones
+POST /assets/:id/versions # Subir nueva versiΓ³n
+GET /assets/:id/versions/:v # Obtener versiΓ³n especΓfica
+
+# Status & Approval
+PATCH /assets/:id/status # Cambiar estado
+POST /assets/:id/approve # Aprobar
+POST /assets/:id/reject # Rechazar con feedback
+
+# Comments
+GET /assets/:id/comments # Listar comentarios
+POST /assets/:id/comments # Agregar comentario
+PUT /assets/:id/comments/:cid # Editar comentario
+DELETE /assets/:id/comments/:cid # Eliminar comentario
+
+# Downloads
+GET /assets/:id/download # Descargar asset
+POST /assets/download/batch # Descargar mΓΊltiples (ZIP)
+POST /assets/:id/share # Generar enlace temporal
+
+# Collections
+GET /collections # Listar colecciones
+POST /collections # Crear colecciΓ³n
+GET /collections/:id # Detalle de colecciΓ³n
+PUT /collections/:id # Actualizar colecciΓ³n
+DELETE /collections/:id # Eliminar colecciΓ³n
+POST /collections/:id/assets # Agregar assets
+DELETE /collections/:id/assets # Quitar assets
+
+# Search
+POST /assets/search # BΓΊsqueda avanzada
+GET /assets/tags # Listar tags usados
+```
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-006.1:
+ DescripciΓ³n: Assets generados heredan metadata del job
+ Comportamiento: Copiar prompt, modelo, parΓ‘metros automΓ‘ticamente
+
+RN-006.2:
+ DescripciΓ³n: Thumbnails se generan automΓ‘ticamente
+ TamaΓ±os: 200px y 800px de ancho, manteniendo aspect ratio
+
+RN-006.3:
+ DescripciΓ³n: Soft delete retiene archivos 30 dΓas
+ AcciΓ³n: Cron job limpia despuΓ©s del perΓodo
+
+RN-006.4:
+ DescripciΓ³n: Versionado mantiene historial completo
+ LΓmite: MΓ‘ximo 10 versiones por asset
+
+RN-006.5:
+ DescripciΓ³n: Links temporales expiran segΓΊn configuraciΓ³n
+ Default: 7 dΓas, mΓ‘ximo 30 dΓas
+
+RN-006.6:
+ DescripciΓ³n: Storage cuenta contra cuota del tenant
+ ValidaciΓ³n: Verificar lΓmite antes de upload
+```
+
+---
+
+## UI/UX Consideraciones
+
+```yaml
+Vistas principales:
+ - Grid view: Thumbnails en cuadrΓcula
+ - List view: Lista con metadata
+ - Detail view: Asset grande con panel de info
+
+Componentes:
+ - AssetUploader: Drag & drop, multi-file
+ - AssetPreview: Lightbox con navegaciΓ³n
+ - AssetFilters: Panel de filtros colapsable
+ - CollectionPicker: Modal para agregar a colecciΓ³n
+ - CommentPanel: Sidebar con comentarios
+
+Acciones rΓ‘pidas:
+ - Quick preview (spacebar)
+ - Quick download (d)
+ - Quick approve (a)
+ - Add to collection (c)
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: Cuotas de storage
+ - PMC-003 Projects: VinculaciΓ³n con campaΓ±as
+ - PMC-004 Generation: Assets generados
+
+Servicios Externos:
+ - S3/MinIO: Almacenamiento de archivos
+ - Sharp: Procesamiento de imΓ‘genes
+ - FFmpeg: Procesamiento de video (opcional)
+
+Dependencias del CatΓ‘logo:
+ - (ninguna directa)
+```
+
+---
+
+## Consideraciones de Performance
+
+```yaml
+Optimizaciones:
+ - Lazy loading de thumbnails
+ - PaginaciΓ³n con cursor para grandes volΓΊmenes
+ - CDN para servir assets estΓ‘ticos
+ - CompresiΓ³n de uploads grandes
+ - Pre-signed URLs para uploads directos a S3
+
+Γndices BD:
+ - tenant_id + type + status
+ - tenant_id + created_at
+ - tenant_id + tags (GIN index)
+ - Full-text search en name, description
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] Upload funciona con drag & drop y file picker
+- [ ] Thumbnails se generan automΓ‘ticamente
+- [ ] BΓΊsqueda y filtros funcionan correctamente
+- [ ] Colecciones permiten organizar assets
+- [ ] Versionado mantiene historial
+- [ ] Flujo de aprobaciΓ³n funciona
+- [ ] Descargas individuales y batch funcionan
+- [ ] Links temporales se generan y expiran
+- [ ] Comentarios se pueden agregar y resolver
+- [ ] Storage se cuenta contra cuota
+
+---
+
+## Referencias
+
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [GLOSARIO.md](../00-vision-general/GLOSARIO.md) - DefiniciΓ³n de DAM
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-007-ADMIN.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-007-ADMIN.md
new file mode 100644
index 0000000..3e67898
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-007-ADMIN.md
@@ -0,0 +1,495 @@
+# PMC-007: MΓ³dulo de Admin
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Media
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Admin proporciona las funcionalidades de administraciΓ³n del sistema SaaS: gestiΓ³n de usuarios, roles, permisos, planes de suscripciΓ³n, configuraciΓ³n global y herramientas de supervisiΓ³n.
+
+---
+
+## Objetivos
+
+1. Gestionar usuarios y sus roles dentro del tenant
+2. Controlar permisos de acceso por mΓ³dulo/acciΓ³n
+3. Administrar planes y suscripciones (preparaciΓ³n SaaS)
+4. Configurar parΓ‘metros globales del sistema
+5. Monitorear uso y salud del sistema
+
+---
+
+## Entidades del Dominio
+
+### User
+
+```yaml
+Entidad: User
+DescripciΓ³n: Usuario del sistema
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - email: string (ΓΊnico por tenant)
+ - password_hash: string
+ - first_name: string
+ - last_name: string
+ - avatar_url: string
+ - status: enum [pending, active, suspended, deactivated]
+ - role_id: UUID (FK)
+ - preferences: JSONB
+ - language: string
+ - timezone: string
+ - theme: string
+ - notifications: object
+ - last_login_at: timestamp
+ - email_verified_at: timestamp
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con Role
+ - 1:N con Project (como owner)
+ - 1:N con Asset (como creator)
+ - 1:N con GenerationJob
+```
+
+### Role
+
+```yaml
+Entidad: Role
+DescripciΓ³n: Rol con conjunto de permisos
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK, null = rol de sistema)
+ - name: string
+ - description: text
+ - permissions: array[string] (lista de permisos)
+ - is_system: boolean (no editable si true)
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant (opcional)
+ - 1:N con User
+
+Roles de Sistema:
+ - super_admin: Acceso total, sin lΓmites
+ - tenant_admin: Admin del tenant
+ - creative: Crear contenido, gestionar campaΓ±as
+ - analyst: CRM, reportes
+ - viewer: Solo lectura
+```
+
+### Permission (definiciΓ³n estΓ‘tica)
+
+```yaml
+Permisos del Sistema:
+ # Tenants
+ - tenants.view
+ - tenants.create
+ - tenants.edit
+ - tenants.delete
+
+ # Users
+ - users.view
+ - users.create
+ - users.edit
+ - users.delete
+ - users.invite
+
+ # CRM
+ - clients.view
+ - clients.create
+ - clients.edit
+ - clients.delete
+ - brands.view
+ - brands.create
+ - brands.edit
+ - brands.delete
+ - products.view
+ - products.create
+ - products.edit
+ - products.delete
+
+ # Projects
+ - projects.view
+ - projects.create
+ - projects.edit
+ - projects.delete
+ - campaigns.view
+ - campaigns.create
+ - campaigns.edit
+ - campaigns.delete
+ - campaigns.approve
+
+ # Generation
+ - generation.execute
+ - generation.view_queue
+ - generation.manage_queue
+ - models.view
+ - models.create
+ - models.delete
+ - models.train
+
+ # Assets
+ - assets.view
+ - assets.upload
+ - assets.edit
+ - assets.delete
+ - assets.approve
+ - assets.download
+
+ # Automation
+ - automation.view
+ - automation.configure
+ - automation.execute
+
+ # Admin
+ - admin.users
+ - admin.roles
+ - admin.settings
+ - admin.billing
+ - admin.audit
+```
+
+### Invitation
+
+```yaml
+Entidad: Invitation
+DescripciΓ³n: InvitaciΓ³n pendiente para unirse al tenant
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - email: string
+ - role_id: UUID (FK)
+ - invited_by: UUID (FK a User)
+ - token: string (ΓΊnico)
+ - status: enum [pending, accepted, expired, cancelled]
+ - expires_at: timestamp
+ - accepted_at: timestamp
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con Role
+ - N:1 con User (inviter)
+```
+
+### AuditLog
+
+```yaml
+Entidad: AuditLog
+DescripciΓ³n: Registro de acciones importantes
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - user_id: UUID (FK)
+ - action: string (ej: user.created, asset.deleted)
+ - entity_type: string
+ - entity_id: UUID
+ - old_values: JSONB
+ - new_values: JSONB
+ - ip_address: string
+ - user_agent: string
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con User
+```
+
+### Setting
+
+```yaml
+Entidad: Setting
+DescripciΓ³n: ConfiguraciΓ³n del sistema/tenant
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK, null = global)
+ - key: string
+ - value: JSONB
+ - type: enum [string, number, boolean, json]
+ - category: string
+ - is_secret: boolean
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant (opcional)
+```
+
+---
+
+## Funcionalidades
+
+### F-007.1: GestiΓ³n de Usuarios
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-007.1.1 | Listar usuarios | Ver todos los usuarios del tenant | Alta |
+| F-007.1.2 | Invitar usuario | Enviar invitaciΓ³n por email | Alta |
+| F-007.1.3 | Editar usuario | Modificar datos y rol | Alta |
+| F-007.1.4 | Suspender usuario | Bloquear acceso temporalmente | Media |
+| F-007.1.5 | Eliminar usuario | Desactivar cuenta | Media |
+
+### F-007.2: GestiΓ³n de Roles
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-007.2.1 | Listar roles | Ver roles disponibles | Alta |
+| F-007.2.2 | Crear rol | Definir rol personalizado | Media |
+| F-007.2.3 | Editar permisos | Modificar permisos de rol | Media |
+| F-007.2.4 | Eliminar rol | Solo si no tiene usuarios | Baja |
+
+### F-007.3: ConfiguraciΓ³n
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-007.3.1 | Settings generales | Nombre, branding, etc. | Alta |
+| F-007.3.2 | Settings de generaciΓ³n | Modelos por defecto, calidad | Media |
+| F-007.3.3 | Integraciones | Configurar n8n, APIs externas | Media |
+| F-007.3.4 | Notificaciones | Templates de email, webhooks | Media |
+
+### F-007.4: AuditorΓa
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-007.4.1 | Ver logs | Historial de acciones | Media |
+| F-007.4.2 | Filtrar logs | Por usuario, acciΓ³n, fecha | Media |
+| F-007.4.3 | Exportar logs | Descargar en CSV | Baja |
+
+### F-007.5: Monitoreo (Super Admin)
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-007.5.1 | Dashboard sistema | MΓ©tricas globales | Media |
+| F-007.5.2 | Estado de servicios | GPU, queue, storage | Alta |
+| F-007.5.3 | Uso por tenant | Consumo de recursos | Media |
+
+---
+
+## Roles del Sistema
+
+### Matriz de Permisos por Rol
+
+```yaml
+super_admin:
+ description: "Administrador del sistema completo"
+ permissions: ["*"] # Todos los permisos
+ notes: "Solo para el owner/CTO. Sin lΓmites de uso."
+
+tenant_admin:
+ description: "Administrador del tenant/agencia"
+ permissions:
+ - users.*
+ - roles.view
+ - clients.*
+ - brands.*
+ - products.*
+ - projects.*
+ - campaigns.*
+ - generation.*
+ - assets.*
+ - automation.view
+ - automation.configure
+ - admin.users
+ - admin.settings
+ - admin.audit
+
+creative:
+ description: "Creativo/Media Buyer"
+ permissions:
+ - clients.view
+ - brands.view
+ - products.view
+ - products.create
+ - projects.view
+ - projects.create
+ - projects.edit
+ - campaigns.*
+ - generation.execute
+ - generation.view_queue
+ - models.view
+ - assets.view
+ - assets.upload
+ - assets.edit
+
+analyst:
+ description: "Analista/CRM"
+ permissions:
+ - clients.*
+ - brands.view
+ - products.view
+ - projects.view
+ - campaigns.view
+ - assets.view
+ - assets.download
+ - automation.view
+
+viewer:
+ description: "Solo lectura"
+ permissions:
+ - clients.view
+ - brands.view
+ - products.view
+ - projects.view
+ - campaigns.view
+ - assets.view
+
+client_portal:
+ description: "Cliente externo (portal)"
+ permissions:
+ - campaigns.view # Solo sus campaΓ±as
+ - assets.view # Solo sus assets
+ - assets.download
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/admin
+
+# Users
+GET /users # Listar usuarios
+GET /users/:id # Detalle de usuario
+POST /users/invite # Invitar usuario
+PUT /users/:id # Actualizar usuario
+PATCH /users/:id/status # Cambiar estado
+DELETE /users/:id # Desactivar usuario
+
+# Invitations
+GET /invitations # Listar invitaciones
+POST /invitations/:id/resend # Reenviar
+DELETE /invitations/:id # Cancelar
+
+# Roles
+GET /roles # Listar roles
+GET /roles/:id # Detalle de rol
+POST /roles # Crear rol
+PUT /roles/:id # Actualizar rol
+DELETE /roles/:id # Eliminar rol
+
+# Settings
+GET /settings # Listar settings
+GET /settings/:key # Obtener setting
+PUT /settings/:key # Actualizar setting
+DELETE /settings/:key # Eliminar setting (custom)
+
+# Audit
+GET /audit # Listar logs
+GET /audit/export # Exportar logs
+
+# System (Super Admin only)
+GET /system/status # Estado del sistema
+GET /system/metrics # MΓ©tricas globales
+GET /system/tenants # Listar todos los tenants
+GET /system/tenants/:id/usage # Uso de un tenant
+```
+
+---
+
+## Reglas de Negocio
+
+```yaml
+RN-007.1:
+ DescripciΓ³n: Email ΓΊnico por tenant
+ ValidaciΓ³n: No puede haber dos usuarios con mismo email en un tenant
+
+RN-007.2:
+ DescripciΓ³n: Roles de sistema no editables
+ ValidaciΓ³n: is_system = true bloquea ediciΓ³n
+
+RN-007.3:
+ DescripciΓ³n: No eliminar rol con usuarios asignados
+ ValidaciΓ³n: Verificar user_count = 0 antes de DELETE
+
+RN-007.4:
+ DescripciΓ³n: InvitaciΓ³n expira en 7 dΓas
+ ValidaciΓ³n: expires_at = created_at + 7 days
+
+RN-007.5:
+ DescripciΓ³n: Super admin no puede ser suspendido
+ ValidaciΓ³n: Bloquear cambio de status si role = super_admin
+
+RN-007.6:
+ DescripciΓ³n: Audit logs son inmutables
+ ValidaciΓ³n: Solo INSERT, no UPDATE ni DELETE
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: ConfiguraciΓ³n de tenant
+ - Todos los mΓ³dulos: Para verificaciΓ³n de permisos
+
+Dependencias del CatΓ‘logo:
+ - @CATALOG_AUTH: AutenticaciΓ³n JWT + OAuth
+ - @CATALOG_SESSION: GestiΓ³n de sesiones
+
+Servicios Externos:
+ - SMTP: EnvΓo de invitaciones
+ - (OAuth providers si se implementa SSO)
+```
+
+---
+
+## Flujos de Usuario
+
+### Invitar Usuario
+
+```
+1. Admin navega a Users β Invite
+2. Ingresa email y selecciona rol
+3. Sistema genera token ΓΊnico
+4. Sistema envΓa email con link
+5. Usuario hace clic en link
+6. Usuario completa registro (password, nombre)
+7. Usuario queda activo en el tenant
+```
+
+### Cambiar Rol de Usuario
+
+```
+1. Admin navega a Users β [Usuario]
+2. Selecciona nuevo rol
+3. Sistema verifica que no sea el ΓΊnico admin
+4. Sistema actualiza rol
+5. Permisos se aplican inmediatamente
+6. Se registra en audit log
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] CRUD completo de usuarios funciona
+- [ ] Sistema de invitaciones por email funciona
+- [ ] Roles controlan acceso a mΓ³dulos correctamente
+- [ ] Permisos se verifican en cada endpoint
+- [ ] Settings se guardan y cargan correctamente
+- [ ] Audit logs registran acciones importantes
+- [ ] Dashboard de sistema muestra mΓ©tricas
+- [ ] Super admin tiene acceso a todo
+
+---
+
+## Referencias
+
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [@CATALOG_AUTH](../../../core/catalog/modules/auth/)
+- [PMC-001-TENANTS.md](./PMC-001-TENANTS.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-008-ANALYTICS.md b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-008-ANALYTICS.md
new file mode 100644
index 0000000..fabafbd
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/PMC-008-ANALYTICS.md
@@ -0,0 +1,443 @@
+# PMC-008: MΓ³dulo de Analytics
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+**Estado:** DefiniciΓ³n
+**Prioridad:** Baja
+
+---
+
+## DescripciΓ³n General
+
+El mΓ³dulo de Analytics proporciona dashboards, reportes y mΓ©tricas sobre el uso de la plataforma, rendimiento de campaΓ±as, y consumo de recursos. Permite tomar decisiones basadas en datos.
+
+---
+
+## Objetivos
+
+1. Visualizar mΓ©tricas clave de operaciΓ³n
+2. Analizar rendimiento de campaΓ±as
+3. Monitorear uso de recursos (generaciones, storage)
+4. Generar reportes exportables
+5. Identificar tendencias y oportunidades
+
+---
+
+## Dashboards
+
+### Dashboard Principal (Home)
+
+```yaml
+Widgets:
+ - quick_stats:
+ - CampaΓ±as activas
+ - Assets generados (mes)
+ - Tasa de aprobaciΓ³n
+ - Jobs en cola
+
+ - recent_activity:
+ - Γltimos assets generados
+ - CampaΓ±as reciΓ©n creadas
+ - Jobs completados
+
+ - pending_actions:
+ - Assets pendientes de revisiΓ³n
+ - CampaΓ±as esperando aprobaciΓ³n
+```
+
+### Dashboard de ProducciΓ³n
+
+```yaml
+Widgets:
+ - generation_volume:
+ Tipo: Line chart
+ Datos: Generaciones por dΓa/semana/mes
+ Filtros: Tipo (imagen/texto), workflow
+
+ - queue_status:
+ Tipo: Real-time gauge
+ Datos: Jobs en cola, procesando, completados
+
+ - model_usage:
+ Tipo: Pie chart
+ Datos: DistribuciΓ³n de uso de workflows/LoRAs
+
+ - error_rate:
+ Tipo: Line chart
+ Datos: % de jobs fallidos por perΓodo
+
+ - processing_time:
+ Tipo: Bar chart
+ Datos: Tiempo promedio por tipo de workflow
+```
+
+### Dashboard de CampaΓ±as
+
+```yaml
+Widgets:
+ - campaign_funnel:
+ Tipo: Funnel chart
+ Datos: CampaΓ±as por estado
+
+ - approval_metrics:
+ Tipo: Stats cards
+ Datos:
+ - Tasa de aprobaciΓ³n primera iteraciΓ³n
+ - Promedio de revisiones por campaΓ±a
+ - Tiempo desde brief hasta aprobaciΓ³n
+
+ - assets_per_campaign:
+ Tipo: Bar chart
+ Datos: Promedio de assets por campaΓ±a
+
+ - top_clients:
+ Tipo: Table
+ Datos: Clientes con mΓ‘s campaΓ±as/assets
+```
+
+### Dashboard de Recursos
+
+```yaml
+Widgets:
+ - storage_usage:
+ Tipo: Progress bar + breakdown
+ Datos: GB usados vs cuota, por tipo de archivo
+
+ - generation_quota:
+ Tipo: Progress bar
+ Datos: Generaciones usadas vs lΓmite mensual
+
+ - gpu_utilization:
+ Tipo: Real-time gauge (si aplica)
+ Datos: % de uso de GPU
+
+ - cost_estimate:
+ Tipo: Stats card
+ Datos: Costo estimado de APIs externas (LLM, etc.)
+```
+
+---
+
+## Reportes
+
+### Reporte de Actividad Mensual
+
+```yaml
+Nombre: monthly_activity_report
+PerΓodo: Mes natural
+Contenido:
+ - Resumen ejecutivo
+ - CampaΓ±as creadas/completadas
+ - Assets generados por tipo
+ - Clientes mΓ‘s activos
+ - Uso de recursos
+ - Comparativa con mes anterior
+
+Formatos: PDF, Excel
+ProgramaciΓ³n: AutomΓ‘tico primer dΓa del mes
+```
+
+### Reporte de CampaΓ±a
+
+```yaml
+Nombre: campaign_report
+PerΓodo: DuraciΓ³n de la campaΓ±a
+Contenido:
+ - Datos de la campaΓ±a y brief
+ - Assets generados
+ - Historial de revisiones
+ - Tiempo total de producciΓ³n
+ - Participantes (usuarios)
+
+Formatos: PDF
+GeneraciΓ³n: Manual o al cerrar campaΓ±a
+```
+
+### Reporte de Cliente
+
+```yaml
+Nombre: client_report
+PerΓodo: Configurable
+Contenido:
+ - Proyectos y campaΓ±as del cliente
+ - Assets entregados
+ - HistΓ³rico de actividad
+ - MΓ©tricas de satisfacciΓ³n (si aplica)
+
+Formatos: PDF, Excel
+GeneraciΓ³n: Manual
+```
+
+### Reporte de Uso (Admin)
+
+```yaml
+Nombre: usage_report
+PerΓodo: Configurable
+Contenido:
+ - Generaciones por usuario
+ - Storage consumido
+ - Costo de APIs externas
+ - Comparativa por perΓodo
+
+Formatos: Excel, CSV
+Audiencia: Admin/Finance
+```
+
+---
+
+## Entidades del Dominio
+
+### Metric
+
+```yaml
+Entidad: Metric (tabla de hechos)
+DescripciΓ³n: Registro agregado de mΓ©tricas
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - metric_type: string (generation_count, storage_used, etc.)
+ - dimension_1: string (ej: workflow_type)
+ - dimension_2: string (ej: user_id)
+ - value: decimal
+ - period_type: enum [hour, day, week, month]
+ - period_start: timestamp
+ - created_at: timestamp
+
+Γndices:
+ - tenant_id + metric_type + period_start
+ - tenant_id + period_type + period_start
+```
+
+### Report
+
+```yaml
+Entidad: Report
+DescripciΓ³n: Reporte generado
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - name: string
+ - type: string (monthly_activity, campaign, client, usage)
+ - parameters: JSONB (filtros aplicados)
+ - file_path: string
+ - file_format: enum [pdf, xlsx, csv]
+ - generated_by: UUID (FK a User)
+ - created_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con User
+```
+
+### SavedView
+
+```yaml
+Entidad: SavedView
+DescripciΓ³n: Vista personalizada guardada
+Atributos:
+ - id: UUID (PK)
+ - tenant_id: UUID (FK)
+ - user_id: UUID (FK)
+ - name: string
+ - dashboard: string (production, campaigns, resources)
+ - config: JSONB (filtros, widgets visibles, layout)
+ - is_default: boolean
+ - created_at: timestamp
+ - updated_at: timestamp
+
+Relaciones:
+ - N:1 con Tenant
+ - N:1 con User
+```
+
+---
+
+## Funcionalidades
+
+### F-008.1: Dashboards
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-008.1.1 | Dashboard home | Vista principal con KPIs | Alta |
+| F-008.1.2 | Dashboard producciΓ³n | MΓ©tricas de generaciΓ³n | Media |
+| F-008.1.3 | Dashboard campaΓ±as | MΓ©tricas de campaΓ±as | Media |
+| F-008.1.4 | Dashboard recursos | Uso de recursos | Media |
+| F-008.1.5 | Filtros globales | Por fecha, cliente, usuario | Alta |
+
+### F-008.2: Reportes
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-008.2.1 | Generar reporte | Crear reporte bajo demanda | Media |
+| F-008.2.2 | Programar reporte | GeneraciΓ³n automΓ‘tica | Baja |
+| F-008.2.3 | Descargar reporte | PDF, Excel, CSV | Media |
+| F-008.2.4 | Historial reportes | Ver reportes generados | Baja |
+
+### F-008.3: PersonalizaciΓ³n
+
+| ID | Funcionalidad | DescripciΓ³n | Prioridad |
+|----|---------------|-------------|-----------|
+| F-008.3.1 | Guardar vista | Guardar configuraciΓ³n de dashboard | Baja |
+| F-008.3.2 | Vista por defecto | Establecer vista inicial | Baja |
+
+---
+
+## KPIs Principales
+
+```yaml
+OperaciΓ³n:
+ - Generaciones totales (dΓa/semana/mes)
+ - Tiempo promedio de generaciΓ³n
+ - Tasa de Γ©xito de jobs (%)
+ - Cola promedio (tiempo de espera)
+
+CampaΓ±as:
+ - CampaΓ±as activas
+ - Tiempo promedio brief β aprobaciΓ³n
+ - Tasa de aprobaciΓ³n primera iteraciΓ³n (%)
+ - Assets por campaΓ±a (promedio)
+
+Recursos:
+ - Storage utilizado vs cuota (%)
+ - Generaciones usadas vs lΓmite (%)
+ - Costo estimado de APIs externas
+
+Usuarios:
+ - Usuarios activos (dΓa/semana/mes)
+ - Generaciones por usuario
+ - Acciones por usuario
+```
+
+---
+
+## API Endpoints
+
+```yaml
+Base: /api/v1/analytics
+
+# Dashboards
+GET /dashboards/:name # Datos de dashboard
+GET /dashboards/:name/widgets/:widget # Datos de widget especΓfico
+
+# Metrics
+GET /metrics # Query de mΓ©tricas
+POST /metrics/aggregate # AgregaciΓ³n personalizada
+
+# Reports
+GET /reports # Listar reportes generados
+POST /reports # Generar nuevo reporte
+GET /reports/:id # Detalle de reporte
+GET /reports/:id/download # Descargar archivo
+DELETE /reports/:id # Eliminar reporte
+
+# Saved Views
+GET /views # Listar vistas guardadas
+POST /views # Crear vista
+PUT /views/:id # Actualizar vista
+DELETE /views/:id # Eliminar vista
+PATCH /views/:id/default # Establecer como default
+
+# Quick stats (para widgets)
+GET /stats/overview # Resumen general
+GET /stats/generations # Stats de generaciΓ³n
+GET /stats/campaigns # Stats de campaΓ±as
+GET /stats/storage # Stats de storage
+```
+
+---
+
+## Arquitectura de Datos
+
+### Pipeline de MΓ©tricas
+
+```yaml
+Flujo:
+ 1. Evento ocurre (generaciΓ³n, campaΓ±a creada, etc.)
+ 2. EventEmitter emite evento
+ 3. MetricsService captura y procesa
+ 4. Se inserta en tabla metrics (agregado horario)
+ 5. Job nocturno consolida a dΓa/semana/mes
+
+RetenciΓ³n:
+ - MΓ©tricas horarias: 7 dΓas
+ - MΓ©tricas diarias: 90 dΓas
+ - MΓ©tricas semanales: 1 aΓ±o
+ - MΓ©tricas mensuales: indefinido
+```
+
+### Queries Optimizadas
+
+```yaml
+Estrategias:
+ - Tablas de mΓ©tricas pre-agregadas
+ - Γndices por tenant + perΓodo
+ - Cache en Redis para datos frecuentes
+ - Refresh periΓ³dico de materialized views
+```
+
+---
+
+## Dependencias
+
+```yaml
+Dependencias de MΓ³dulos:
+ - PMC-001 Tenants: Contexto de datos
+ - PMC-003 Projects: Datos de campaΓ±as
+ - PMC-004 Generation: Datos de generaciΓ³n
+ - PMC-006 Assets: Datos de almacenamiento
+
+Servicios Externos:
+ - Redis: Cache de mΓ©tricas
+ - (Opcional) Chart library frontend
+
+Dependencias del CatΓ‘logo:
+ - (ninguna directa)
+```
+
+---
+
+## UI/UX Consideraciones
+
+```yaml
+Componentes:
+ - DashboardGrid: Layout responsivo de widgets
+ - ChartWidget: Wrapper para grΓ‘ficos
+ - FilterBar: Barra de filtros global
+ - DateRangePicker: Selector de perΓodo
+ - ExportButton: Descarga de datos/reportes
+
+Interactividad:
+ - Drill-down en grΓ‘ficos
+ - Tooltips con detalles
+ - Filtros aplicables a toda la pΓ‘gina
+ - Auto-refresh configurable
+
+Responsividad:
+ - Widgets se reordenan en mΓ³vil
+ - GrΓ‘ficos adaptan tamaΓ±o
+ - Tablas con scroll horizontal
+```
+
+---
+
+## Criterios de AceptaciΓ³n
+
+- [ ] Dashboard home muestra KPIs correctos
+- [ ] Filtros de fecha funcionan globalmente
+- [ ] GrΓ‘ficos cargan datos correctamente
+- [ ] Reportes se generan en PDF y Excel
+- [ ] MΓ©tricas se agregan correctamente
+- [ ] Cache mejora tiempos de carga
+- [ ] Datos se aΓslan por tenant
+
+---
+
+## Referencias
+
+- [VISION-GENERAL.md](../00-vision-general/VISION-GENERAL.md)
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/02-definicion-modulos/_INDEX.md b/projects/platform_marketing_content/docs/02-definicion-modulos/_INDEX.md
new file mode 100644
index 0000000..c524def
--- /dev/null
+++ b/projects/platform_marketing_content/docs/02-definicion-modulos/_INDEX.md
@@ -0,0 +1,148 @@
+# Γndice de MΓ³dulos - Platform Marketing Content
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## Resumen de MΓ³dulos
+
+| ID | MΓ³dulo | DescripciΓ³n | Prioridad | Estado |
+|----|--------|-------------|-----------|--------|
+| PMC-001 | [Tenants](./PMC-001-TENANTS.md) | Arquitectura multi-tenant, planes, configuraciΓ³n | Alta | Definido |
+| PMC-002 | [CRM](./PMC-002-CRM.md) | Clientes, marcas, productos, oportunidades | Alta | Definido |
+| PMC-003 | [Projects](./PMC-003-PROJECTS.md) | Proyectos, campaΓ±as, briefs, flujos de trabajo | Alta | Definido |
+| PMC-004 | [Generation](./PMC-004-GENERATION.md) | Motor de IA, workflows ComfyUI, modelos custom | Alta | Definido |
+| PMC-005 | [Automation](./PMC-005-AUTOMATION.md) | Flujos automatizados con n8n, triggers, webhooks | Media | Definido |
+| PMC-006 | [Assets](./PMC-006-ASSETS.md) | DAM, biblioteca de activos, versionado | Alta | Definido |
+| PMC-007 | [Admin](./PMC-007-ADMIN.md) | Usuarios, roles, permisos, configuraciΓ³n SaaS | Media | Definido |
+| PMC-008 | [Analytics](./PMC-008-ANALYTICS.md) | Dashboards, reportes, mΓ©tricas | Baja | Definido |
+
+---
+
+## Dependencias entre MΓ³dulos
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PMC-001 Tenants β
+β (Base de aislamiento) β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+ β
+ βββββββββββββββββββββββΌββββββββββββββββββββββ
+ β β β
+ βΌ βΌ βΌ
+βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
+β PMC-007 β β PMC-002 β β PMC-006 β
+β Admin β β CRM β β Assets β
+β (Users/Roles)β β (Clientes) β β (DAM) β
+βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
+ β β β²
+ β β β
+ β βΌ β
+ β βββββββββββββββββ β
+ β β PMC-003 β β
+ β β Projects ββββββββββββββββ€
+ β β (CampaΓ±as) β β
+ β βββββββββββββββββ β
+ β β β
+ β βΌ β
+ β βββββββββββββββββ β
+ β β PMC-004 β β
+ β β Generation ββββββββββββββββ
+ β β (Motor IA) β
+ β βββββββββββββββββ
+ β β
+ β βΌ
+ β βββββββββββββββββ
+ βββββββββββββΊβ PMC-005 β
+ β Automation β
+ β (n8n) β
+ βββββββββββββββββ
+ β
+ βΌ
+ βββββββββββββββββ
+ β PMC-008 β
+ β Analytics β
+ β (MΓ©tricas) β
+ βββββββββββββββββ
+```
+
+---
+
+## Orden de ImplementaciΓ³n Sugerido
+
+### Fase 1 - Core MVP
+
+1. **PMC-001 Tenants** - Base de la arquitectura
+2. **PMC-007 Admin** - Usuarios y autenticaciΓ³n
+3. **PMC-002 CRM** - GestiΓ³n de clientes y marcas
+4. **PMC-006 Assets** - Almacenamiento de activos
+5. **PMC-003 Projects** - Proyectos y campaΓ±as bΓ‘sicos
+6. **PMC-004 Generation** - Motor de generaciΓ³n (2-3 workflows)
+
+### Fase 2 - AutomatizaciΓ³n
+
+7. **PMC-005 Automation** - Flujos automatizados
+
+### Fase 3 - Analytics
+
+8. **PMC-008 Analytics** - Dashboards y reportes
+
+---
+
+## Entidades Compartidas
+
+| Entidad | MΓ³dulo Principal | MΓ³dulos que Referencian |
+|---------|------------------|------------------------|
+| Tenant | PMC-001 | Todos |
+| User | PMC-007 | Todos |
+| Client | PMC-002 | PMC-003, PMC-008 |
+| Brand | PMC-002 | PMC-003, PMC-004, PMC-006 |
+| Product | PMC-002 | PMC-004, PMC-006 |
+| Campaign | PMC-003 | PMC-004, PMC-005, PMC-006, PMC-008 |
+| Asset | PMC-006 | PMC-002, PMC-003, PMC-004 |
+| GenerationJob | PMC-004 | PMC-003, PMC-006, PMC-008 |
+
+---
+
+## APIs por MΓ³dulo
+
+| MΓ³dulo | Base Path | Endpoints Principales |
+|--------|-----------|----------------------|
+| Tenants | `/api/v1/tenants` | CRUD tenants, config |
+| CRM | `/api/v1/crm` | clients, contacts, brands, products, opportunities |
+| Projects | `/api/v1/projects` | projects, campaigns, briefs |
+| Generation | `/api/v1/generation` | jobs, workflows, models |
+| Automation | `/api/v1/automation` | flows, runs, webhooks |
+| Assets | `/api/v1/assets` | assets, collections, downloads |
+| Admin | `/api/v1/admin` | users, roles, settings, audit |
+| Analytics | `/api/v1/analytics` | dashboards, metrics, reports |
+
+---
+
+## Conteo de Funcionalidades
+
+| MΓ³dulo | Funcionalidades | Prioridad Alta | Prioridad Media | Prioridad Baja |
+|--------|-----------------|----------------|-----------------|----------------|
+| PMC-001 | 10 | 6 | 3 | 1 |
+| PMC-002 | 18 | 12 | 5 | 1 |
+| PMC-003 | 16 | 10 | 5 | 1 |
+| PMC-004 | 20 | 12 | 6 | 2 |
+| PMC-005 | 12 | 4 | 6 | 2 |
+| PMC-006 | 18 | 10 | 6 | 2 |
+| PMC-007 | 14 | 7 | 5 | 2 |
+| PMC-008 | 10 | 3 | 5 | 2 |
+| **TOTAL** | **118** | **64** | **41** | **13** |
+
+---
+
+## Referencias
+
+- [VISION-GENERAL.md](../00-vision-general/VISION-GENERAL.md)
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [GLOSARIO.md](../00-vision-general/GLOSARIO.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-001-TENANTS.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-001-TENANTS.md
new file mode 100644
index 0000000..a2c74df
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-001-TENANTS.md
@@ -0,0 +1,512 @@
+# Requerimientos Funcionales - PMC-001 Tenants
+
+**MΓ³dulo:** Tenants
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## RF-PMC-001-001: Crear Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-001 |
+| **Nombre** | Crear Tenant |
+| **Prioridad** | P1 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir crear un nuevo tenant con datos bΓ‘sicos.
+
+**Precondiciones:**
+- Usuario autenticado como Super Admin
+
+**Datos de entrada:**
+- name: string (requerido, 3-100 caracteres)
+- slug: string (requerido, ΓΊnico, formato URL-safe)
+- plan_id: UUID (requerido)
+- settings: object (opcional)
+- branding: object (opcional)
+
+**Flujo principal:**
+1. Super Admin accede a gestiΓ³n de tenants
+2. Selecciona "Crear tenant"
+3. Completa formulario con datos requeridos
+4. Sistema valida unicidad del slug
+5. Sistema crea tenant con status "active"
+6. Sistema crea usuario admin inicial (opcional)
+7. Sistema retorna tenant creado
+
+**Postcondiciones:**
+- Tenant existe en base de datos
+- Tenant tiene plan asignado
+- RLS configurado para nuevo tenant
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ValidaciΓ³n de slug ΓΊnico funciona
+- [ ] Tenant se crea con status "active"
+- [ ] Plan se asocia correctamente
+
+---
+
+## RF-PMC-001-002: Editar Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-002 |
+| **Nombre** | Editar Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin, Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir modificar datos de un tenant existente.
+
+**Precondiciones:**
+- Usuario autenticado con permisos de ediciΓ³n
+- Tenant existe
+
+**Datos de entrada:**
+- name: string (opcional)
+- settings: object (opcional)
+- branding: object (opcional)
+- limits: object (opcional, solo Super Admin)
+
+**Flujo principal:**
+1. Usuario accede a configuraciΓ³n del tenant
+2. Modifica campos permitidos segΓΊn rol
+3. Sistema valida datos
+4. Sistema actualiza tenant
+5. Sistema registra cambio en audit log
+
+**Restricciones:**
+- Tenant Admin no puede modificar limits ni plan
+- Slug no es editable despuΓ©s de creaciΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos se actualizan correctamente
+- [ ] Permisos por rol se respetan
+- [ ] Audit log registra cambios
+
+---
+
+## RF-PMC-001-003: Suspender Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-003 |
+| **Nombre** | Suspender Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir suspender un tenant, bloqueando acceso de usuarios.
+
+**Precondiciones:**
+- Usuario autenticado como Super Admin
+- Tenant existe con status "active"
+
+**Flujo principal:**
+1. Super Admin selecciona tenant a suspender
+2. Sistema solicita confirmaciΓ³n
+3. Sistema cambia status a "suspended"
+4. Sistema invalida todas las sesiones del tenant
+5. Sistema notifica a admins del tenant
+
+**Postcondiciones:**
+- Usuarios del tenant no pueden hacer login
+- Datos permanecen intactos
+- Jobs pendientes se pausan
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "suspended"
+- [ ] Login bloqueado para usuarios del tenant
+- [ ] Sesiones existentes invalidadas
+
+---
+
+## RF-PMC-001-004: Reactivar Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-004 |
+| **Nombre** | Reactivar Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir reactivar un tenant suspendido.
+
+**Precondiciones:**
+- Tenant existe con status "suspended"
+
+**Flujo principal:**
+1. Super Admin selecciona tenant suspendido
+2. Selecciona "Reactivar"
+3. Sistema cambia status a "active"
+4. Sistema notifica a admins del tenant
+
+**Postcondiciones:**
+- Usuarios pueden hacer login
+- Jobs pausados se reactivan
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "active"
+- [ ] Login permitido nuevamente
+
+---
+
+## RF-PMC-001-005: Eliminar Tenant (Soft Delete)
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-005 |
+| **Nombre** | Eliminar Tenant |
+| **Prioridad** | P3 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir eliminar un tenant mediante soft delete.
+
+**Precondiciones:**
+- Tenant existe
+
+**Flujo principal:**
+1. Super Admin selecciona tenant a eliminar
+2. Sistema solicita confirmaciΓ³n con texto de verificaciΓ³n
+3. Sistema marca tenant como eliminado (deleted_at)
+4. Sistema invalida sesiones
+5. Sistema programa limpieza de datos (90 dΓas)
+
+**Postcondiciones:**
+- Tenant marcado con deleted_at
+- Datos retenidos por 90 dΓas
+- Acceso completamente bloqueado
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Soft delete funciona correctamente
+- [ ] Datos no se eliminan inmediatamente
+- [ ] Tenant no aparece en listados
+
+---
+
+## RF-PMC-001-006: Listar Tenants
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-006 |
+| **Nombre** | Listar Tenants |
+| **Prioridad** | P1 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir listar todos los tenants con filtros y paginaciΓ³n.
+
+**Datos de entrada (query params):**
+- status: string (filtro por estado)
+- plan_id: UUID (filtro por plan)
+- search: string (bΓΊsqueda por nombre)
+- page: number
+- limit: number (max 100)
+
+**Datos de salida:**
+- Lista de tenants con datos bΓ‘sicos
+- Total de registros
+- InformaciΓ³n de paginaciΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] PaginaciΓ³n funciona correctamente
+- [ ] Filtros se aplican correctamente
+- [ ] BΓΊsqueda por nombre funciona
+
+---
+
+## RF-PMC-001-007: Ver Detalle de Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-007 |
+| **Nombre** | Ver Detalle de Tenant |
+| **Prioridad** | P1 |
+| **Actor** | Super Admin, Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe mostrar informaciΓ³n detallada de un tenant.
+
+**Datos de salida:**
+- Datos bΓ‘sicos del tenant
+- Plan asociado con lΓmites
+- ConfiguraciΓ³n (settings)
+- Branding
+- EstadΓsticas de uso
+- Usuarios activos (count)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todos los datos se muestran correctamente
+- [ ] Tenant Admin solo ve su propio tenant
+
+---
+
+## RF-PMC-001-008: Configurar Branding
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-008 |
+| **Nombre** | Configurar Branding |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir personalizar el branding del tenant.
+
+**Datos de entrada:**
+- logo_url: string (URL o upload)
+- primary_color: string (hex color)
+- secondary_color: string (hex color)
+- favicon_url: string (opcional)
+
+**Flujo principal:**
+1. Admin accede a configuraciΓ³n de branding
+2. Sube logo o proporciona URL
+3. Selecciona colores
+4. Sistema valida formatos
+5. Sistema actualiza branding
+6. Cambios se reflejan en UI
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Logo se almacena/referencia correctamente
+- [ ] Colores se aplican en UI
+- [ ] Preview disponible antes de guardar
+
+---
+
+## RF-PMC-001-009: Configurar LΓmites Personalizados
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-009 |
+| **Nombre** | Configurar LΓmites Personalizados |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir sobreescribir lΓmites del plan para un tenant especΓfico.
+
+**Datos de entrada:**
+- generations_per_month: number (null = usar plan)
+- storage_gb: number (null = usar plan)
+- users_max: number (null = usar plan)
+- custom_limits: object
+
+**Flujo principal:**
+1. Super Admin accede a lΓmites del tenant
+2. Modifica valores especΓficos
+3. Sistema valida que valores sean >= 0
+4. Sistema guarda lΓmites personalizados
+5. LΓmites se aplican sobre los del plan
+
+**Criterios de aceptaciΓ³n:**
+- [ ] LΓmites personalizados sobreescriben plan
+- [ ] Valores null usan defaults del plan
+- [ ] Cambios se aplican inmediatamente
+
+---
+
+## RF-PMC-001-010: Obtener Tenant Actual
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-010 |
+| **Nombre** | Obtener Tenant Actual |
+| **Prioridad** | P1 |
+| **Actor** | Usuario autenticado |
+
+**DescripciΓ³n:**
+El sistema debe proporcionar los datos del tenant del usuario actual.
+
+**Flujo principal:**
+1. Usuario hace request a /tenants/current
+2. Sistema extrae tenant_id del JWT
+3. Sistema retorna datos del tenant
+
+**Datos de salida:**
+- Datos bΓ‘sicos del tenant
+- Plan con lΓmites efectivos
+- Branding
+- Settings relevantes para el usuario
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Endpoint retorna tenant correcto
+- [ ] LΓmites efectivos calculados correctamente
+
+---
+
+## RF-PMC-001-011: Validar Cuota de Uso
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-011 |
+| **Nombre** | Validar Cuota de Uso |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+El sistema debe validar cuotas antes de operaciones que consumen recursos.
+
+**Operaciones validadas:**
+- GeneraciΓ³n de imΓ‘genes
+- Entrenamiento de modelos
+- Subida de archivos (storage)
+- CreaciΓ³n de usuarios
+
+**Flujo principal:**
+1. Usuario solicita operaciΓ³n
+2. Sistema obtiene lΓmites del tenant
+3. Sistema obtiene uso actual
+4. Sistema compara uso vs lΓmite
+5. Si excede: rechaza con error especΓfico
+6. Si no excede: permite operaciΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ValidaciΓ³n ocurre antes de cada operaciΓ³n
+- [ ] Mensaje de error indica lΓmite y uso actual
+- [ ] Operaciones no se ejecutan si exceden lΓmite
+
+---
+
+## RF-PMC-001-012: Aplicar RLS por Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-012 |
+| **Nombre** | Aplicar RLS por Tenant |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+El sistema debe garantizar aislamiento de datos entre tenants mediante RLS.
+
+**ImplementaciΓ³n:**
+1. Todas las tablas principales tienen columna tenant_id
+2. PolΓticas RLS filtran por tenant_id
+3. Middleware inyecta tenant_id en cada request
+4. SET app.current_tenant ejecutado antes de queries
+
+**Tablas afectadas:**
+- clients, contacts, brands, products
+- projects, campaigns
+- assets, collections
+- users, roles
+- generation_jobs, custom_models
+- automation_flows, automation_runs
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Queries solo retornan datos del tenant actual
+- [ ] INSERT automΓ‘ticamente incluye tenant_id
+- [ ] No es posible acceder a datos de otro tenant
+
+---
+
+## RF-PMC-001-013: Gestionar Planes
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-013 |
+| **Nombre** | Gestionar Planes |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir crear y gestionar planes de suscripciΓ³n.
+
+**Datos de entrada:**
+- name: string
+- code: string (ΓΊnico)
+- features: object (funcionalidades habilitadas)
+- limits: object (cuotas)
+- price_monthly: decimal
+- price_yearly: decimal
+- is_active: boolean
+
+**Operaciones:**
+- Crear plan
+- Editar plan
+- Activar/desactivar plan
+- Ver tenants por plan
+
+**Criterios de aceptaciΓ³n:**
+- [ ] CRUD de planes funciona
+- [ ] Planes inactivos no asignables a nuevos tenants
+- [ ] Cambio de plan en tenant actualiza lΓmites
+
+---
+
+## RF-PMC-001-014: Cambiar Plan de Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-014 |
+| **Nombre** | Cambiar Plan de Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir cambiar el plan de un tenant.
+
+**Flujo principal:**
+1. Super Admin selecciona tenant
+2. Selecciona nuevo plan
+3. Sistema valida compatibilidad
+4. Sistema actualiza plan_id
+5. Nuevos lΓmites se aplican inmediatamente
+6. Sistema notifica a admins del tenant
+
+**Validaciones:**
+- Si downgrade: verificar que uso actual no exceda nuevos lΓmites
+- Warning si usuarios exceden nuevo lΓmite
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Plan se actualiza correctamente
+- [ ] LΓmites se aplican inmediatamente
+- [ ] Warnings apropiados en downgrade
+
+---
+
+## RF-PMC-001-015: Ver Uso del Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-001-015 |
+| **Nombre** | Ver Uso del Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin, Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe mostrar mΓ©tricas de uso del tenant.
+
+**Datos de salida:**
+- Generaciones: usado/lΓmite
+- Storage: usado/lΓmite (GB)
+- Usuarios: activos/lΓmite
+- Entrenamientos: usado/lΓmite
+- PerΓodo de facturaciΓ³n actual
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓ©tricas se calculan correctamente
+- [ ] Porcentajes y grΓ‘ficos visuales
+- [ ] Alertas cuando se acerca al lΓmite (>80%)
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 6 |
+| P2 | 6 |
+| P3 | 3 |
+| **Total** | **15** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-002-CRM.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-002-CRM.md
new file mode 100644
index 0000000..bf78881
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-002-CRM.md
@@ -0,0 +1,587 @@
+# Requerimientos Funcionales - PMC-002 CRM
+
+**MΓ³dulo:** CRM
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GestiΓ³n de Clientes
+
+### RF-PMC-002-001: Crear Cliente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-001 |
+| **Nombre** | Crear Cliente |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir registrar un nuevo cliente de la agencia.
+
+**Datos de entrada:**
+- name: string (requerido)
+- legal_name: string (opcional)
+- tax_id: string (opcional)
+- industry: string (opcional)
+- size: enum (opcional)
+- website: string (opcional)
+- notes: text (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Cliente se crea con status "prospect"
+- [ ] tenant_id se asigna automΓ‘ticamente
+- [ ] ValidaciΓ³n de datos funciona
+
+---
+
+### RF-PMC-002-002: Editar Cliente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-002 |
+| **Nombre** | Editar Cliente |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir modificar datos de un cliente existente.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todos los campos editables se actualizan
+- [ ] Cambio de status registra historial
+- [ ] Audit log registra modificaciones
+
+---
+
+### RF-PMC-002-003: Listar Clientes
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-003 |
+| **Nombre** | Listar Clientes |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**DescripciΓ³n:**
+El sistema debe mostrar lista de clientes con filtros y paginaciΓ³n.
+
+**Filtros disponibles:**
+- status: prospect, active, inactive, churned
+- industry: string
+- size: enum
+- search: nombre o legal_name
+
+**Criterios de aceptaciΓ³n:**
+- [ ] PaginaciΓ³n funciona correctamente
+- [ ] Filtros se combinan con AND
+- [ ] Ordenamiento por nombre/fecha
+
+---
+
+### RF-PMC-002-004: Ver Ficha de Cliente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-004 |
+| **Nombre** | Ver Ficha de Cliente |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**DescripciΓ³n:**
+El sistema debe mostrar vista detallada del cliente con informaciΓ³n relacionada.
+
+**Datos mostrados:**
+- InformaciΓ³n bΓ‘sica
+- Contactos asociados
+- Marcas del cliente
+- Proyectos activos
+- Oportunidades abiertas
+- Historial de actividad
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Tabs organizan informaciΓ³n
+- [ ] Datos relacionados cargan correctamente
+- [ ] Acciones rΓ‘pidas disponibles
+
+---
+
+### RF-PMC-002-005: Eliminar Cliente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-005 |
+| **Nombre** | Eliminar Cliente |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+El sistema debe permitir eliminar un cliente (soft delete).
+
+**Validaciones:**
+- No tiene proyectos activos
+- ConfirmaciΓ³n requerida
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Soft delete funciona
+- [ ] Validaciones impiden eliminaciΓ³n si hay dependencias activas
+
+---
+
+## GestiΓ³n de Contactos
+
+### RF-PMC-002-006: Crear Contacto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-006 |
+| **Nombre** | Crear Contacto |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**Datos de entrada:**
+- client_id: UUID (requerido)
+- first_name: string (requerido)
+- last_name: string (requerido)
+- email: string (requerido)
+- phone: string (opcional)
+- position: string (opcional)
+- is_primary: boolean (default false)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Contacto se asocia al cliente
+- [ ] Email validado (formato)
+- [ ] Solo un contacto primario por cliente
+
+---
+
+### RF-PMC-002-007: Editar Contacto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-007 |
+| **Nombre** | Editar Contacto |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos se actualizan correctamente
+- [ ] Cambio de is_primary actualiza otros contactos
+
+---
+
+### RF-PMC-002-008: Listar Contactos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-008 |
+| **Nombre** | Listar Contactos |
+| **Prioridad** | P2 |
+| **Actor** | Todos los roles |
+
+**DescripciΓ³n:**
+Listar contactos del tenant o de un cliente especΓfico.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtro por cliente funciona
+- [ ] BΓΊsqueda por nombre/email
+- [ ] PaginaciΓ³n implementada
+
+---
+
+### RF-PMC-002-009: Marcar Contacto Primario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-009 |
+| **Nombre** | Marcar Contacto Primario |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+Designar un contacto como principal del cliente.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Solo un contacto primario por cliente
+- [ ] Al marcar uno, otros se desmarcan automΓ‘ticamente
+
+---
+
+## GestiΓ³n de Marcas
+
+### RF-PMC-002-010: Crear Marca
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-010 |
+| **Nombre** | Crear Marca |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- client_id: UUID (requerido)
+- name: string (requerido)
+- description: text (opcional)
+- identity: object (opcional)
+ - logo_url
+ - primary_color
+ - secondary_colors
+ - typography
+ - tone_of_voice
+ - keywords
+ - forbidden_words
+ - visual_style
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Marca se asocia al cliente
+- [ ] Identity se almacena como JSONB
+- [ ] Logo se puede subir o referenciar URL
+
+---
+
+### RF-PMC-002-011: Editar Marca
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-011 |
+| **Nombre** | Editar Marca |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todos los campos de identity editables
+- [ ] Preview de colores en tiempo real
+- [ ] Cambios se propagan a nuevas generaciones
+
+---
+
+### RF-PMC-002-012: Definir Identidad Visual
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-012 |
+| **Nombre** | Definir Identidad Visual |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**DescripciΓ³n:**
+Configurar todos los elementos de identidad visual de la marca.
+
+**Campos de identidad:**
+- Logo (principal y variaciones)
+- Paleta de colores
+- TipografΓas
+- Tono de voz
+- Keywords positivas
+- Palabras prohibidas
+- Estilo visual preferido
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Formulario estructurado para cada secciΓ³n
+- [ ] Upload de logos funciona
+- [ ] Preview visual de paleta de colores
+
+---
+
+### RF-PMC-002-013: Asociar LoRA a Marca
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-013 |
+| **Nombre** | Asociar LoRA a Marca |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**DescripciΓ³n:**
+Vincular modelos LoRA entrenados con una marca.
+
+**Flujo:**
+1. Usuario accede a configuraciΓ³n de marca
+2. Selecciona "Modelos IA"
+3. Elige LoRA(s) del catΓ‘logo del tenant
+4. Sistema vincula LoRA con marca
+5. LoRA se usa automΓ‘ticamente en generaciones de la marca
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓΊltiples LoRAs pueden asociarse
+- [ ] LoRA se aplica por defecto en generaciΓ³n
+- [ ] DesasociaciΓ³n funciona
+
+---
+
+### RF-PMC-002-014: Listar Marcas
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-014 |
+| **Nombre** | Listar Marcas |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtro por cliente funciona
+- [ ] Preview de logo/colores en lista
+- [ ] BΓΊsqueda por nombre
+
+---
+
+## GestiΓ³n de Productos
+
+### RF-PMC-002-015: Crear Producto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-015 |
+| **Nombre** | Crear Producto |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Analyst |
+
+**Datos de entrada:**
+- brand_id: UUID (requerido)
+- name: string (requerido)
+- sku: string (opcional)
+- description: text (opcional)
+- category: string (opcional)
+- attributes: object (precio, features, etc.)
+- reference_images: array[file] (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Producto se asocia a marca
+- [ ] ImΓ‘genes de referencia se almacenan
+- [ ] Status inicial "active"
+
+---
+
+### RF-PMC-002-016: Editar Producto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-016 |
+| **Nombre** | Editar Producto |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Analyst |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos se actualizan correctamente
+- [ ] ImΓ‘genes de referencia pueden agregarse/quitarse
+
+---
+
+### RF-PMC-002-017: Subir ImΓ‘genes de Referencia
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-017 |
+| **Nombre** | Subir ImΓ‘genes de Referencia |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Analyst |
+
+**DescripciΓ³n:**
+Agregar fotos reales del producto para usar como referencia en generaciΓ³n.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Upload mΓΊltiple funciona
+- [ ] Formatos: JPG, PNG, WebP
+- [ ] TamaΓ±o mΓ‘ximo: 10MB por imagen
+- [ ] Thumbnails generados automΓ‘ticamente
+
+---
+
+### RF-PMC-002-018: Trigger GeneraciΓ³n desde Producto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-018 |
+| **Nombre** | Trigger GeneraciΓ³n desde Producto |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Iniciar generaciΓ³n de contenido directamente desde la ficha de producto.
+
+**Flujo:**
+1. Usuario ve ficha de producto
+2. Selecciona "Generar contenido"
+3. Elige workflow template
+4. Configura opciones (cantidad, estilo)
+5. Sistema crea job de generaciΓ³n
+6. Sistema redirige a monitor o muestra progreso
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Datos del producto se cargan al job
+- [ ] Identidad de marca se incluye
+- [ ] LoRAs se aplican automΓ‘ticamente
+
+---
+
+### RF-PMC-002-019: Listar Productos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-019 |
+| **Nombre** | Listar Productos |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtro por marca funciona
+- [ ] Vista de catΓ‘logo con imΓ‘genes
+- [ ] BΓΊsqueda por nombre/SKU
+
+---
+
+## GestiΓ³n de Oportunidades
+
+### RF-PMC-002-020: Crear Oportunidad
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-020 |
+| **Nombre** | Crear Oportunidad |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**Datos de entrada:**
+- client_id: UUID (requerido)
+- name: string (requerido)
+- description: text (opcional)
+- value: decimal (opcional)
+- currency: string (default: USD)
+- expected_close_date: date (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Stage inicial "lead"
+- [ ] Probability calculada por stage
+
+---
+
+### RF-PMC-002-021: Mover Oportunidad en Pipeline
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-021 |
+| **Nombre** | Mover Oportunidad en Pipeline |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+Cambiar stage de una oportunidad mediante drag & drop o acciΓ³n directa.
+
+**Stages:**
+- lead β qualified β proposal β negotiation β won/lost
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Drag & drop en vista Kanban
+- [ ] Probability se actualiza automΓ‘ticamente
+- [ ] Registro de historial de cambios
+
+---
+
+### RF-PMC-002-022: Cerrar Oportunidad como Ganada
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-022 |
+| **Nombre** | Cerrar Oportunidad como Ganada |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**Flujo:**
+1. Usuario mueve a stage "won"
+2. Sistema solicita valor final confirmado
+3. Sistema marca como ganada
+4. Sistema ofrece crear proyecto
+
+**Criterios de aceptaciΓ³n:**
+- [ ] actual_close_date se registra
+- [ ] OpciΓ³n de crear proyecto disponible
+
+---
+
+### RF-PMC-002-023: Cerrar Oportunidad como Perdida
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-023 |
+| **Nombre** | Cerrar Oportunidad como Perdida |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**Flujo:**
+1. Usuario mueve a stage "lost"
+2. Sistema solicita motivo de pΓ©rdida
+3. Sistema registra lost_reason
+4. Sistema marca como perdida
+
+**Criterios de aceptaciΓ³n:**
+- [ ] lost_reason es requerido
+- [ ] Oportunidad no editable despuΓ©s de cerrar
+
+---
+
+### RF-PMC-002-024: Convertir Oportunidad en Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-024 |
+| **Nombre** | Convertir Oportunidad en Proyecto |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+Crear proyecto automΓ‘ticamente desde oportunidad ganada.
+
+**Flujo:**
+1. Usuario selecciona "Convertir a proyecto"
+2. Sistema muestra formulario pre-llenado
+3. Usuario confirma/modifica datos
+4. Sistema crea proyecto vinculado al cliente
+5. Sistema vincula oportunidad con proyecto
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Datos del cliente se heredan
+- [ ] DescripciΓ³n de oportunidad se copia a proyecto
+- [ ] RelaciΓ³n bidireccional establecida
+
+---
+
+### RF-PMC-002-025: Vista Kanban de Oportunidades
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-002-025 |
+| **Nombre** | Vista Kanban de Oportunidades |
+| **Prioridad** | P2 |
+| **Actor** | Analyst, Tenant Admin |
+
+**DescripciΓ³n:**
+Mostrar pipeline de oportunidades en formato Kanban.
+
+**CaracterΓsticas:**
+- Columnas por stage
+- Cards con info resumida
+- Drag & drop entre columnas
+- Filtros por cliente, fecha, valor
+- Totales por columna
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Drag & drop funciona
+- [ ] Totales se calculan correctamente
+- [ ] Filtros se aplican en tiempo real
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 14 |
+| P2 | 10 |
+| P3 | 1 |
+| **Total** | **25** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-003-PROJECTS.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-003-PROJECTS.md
new file mode 100644
index 0000000..459253a
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-003-PROJECTS.md
@@ -0,0 +1,503 @@
+# Requerimientos Funcionales - PMC-003 Projects
+
+**MΓ³dulo:** Projects
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GestiΓ³n de Proyectos
+
+### RF-PMC-003-001: Crear Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-001 |
+| **Nombre** | Crear Proyecto |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- client_id: UUID (requerido)
+- name: string (requerido)
+- description: text (opcional)
+- start_date: date (opcional)
+- end_date: date (opcional)
+- budget: decimal (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Proyecto se crea con status "draft"
+- [ ] CΓ³digo autogenerado (PRJ-YYYY-XXX)
+- [ ] Owner asignado al creador
+
+---
+
+### RF-PMC-003-002: Editar Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-002 |
+| **Nombre** | Editar Proyecto |
+| **Prioridad** | P1 |
+| **Actor** | Project Owner, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos bΓ‘sicos editables
+- [ ] Cambio de cliente requiere confirmaciΓ³n
+- [ ] Historial de cambios registrado
+
+---
+
+### RF-PMC-003-003: Cambiar Estado de Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-003 |
+| **Nombre** | Cambiar Estado de Proyecto |
+| **Prioridad** | P1 |
+| **Actor** | Project Owner, Tenant Admin |
+
+**Estados vΓ‘lidos:**
+- draft β active
+- active β on_hold, completed
+- on_hold β active
+- cualquiera β cancelled
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Transiciones vΓ‘lidas se permiten
+- [ ] Transiciones invΓ‘lidas se bloquean
+- [ ] NotificaciΓ³n al equipo en cambio de estado
+
+---
+
+### RF-PMC-003-004: Asignar Equipo a Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-004 |
+| **Nombre** | Asignar Equipo a Proyecto |
+| **Prioridad** | P2 |
+| **Actor** | Project Owner, Tenant Admin |
+
+**DescripciΓ³n:**
+Agregar o quitar miembros del equipo de un proyecto.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Usuarios del tenant pueden asignarse
+- [ ] Owner siempre estΓ‘ en el equipo
+- [ ] NotificaciΓ³n al agregar miembro
+
+---
+
+### RF-PMC-003-005: Listar Proyectos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-005 |
+| **Nombre** | Listar Proyectos |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Filtros:**
+- client_id
+- status
+- owner_id
+- date_range
+
+**Criterios de aceptaciΓ³n:**
+- [ ] PaginaciΓ³n funciona
+- [ ] Filtros combinables
+- [ ] Vista lista y tarjetas
+
+---
+
+### RF-PMC-003-006: Ver Dashboard de Proyecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-006 |
+| **Nombre** | Ver Dashboard de Proyecto |
+| **Prioridad** | P1 |
+| **Actor** | Miembros del proyecto |
+
+**InformaciΓ³n mostrada:**
+- Resumen del proyecto
+- CampaΓ±as con estado
+- Assets recientes
+- Actividad del equipo
+- MΓ©tricas de progreso
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Dashboard carga correctamente
+- [ ] MΓ©tricas calculadas en tiempo real
+- [ ] Acciones rΓ‘pidas disponibles
+
+---
+
+## GestiΓ³n de CampaΓ±as
+
+### RF-PMC-003-007: Crear CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-007 |
+| **Nombre** | Crear CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- project_id: UUID (requerido)
+- brand_id: UUID (requerido)
+- name: string (requerido)
+- type: enum (requerido)
+- channels: array[string]
+- start_date: date (opcional)
+- end_date: date (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] CampaΓ±a se crea con status "draft"
+- [ ] Brand se vincula correctamente
+- [ ] Brief vacΓo se inicializa
+
+---
+
+### RF-PMC-003-008: Editar CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-008 |
+| **Nombre** | Editar CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos bΓ‘sicos editables en cualquier estado
+- [ ] Brief editable hasta "in_production"
+
+---
+
+### RF-PMC-003-009: Completar Brief de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-009 |
+| **Nombre** | Completar Brief de CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Secciones del Brief:**
+- Objetivo: descripciΓ³n, KPIs
+- Audiencia: demographics, psychographics, pain_points
+- Mensajes: main_message, tone, CTA, hashtags
+- Visual: style, mood, color_palette, references
+- Restricciones: forbidden_words, disclaimers
+- Entregables: formatos, cantidades
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Formulario con secciones colapsables
+- [ ] ValidaciΓ³n de campos mΓnimos
+- [ ] Guardado automΓ‘tico (draft)
+- [ ] Al completar: estado β "briefing"
+
+---
+
+### RF-PMC-003-010: Usar Plantilla de Brief
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-010 |
+| **Nombre** | Usar Plantilla de Brief |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Cargar brief desde una plantilla predefinida.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Listado de plantillas disponibles
+- [ ] Preview de plantilla antes de aplicar
+- [ ] Campos se pre-llenan pero son editables
+
+---
+
+### RF-PMC-003-011: Cambiar Estado de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-011 |
+| **Nombre** | Cambiar Estado de CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Estados y transiciones:**
+```
+draft β briefing β in_production β review β approved β published
+ β_______________|
+ (revision_requested)
+```
+
+**Validaciones:**
+- briefing β in_production: brief mΓnimo completado
+- review β approved: al menos 1 asset aprobado
+- approved β published: confirmaciΓ³n requerida
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Transiciones vΓ‘lidas funcionan
+- [ ] Validaciones se aplican
+- [ ] Notificaciones en cada cambio
+
+---
+
+### RF-PMC-003-012: Listar CampaΓ±as
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-012 |
+| **Nombre** | Listar CampaΓ±as |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Vistas:**
+- Lista con filtros
+- Kanban por estado
+- Calendario por fechas
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtro por proyecto, brand, status, type
+- [ ] Vista Kanban con drag & drop
+- [ ] BΓΊsqueda por nombre
+
+---
+
+### RF-PMC-003-013: Ver Detalle de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-013 |
+| **Nombre** | Ver Detalle de CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Miembros del proyecto |
+
+**InformaciΓ³n mostrada:**
+- Datos de campaΓ±a
+- Brief completo
+- Assets generados con estados
+- Historial de actividad
+- Jobs de generaciΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todas las secciones visibles
+- [ ] Assets organizados por estado
+- [ ] Acciones contextuales disponibles
+
+---
+
+## GeneraciΓ³n de Contenido
+
+### RF-PMC-003-014: Lanzar GeneraciΓ³n desde CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-014 |
+| **Nombre** | Lanzar GeneraciΓ³n desde CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Flujo:**
+1. Usuario abre campaΓ±a en status "briefing" o superior
+2. Selecciona "Generar contenido"
+3. Elige workflows segΓΊn deliverables del brief
+4. Configura opciones adicionales
+5. Sistema crea jobs de generaciΓ³n
+6. Sistema cambia status a "in_production" si no lo estΓ‘
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Brief se usa para configurar generaciΓ³n
+- [ ] MΓΊltiples workflows ejecutables
+- [ ] Progreso visible en tiempo real
+
+---
+
+### RF-PMC-003-015: Seleccionar Workflows de GeneraciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-015 |
+| **Nombre** | Seleccionar Workflows de GeneraciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Elegir quΓ© workflows ejecutar basado en deliverables del brief.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Workflows sugeridos segΓΊn tipo de campaΓ±a
+- [ ] Preview de cada workflow
+- [ ] ConfiguraciΓ³n de cantidad por workflow
+
+---
+
+### RF-PMC-003-016: Monitorear Progreso de GeneraciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-016 |
+| **Nombre** | Monitorear Progreso de GeneraciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**InformaciΓ³n mostrada:**
+- Jobs en cola
+- Jobs procesando (con %)
+- Jobs completados
+- Jobs fallidos
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ActualizaciΓ³n en tiempo real (websocket)
+- [ ] Posibilidad de cancelar jobs pendientes
+- [ ] Reintentar jobs fallidos
+
+---
+
+## Flujo de AprobaciΓ³n
+
+### RF-PMC-003-017: Aprobar Asset de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-017 |
+| **Nombre** | Aprobar Asset de CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Flujo:**
+1. Usuario revisa asset en vista de revisiΓ³n
+2. Selecciona "Aprobar"
+3. Sistema marca asset como aprobado
+4. Sistema registra aprobador y timestamp
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Asset cambia a status "approved"
+- [ ] Metadata de aprobaciΓ³n registrada
+- [ ] No editable despuΓ©s de aprobar
+
+---
+
+### RF-PMC-003-018: Rechazar Asset de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-018 |
+| **Nombre** | Rechazar Asset de CampaΓ±a |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Flujo:**
+1. Usuario revisa asset
+2. Selecciona "Rechazar"
+3. Sistema solicita feedback obligatorio
+4. Sistema marca asset como rechazado
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Feedback es requerido
+- [ ] Asset puede regenerarse
+- [ ] Historial de rechazos visible
+
+---
+
+### RF-PMC-003-019: Solicitar RevisiΓ³n de Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-019 |
+| **Nombre** | Solicitar RevisiΓ³n de Asset |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Pedir cambios especΓficos en un asset antes de decidir.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Comentario con posiciΓ³n en imagen
+- [ ] Asset queda en "revision_requested"
+- [ ] NotificaciΓ³n a equipo
+
+---
+
+### RF-PMC-003-020: Aprobar Todos los Assets
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-020 |
+| **Nombre** | Aprobar Todos los Assets |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+AcciΓ³n bulk para aprobar todos los assets pendientes.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ConfirmaciΓ³n requerida
+- [ ] Solo assets en "pending_review"
+- [ ] Registro individual por asset
+
+---
+
+### RF-PMC-003-021: Regenerar Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-021 |
+| **Nombre** | Regenerar Asset |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Crear nueva versiΓ³n de un asset rechazado o en revisiΓ³n.
+
+**Flujo:**
+1. Usuario selecciona asset rechazado
+2. Selecciona "Regenerar"
+3. Opcionalmente ajusta parΓ‘metros
+4. Sistema crea nuevo job
+5. Nuevo asset se vincula como versiΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ParΓ‘metros originales pre-cargados
+- [ ] Historial de versiones mantenido
+- [ ] Original no se elimina
+
+---
+
+### RF-PMC-003-022: Descargar Assets Aprobados
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-003-022 |
+| **Nombre** | Descargar Assets Aprobados |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**DescripciΓ³n:**
+Descargar pack de todos los assets aprobados de la campaΓ±a.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ZIP generado con estructura organizada
+- [ ] Solo assets aprobados incluidos
+- [ ] Copys incluidos como .txt
+- [ ] OpciΓ³n de selecciΓ³n manual
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 15 |
+| P2 | 7 |
+| **Total** | **22** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-004-GENERATION.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-004-GENERATION.md
new file mode 100644
index 0000000..b36aa46
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-004-GENERATION.md
@@ -0,0 +1,641 @@
+# Requerimientos Funcionales - PMC-004 Generation
+
+**MΓ³dulo:** Generation (Motor IA)
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GeneraciΓ³n de ImΓ‘genes
+
+### RF-PMC-004-001: Generar Imagen Text-to-Image
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-001 |
+| **Nombre** | Generar Imagen Text-to-Image |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- prompt: string (requerido)
+- negative_prompt: string (opcional)
+- width: number (default: 1024)
+- height: number (default: 1024)
+- seed: number (opcional, aleatorio si no se especifica)
+- steps: number (default: 30)
+- cfg_scale: number (default: 7.5)
+- lora_id: UUID (opcional)
+- brand_id: UUID (opcional, para cargar LoRA automΓ‘ticamente)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Imagen se genera correctamente
+- [ ] ParΓ‘metros se aplican
+- [ ] LoRA se carga si especificado
+- [ ] Asset se crea automΓ‘ticamente
+
+---
+
+### RF-PMC-004-002: Generar Imagen Image-to-Image
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-002 |
+| **Nombre** | Generar Imagen Image-to-Image |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- input_image: file/URL (requerido)
+- prompt: string (requerido)
+- strength: number (0.0-1.0, default: 0.75)
+- Otros parΓ‘metros de T2I
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Imagen input se procesa correctamente
+- [ ] Strength afecta resultado
+- [ ] Formatos soportados: PNG, JPG, WebP
+
+---
+
+### RF-PMC-004-003: Aplicar Inpainting
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-003 |
+| **Nombre** | Aplicar Inpainting |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- input_image: file/URL (requerido)
+- mask_image: file (requerido)
+- prompt: string (requerido)
+- Otros parΓ‘metros de generaciΓ³n
+
+**DescripciΓ³n:**
+Regenerar solo la parte enmascarada de una imagen.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓ‘scara define Γ‘rea a regenerar
+- [ ] Resto de imagen preservado
+- [ ] Editor de mΓ‘scara en UI
+
+---
+
+### RF-PMC-004-004: Aplicar Upscaling
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-004 |
+| **Nombre** | Aplicar Upscaling |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- input_image: file/URL (requerido)
+- scale: number (2 o 4)
+- model: string (default: "RealESRGAN")
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Imagen se escala correctamente
+- [ ] Calidad mejorada, no solo interpolaciΓ³n
+- [ ] Formatos de salida preservados
+
+---
+
+### RF-PMC-004-005: Generar Batch de ImΓ‘genes
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-005 |
+| **Nombre** | Generar Batch de ImΓ‘genes |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- base_params: object (parΓ‘metros comunes)
+- count: number (cantidad a generar)
+- variation_type: string (seed, prompt_variation)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] N imΓ‘genes generadas
+- [ ] Seeds diferentes por imagen
+- [ ] Todas vinculadas al mismo job
+
+---
+
+### RF-PMC-004-006: Remover Fondo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-006 |
+| **Nombre** | Remover Fondo |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- input_image: file/URL (requerido)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Fondo removido correctamente
+- [ ] Salida PNG con transparencia
+- [ ] Bordes suaves en objetos
+
+---
+
+## GeneraciΓ³n de Texto
+
+### RF-PMC-004-007: Generar Copy Publicitario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-007 |
+| **Nombre** | Generar Copy Publicitario |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- context: object
+ - product_name: string
+ - product_description: string
+ - brand_tone: string
+ - target_audience: string
+ - objective: string
+- type: enum (title, description, cta, full_post)
+- max_length: number (opcional)
+- variations: number (default: 3)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Texto generado coherente
+- [ ] Tono respeta brand guidelines
+- [ ] MΓΊltiples variaciones disponibles
+
+---
+
+### RF-PMC-004-008: Generar Hashtags
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-008 |
+| **Nombre** | Generar Hashtags |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- context: string (descripciΓ³n del contenido)
+- count: number (default: 10)
+- platform: string (instagram, twitter, linkedin)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Hashtags relevantes generados
+- [ ] Formato correcto (#hashtag)
+- [ ] Sin espacios ni caracteres invΓ‘lidos
+
+---
+
+### RF-PMC-004-009: Adaptar Tono de Texto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-009 |
+| **Nombre** | Adaptar Tono de Texto |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- input_text: string (requerido)
+- target_tone: string (formal, casual, playful, professional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Mensaje preservado, tono cambiado
+- [ ] Opciones de tono claras
+
+---
+
+## Workflows
+
+### RF-PMC-004-010: Listar Workflow Templates
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-010 |
+| **Nombre** | Listar Workflow Templates |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de salida:**
+- Lista de workflows disponibles
+- Por cada uno: nombre, descripciΓ³n, tipo, inputs requeridos
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Workflows de sistema incluidos
+- [ ] Workflows custom del tenant incluidos
+- [ ] Filtro por tipo/categorΓa
+
+---
+
+### RF-PMC-004-011: Ver Detalle de Workflow
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-011 |
+| **Nombre** | Ver Detalle de Workflow |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de salida:**
+- DescripciΓ³n completa
+- Inputs requeridos y opcionales
+- Outputs esperados
+- Ejemplos de resultado
+- Tiempo estimado
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Schema de inputs documentado
+- [ ] Ejemplos visuales disponibles
+
+---
+
+### RF-PMC-004-012: Ejecutar Workflow
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-012 |
+| **Nombre** | Ejecutar Workflow |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- workflow_id: UUID (requerido)
+- inputs: object (segΓΊn schema del workflow)
+- campaign_id: UUID (opcional)
+- brand_id: UUID (opcional)
+
+**Flujo:**
+1. Sistema valida inputs contra schema
+2. Sistema verifica cuotas del tenant
+3. Sistema crea GenerationJob
+4. Sistema encola job
+5. Sistema retorna job_id
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ValidaciΓ³n de inputs funciona
+- [ ] Job se crea correctamente
+- [ ] ID retornado para tracking
+
+---
+
+### RF-PMC-004-013: Crear Workflow Template (Admin)
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-013 |
+| **Nombre** | Crear Workflow Template |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- name: string
+- description: text
+- type: enum
+- comfyui_workflow: JSON
+- input_schema: JSON
+- output_config: object
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Workflow se almacena correctamente
+- [ ] Schema de inputs validado
+- [ ] Disponible para usuarios del tenant
+
+---
+
+## Modelos Personalizados
+
+### RF-PMC-004-014: Listar Modelos Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-014 |
+| **Nombre** | Listar Modelos Custom |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de salida:**
+- Lista de LoRAs, checkpoints disponibles
+- Status de cada uno
+- Brand asociada (si aplica)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Solo modelos del tenant
+- [ ] Filtro por tipo y brand
+- [ ] Preview images mostradas
+
+---
+
+### RF-PMC-004-015: Registrar Modelo Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-015 |
+| **Nombre** | Registrar Modelo Custom |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- name: string (requerido)
+- type: enum (lora, checkpoint, embedding)
+- file: upload (requerido)
+- purpose: string
+- trigger_word: string (para LoRAs)
+- brand_id: UUID (opcional)
+- preview_images: array[file]
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Archivo subido a storage
+- [ ] Registro en BD
+- [ ] Disponible para generaciΓ³n
+
+---
+
+### RF-PMC-004-016: Eliminar Modelo Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-016 |
+| **Nombre** | Eliminar Modelo Custom |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ConfirmaciΓ³n requerida
+- [ ] Archivo eliminado de storage
+- [ ] Registro eliminado de BD
+
+---
+
+### RF-PMC-004-017: Iniciar Entrenamiento de LoRA
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-017 |
+| **Nombre** | Iniciar Entrenamiento de LoRA |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- name: string
+- training_images: array[file] (mΓnimo 10)
+- base_model: string
+- steps: number (default: 1000)
+- learning_rate: number (default: 0.0001)
+- trigger_word: string (requerido)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓnimo 10 imΓ‘genes validado
+- [ ] Job de entrenamiento creado
+- [ ] Status actualizado durante entrenamiento
+- [ ] Modelo disponible al completar
+
+---
+
+## Cola de Tareas
+
+### RF-PMC-004-018: Ver Estado de Cola
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-018 |
+| **Nombre** | Ver Estado de Cola |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de salida:**
+- Jobs en cola (pending)
+- Jobs procesando
+- Jobs completados (recientes)
+- Jobs fallidos (recientes)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ActualizaciΓ³n en tiempo real
+- [ ] Filtro por usuario/campaΓ±a
+- [ ] Progreso visible para jobs activos
+
+---
+
+### RF-PMC-004-019: Ver Detalle de Job
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-019 |
+| **Nombre** | Ver Detalle de Job |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de salida:**
+- ParΓ‘metros de entrada
+- Status y progreso
+- Timestamps
+- Outputs generados
+- Error (si fallΓ³)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Toda la informaciΓ³n visible
+- [ ] Links a assets generados
+
+---
+
+### RF-PMC-004-020: Cancelar Job
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-020 |
+| **Nombre** | Cancelar Job |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Precondiciones:**
+- Job en status "queued"
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Job cambia a "cancelled"
+- [ ] No se ejecuta
+- [ ] Cuota no consumida
+
+---
+
+### RF-PMC-004-021: Reintentar Job Fallido
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-021 |
+| **Nombre** | Reintentar Job Fallido |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Precondiciones:**
+- Job en status "failed"
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Nuevo job creado con mismos parΓ‘metros
+- [ ] Original marcado como "retried"
+- [ ] Hasta 3 reintentos permitidos
+
+---
+
+### RF-PMC-004-022: Cambiar Prioridad de Job (Admin)
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-022 |
+| **Nombre** | Cambiar Prioridad de Job |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Precondiciones:**
+- Job en status "queued"
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Prioridad actualizada
+- [ ] PosiciΓ³n en cola recalculada
+
+---
+
+## IntegraciΓ³n ComfyUI
+
+### RF-PMC-004-023: Enviar Workflow a ComfyUI
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-023 |
+| **Nombre** | Enviar Workflow a ComfyUI |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+El sistema debe enviar workflows a ComfyUI para ejecuciΓ³n.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Payload correcto enviado
+- [ ] Respuesta de ComfyUI procesada
+- [ ] Errores manejados correctamente
+
+---
+
+### RF-PMC-004-024: Recibir Resultados de ComfyUI
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-024 |
+| **Nombre** | Recibir Resultados de ComfyUI |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+El sistema debe procesar callbacks/webhooks de ComfyUI con resultados.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ImΓ‘genes descargadas y almacenadas
+- [ ] Assets creados automΓ‘ticamente
+- [ ] Job actualizado a "completed"
+
+---
+
+### RF-PMC-004-025: Monitorear Progreso en ComfyUI
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-025 |
+| **Nombre** | Monitorear Progreso en ComfyUI |
+| **Prioridad** | P2 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+Tracking de progreso durante ejecuciΓ³n del workflow.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Websocket conectado a ComfyUI
+- [ ] Progreso actualizado en tiempo real
+- [ ] Propagado a frontend
+
+---
+
+## Validaciones
+
+### RF-PMC-004-026: Validar Cuota Antes de GeneraciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-026 |
+| **Nombre** | Validar Cuota Antes de GeneraciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+Verificar lΓmites del tenant antes de aceptar job.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Generaciones mensuales verificadas
+- [ ] Storage verificado para outputs
+- [ ] Error claro si excede lΓmite
+
+---
+
+### RF-PMC-004-027: Agregar Negative Prompts AutomΓ‘ticos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-027 |
+| **Nombre** | Agregar Negative Prompts AutomΓ‘ticos |
+| **Prioridad** | P2 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+AΓ±adir negative prompts de calidad estΓ‘ndar.
+
+**Negative prompts por defecto:**
+- "blurry, low quality, watermark, signature, bad anatomy, deformed..."
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Negativos agregados automΓ‘ticamente
+- [ ] Usuario puede sobreescribir
+- [ ] Configurables por tenant
+
+---
+
+### RF-PMC-004-028: Cargar Identidad de Marca AutomΓ‘ticamente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-004-028 |
+| **Nombre** | Cargar Identidad de Marca AutomΓ‘ticamente |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+Al generar para una campaΓ±a/marca, cargar automΓ‘ticamente:
+- LoRAs asociados
+- Colores de marca (para prompts)
+- Forbidden words (para negative prompts)
+- Tono de voz (para texto)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] LoRA se inyecta en workflow
+- [ ] Colores incluidos en prompt si aplica
+- [ ] Forbidden words en negative prompt
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 17 |
+| P2 | 9 |
+| P3 | 2 |
+| **Total** | **28** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-005-AUTOMATION.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-005-AUTOMATION.md
new file mode 100644
index 0000000..d1e394f
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-005-AUTOMATION.md
@@ -0,0 +1,414 @@
+# Requerimientos Funcionales - PMC-005 Automation
+
+**MΓ³dulo:** Automation
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GestiΓ³n de Flujos
+
+### RF-PMC-005-001: Listar Flujos de AutomatizaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-001 |
+| **Nombre** | Listar Flujos de AutomatizaciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de salida:**
+- Lista de flujos disponibles
+- Estado (activo/inactivo)
+- Tipo (trigger_based, scheduled, manual)
+- Γltima ejecuciΓ³n
+- Conteo de ejecuciones
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Flujos de sistema y custom listados
+- [ ] Filtro por tipo y estado
+- [ ] Ordenamiento por nombre/ΓΊltima ejecuciΓ³n
+
+---
+
+### RF-PMC-005-002: Ver Detalle de Flujo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-002 |
+| **Nombre** | Ver Detalle de Flujo |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de salida:**
+- DescripciΓ³n completa
+- Evento trigger
+- ConfiguraciΓ³n
+- Historial de ejecuciones recientes
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Toda la informaciΓ³n visible
+- [ ] Link a workflow en n8n (admin)
+
+---
+
+### RF-PMC-005-003: Activar Flujo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-003 |
+| **Nombre** | Activar Flujo |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+Habilitar un flujo para que procese eventos.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] is_active cambia a true
+- [ ] Flujo comienza a procesar eventos
+- [ ] Registro en audit log
+
+---
+
+### RF-PMC-005-004: Desactivar Flujo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-004 |
+| **Nombre** | Desactivar Flujo |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+Deshabilitar un flujo sin eliminarlo.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] is_active cambia a false
+- [ ] Eventos son ignorados
+- [ ] ConfiguraciΓ³n preservada
+
+---
+
+### RF-PMC-005-005: Configurar Flujo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-005 |
+| **Nombre** | Configurar Flujo |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- config: object
+ - retry_on_failure: boolean
+ - max_retries: number
+ - timeout_seconds: number
+ - custom_params: object
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ConfiguraciΓ³n se guarda
+- [ ] Valores aplicados en ejecuciones
+- [ ] ValidaciΓ³n de rangos
+
+---
+
+### RF-PMC-005-006: Ejecutar Flujo Manualmente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-006 |
+| **Nombre** | Ejecutar Flujo Manualmente |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+Disparar ejecuciΓ³n manual de un flujo con datos de prueba.
+
+**Datos de entrada:**
+- flow_id: UUID
+- test_data: object (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] EjecuciΓ³n inicia inmediatamente
+- [ ] Datos de prueba inyectados
+- [ ] Resultado visible al completar
+
+---
+
+## Ejecuciones
+
+### RF-PMC-005-007: Ver Historial de Ejecuciones
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-007 |
+| **Nombre** | Ver Historial de Ejecuciones |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Lista de ejecuciones con:
+ - Timestamp
+ - Status
+ - DuraciΓ³n
+ - Trigger data (resumen)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] PaginaciΓ³n implementada
+- [ ] Filtro por status y fecha
+- [ ] Click para ver detalle
+
+---
+
+### RF-PMC-005-008: Ver Detalle de EjecuciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-008 |
+| **Nombre** | Ver Detalle de EjecuciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Datos del trigger completos
+- Output data
+- Error message (si fallΓ³)
+- DuraciΓ³n
+- Timestamps
+
+**Criterios de aceptaciΓ³n:**
+- [ ] JSON viewer para datos complejos
+- [ ] Error stack visible en fallos
+
+---
+
+### RF-PMC-005-009: Cancelar EjecuciΓ³n en Curso
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-009 |
+| **Nombre** | Cancelar EjecuciΓ³n en Curso |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Precondiciones:**
+- EjecuciΓ³n en status "running"
+
+**Criterios de aceptaciΓ³n:**
+- [ ] EjecuciΓ³n marcada como "cancelled"
+- [ ] n8n notificado para cancelar
+
+---
+
+## Webhooks
+
+### RF-PMC-005-010: Crear Endpoint de Webhook
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-010 |
+| **Nombre** | Crear Endpoint de Webhook |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- name: string
+- target_flow_id: UUID
+
+**Datos de salida:**
+- slug generado
+- URL completa
+- secret_key generado
+
+**Criterios de aceptaciΓ³n:**
+- [ ] URL ΓΊnica generada
+- [ ] Secret para validaciΓ³n
+- [ ] Endpoint activo inmediatamente
+
+---
+
+### RF-PMC-005-011: Listar Webhooks
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-011 |
+| **Nombre** | Listar Webhooks |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Lista de endpoints del tenant
+- [ ] URL copiable
+- [ ] Estado y ΓΊltima llamada visible
+
+---
+
+### RF-PMC-005-012: Eliminar Webhook
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-012 |
+| **Nombre** | Eliminar Webhook |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ConfirmaciΓ³n requerida
+- [ ] Endpoint deja de funcionar
+- [ ] Registro eliminado
+
+---
+
+### RF-PMC-005-013: Regenerar Secret de Webhook
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-013 |
+| **Nombre** | Regenerar Secret de Webhook |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+Generar nuevo secret invalidando el anterior.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Nuevo secret generado
+- [ ] Anterior invalidado
+- [ ] Integradores deben actualizar
+
+---
+
+### RF-PMC-005-014: Recibir Webhook Externo
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-014 |
+| **Nombre** | Recibir Webhook Externo |
+| **Prioridad** | P2 |
+| **Actor** | Sistema Externo |
+
+**Flujo:**
+1. Sistema externo hace POST a /hooks/{tenant_slug}/{webhook_slug}
+2. Sistema valida firma HMAC
+3. Sistema busca flujo asociado
+4. Sistema crea ejecuciΓ³n
+5. Sistema responde 202 Accepted
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ValidaciΓ³n HMAC funciona
+- [ ] Payload parseado correctamente
+- [ ] EjecuciΓ³n disparada
+
+---
+
+## Eventos del Sistema
+
+### RF-PMC-005-015: Emitir Eventos Internos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-015 |
+| **Nombre** | Emitir Eventos Internos |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+El sistema debe emitir eventos cuando ocurren acciones relevantes.
+
+**Eventos a emitir:**
+- CRM: client.created, brand.created, product.created
+- Projects: campaign.created, campaign.status_changed, campaign.approved
+- Generation: job.completed, job.failed
+- Assets: asset.approved, all_assets.approved
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Eventos emitidos en cada acciΓ³n
+- [ ] Payload incluye datos relevantes
+- [ ] Flujos suscritos son notificados
+
+---
+
+### RF-PMC-005-016: Suscribir Flujo a Evento
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-016 |
+| **Nombre** | Suscribir Flujo a Evento |
+| **Prioridad** | P1 |
+| **Actor** | Sistema |
+
+**DescripciΓ³n:**
+Asociar un flujo con un evento especΓfico.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Flujo se activa cuando evento ocurre
+- [ ] Datos del evento pasados al flujo
+- [ ] MΓΊltiples flujos pueden suscribirse al mismo evento
+
+---
+
+## Notificaciones
+
+### RF-PMC-005-017: Enviar NotificaciΓ³n por Email
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-017 |
+| **Nombre** | Enviar NotificaciΓ³n por Email |
+| **Prioridad** | P1 |
+| **Actor** | Sistema (vΓa n8n) |
+
+**DescripciΓ³n:**
+Enviar emails como parte de flujos automatizados.
+
+**Datos de entrada:**
+- to: string (email)
+- subject: string
+- body: string (HTML)
+- template_id: string (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Email enviado vΓa SMTP/SendGrid
+- [ ] Templates soportados
+- [ ] Variables interpoladas
+
+---
+
+### RF-PMC-005-018: Enviar NotificaciΓ³n a Slack
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-005-018 |
+| **Nombre** | Enviar NotificaciΓ³n a Slack |
+| **Prioridad** | P3 |
+| **Actor** | Sistema (vΓa n8n) |
+
+**DescripciΓ³n:**
+Enviar mensajes a canales de Slack.
+
+**Datos de entrada:**
+- channel: string
+- message: string
+- blocks: array (opcional, formato Slack)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Mensaje enviado al canal
+- [ ] Formato Slack soportado
+- [ ] Webhook configurable por tenant
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 7 |
+| P2 | 7 |
+| P3 | 4 |
+| **Total** | **18** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-006-ASSETS.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-006-ASSETS.md
new file mode 100644
index 0000000..8beb65b
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-006-ASSETS.md
@@ -0,0 +1,511 @@
+# Requerimientos Funcionales - PMC-006 Assets
+
+**MΓ³dulo:** Assets (DAM)
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GestiΓ³n de Assets
+
+### RF-PMC-006-001: Subir Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-001 |
+| **Nombre** | Subir Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- file(s): array[file] (requerido)
+- name: string (opcional, usa filename si vacΓo)
+- description: text (opcional)
+- tags: array[string] (opcional)
+- campaign_id: UUID (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Upload mΓΊltiple funciona
+- [ ] Drag & drop soportado
+- [ ] Thumbnails generados automΓ‘ticamente
+- [ ] Progreso visible durante upload
+
+---
+
+### RF-PMC-006-002: Ver Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-002 |
+| **Nombre** | Ver Asset |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Datos de salida:**
+- Preview/visualizaciΓ³n del asset
+- Metadata completa
+- Historial de versiones
+- Comentarios
+- Estado de aprobaciΓ³n
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Lightbox para imΓ‘genes
+- [ ] Player para videos
+- [ ] Viewer para documentos
+- [ ] Zoom disponible
+
+---
+
+### RF-PMC-006-003: Editar Metadata de Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-003 |
+| **Nombre** | Editar Metadata de Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos editables:**
+- name
+- description
+- tags
+- visibility
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Cambios guardados correctamente
+- [ ] Historial de cambios registrado
+
+---
+
+### RF-PMC-006-004: Eliminar Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-004 |
+| **Nombre** | Eliminar Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Restricciones:**
+- Assets aprobados no pueden eliminarse (solo admin)
+- Soft delete con retenciΓ³n 30 dΓas
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Soft delete funciona
+- [ ] Asset va a papelera
+- [ ] ConfirmaciΓ³n requerida
+
+---
+
+### RF-PMC-006-005: Restaurar Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-005 |
+| **Nombre** | Restaurar Asset |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**DescripciΓ³n:**
+Recuperar asset de la papelera.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Asset restaurado a su estado anterior
+- [ ] deleted_at se limpia
+- [ ] Disponible dentro de 30 dΓas
+
+---
+
+### RF-PMC-006-006: Listar Assets
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-006 |
+| **Nombre** | Listar Assets |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Vistas:**
+- Grid (thumbnails)
+- Lista (tabla con metadata)
+
+**Filtros:**
+- type (image, video, document, copy, model)
+- status (draft, pending_review, approved, rejected)
+- campaign_id
+- collection_id
+- tags
+- date_range
+- source (generated, uploaded)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Ambas vistas funcionan
+- [ ] Filtros combinables
+- [ ] PaginaciΓ³n con scroll infinito o pΓ‘ginas
+- [ ] Ordenamiento mΓΊltiple
+
+---
+
+### RF-PMC-006-007: BΓΊsqueda de Assets
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-007 |
+| **Nombre** | BΓΊsqueda de Assets |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Campos buscables:**
+- name
+- description
+- tags
+- prompt (para generados)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] BΓΊsqueda de texto funciona
+- [ ] Resultados relevantes primero
+- [ ] Highlighting de matches
+
+---
+
+## Colecciones
+
+### RF-PMC-006-008: Crear ColecciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-008 |
+| **Nombre** | Crear ColecciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- name: string (requerido)
+- description: text (opcional)
+- type: enum (manual, smart)
+- smart_filters: object (si type=smart)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ColecciΓ³n creada correctamente
+- [ ] Smart collection ejecuta filtros
+
+---
+
+### RF-PMC-006-009: Editar ColecciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-009 |
+| **Nombre** | Editar ColecciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Nombre y descripciΓ³n editables
+- [ ] Filtros de smart collection editables
+- [ ] Cover image seleccionable
+
+---
+
+### RF-PMC-006-010: Agregar Assets a ColecciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-010 |
+| **Nombre** | Agregar Assets a ColecciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Creative |
+
+**MΓ©todos:**
+- Desde asset detail β "Add to collection"
+- Desde colecciΓ³n β "Add assets"
+- Bulk selection β "Add to collection"
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓΊltiples mΓ©todos funcionan
+- [ ] Asset puede estar en mΓΊltiples colecciones
+- [ ] No duplicados en misma colecciΓ³n
+
+---
+
+### RF-PMC-006-011: Quitar Assets de ColecciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-011 |
+| **Nombre** | Quitar Assets de ColecciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Asset se desvincula de colecciΓ³n
+- [ ] Asset NO se elimina
+- [ ] Bulk removal soportado
+
+---
+
+### RF-PMC-006-012: Eliminar ColecciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-012 |
+| **Nombre** | Eliminar ColecciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ColecciΓ³n eliminada
+- [ ] Assets NO se eliminan
+- [ ] ConfirmaciΓ³n requerida
+
+---
+
+## Versiones
+
+### RF-PMC-006-013: Subir Nueva VersiΓ³n de Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-013 |
+| **Nombre** | Subir Nueva VersiΓ³n de Asset |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de entrada:**
+- asset_id: UUID
+- new_file: file
+- changes_description: text (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Nueva versiΓ³n almacenada
+- [ ] Version number incrementado
+- [ ] VersiΓ³n anterior preservada
+
+---
+
+### RF-PMC-006-014: Ver Historial de Versiones
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-014 |
+| **Nombre** | Ver Historial de Versiones |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Datos de salida:**
+- Lista de versiones con:
+ - NΓΊmero de versiΓ³n
+ - Fecha
+ - Usuario
+ - DescripciΓ³n de cambios
+ - Preview
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Historial completo visible
+- [ ] Click para ver versiΓ³n especΓfica
+- [ ] OpciΓ³n de restaurar versiΓ³n anterior
+
+---
+
+### RF-PMC-006-015: Restaurar VersiΓ³n Anterior
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-015 |
+| **Nombre** | Restaurar VersiΓ³n Anterior |
+| **Prioridad** | P3 |
+| **Actor** | Creative |
+
+**DescripciΓ³n:**
+Hacer que una versiΓ³n anterior sea la actual.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] VersiΓ³n seleccionada se convierte en actual
+- [ ] Nueva versiΓ³n creada (copia)
+- [ ] Historial preservado
+
+---
+
+## AprobaciΓ³n
+
+### RF-PMC-006-016: Aprobar Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-016 |
+| **Nombre** | Aprobar Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "approved"
+- [ ] approved_by y approved_at registrados
+- [ ] Asset no editable despuΓ©s (excepto metadata)
+
+---
+
+### RF-PMC-006-017: Rechazar Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-017 |
+| **Nombre** | Rechazar Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- feedback: text (requerido)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "rejected"
+- [ ] Feedback almacenado
+- [ ] Asset puede regenerarse/versionarse
+
+---
+
+## Comentarios
+
+### RF-PMC-006-018: Agregar Comentario a Asset
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-018 |
+| **Nombre** | Agregar Comentario a Asset |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- content: text (requerido)
+- position: object (x, y) - opcional, para comentarios en imagen
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Comentario se crea
+- [ ] PosiciΓ³n en imagen soportada
+- [ ] NotificaciΓ³n a equipo
+
+---
+
+### RF-PMC-006-019: Responder Comentario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-019 |
+| **Nombre** | Responder Comentario |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Respuesta vinculada al comentario padre
+- [ ] Thread visible
+- [ ] NotificaciΓ³n a participantes
+
+---
+
+### RF-PMC-006-020: Resolver Comentario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-020 |
+| **Nombre** | Resolver Comentario |
+| **Prioridad** | P2 |
+| **Actor** | Creative |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] is_resolved cambia a true
+- [ ] Comentario colapsado visualmente
+- [ ] Puede des-resolverse
+
+---
+
+## Descargas
+
+### RF-PMC-006-021: Descargar Asset Individual
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-021 |
+| **Nombre** | Descargar Asset Individual |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Opciones:**
+- Original
+- Convertido (formato diferente)
+- TamaΓ±o reducido
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Descarga inicia correctamente
+- [ ] Registro de descarga creado
+- [ ] ConversiΓ³n on-the-fly funciona
+
+---
+
+### RF-PMC-006-022: Descargar MΓΊltiples Assets (ZIP)
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-022 |
+| **Nombre** | Descargar MΓΊltiples Assets (ZIP) |
+| **Prioridad** | P1 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- asset_ids: array[UUID]
+- include_metadata: boolean (opcional)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ZIP generado con estructura organizada
+- [ ] Progreso visible para ZIPs grandes
+- [ ] Metadata en JSON opcional
+
+---
+
+### RF-PMC-006-023: Generar Enlace Temporal
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-023 |
+| **Nombre** | Generar Enlace Temporal |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- asset_id: UUID
+- expiry_days: number (default: 7, max: 30)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] URL ΓΊnica generada
+- [ ] Expira despuΓ©s del tiempo configurado
+- [ ] No requiere autenticaciΓ³n para descargar
+
+---
+
+### RF-PMC-006-024: Descargar ColecciΓ³n Completa
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-006-024 |
+| **Nombre** | Descargar ColecciΓ³n Completa |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todos los assets de colecciΓ³n en ZIP
+- [ ] Estructura de carpetas preservada
+- [ ] OpciΓ³n de incluir solo aprobados
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 13 |
+| P2 | 9 |
+| P3 | 2 |
+| **Total** | **24** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-007-ADMIN.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-007-ADMIN.md
new file mode 100644
index 0000000..7f3785a
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-007-ADMIN.md
@@ -0,0 +1,438 @@
+# Requerimientos Funcionales - PMC-007 Admin
+
+**MΓ³dulo:** Admin
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## GestiΓ³n de Usuarios
+
+### RF-PMC-007-001: Listar Usuarios
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-001 |
+| **Nombre** | Listar Usuarios |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Lista de usuarios del tenant
+- Status, rol, ΓΊltimo login
+- Filtros por status y rol
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Solo usuarios del tenant
+- [ ] PaginaciΓ³n funciona
+- [ ] BΓΊsqueda por nombre/email
+
+---
+
+### RF-PMC-007-002: Invitar Usuario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-002 |
+| **Nombre** | Invitar Usuario |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- email: string (requerido)
+- role_id: UUID (requerido)
+- message: text (opcional)
+
+**Flujo:**
+1. Admin ingresa email y selecciona rol
+2. Sistema verifica email no existe en tenant
+3. Sistema crea invitaciΓ³n con token ΓΊnico
+4. Sistema envΓa email con link
+5. InvitaciΓ³n expira en 7 dΓas
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Email de invitaciΓ³n enviado
+- [ ] Token ΓΊnico generado
+- [ ] InvitaciΓ³n listada como pendiente
+
+---
+
+### RF-PMC-007-003: Aceptar InvitaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-003 |
+| **Nombre** | Aceptar InvitaciΓ³n |
+| **Prioridad** | P1 |
+| **Actor** | Usuario invitado |
+
+**Datos de entrada:**
+- token: string (del link)
+- first_name: string
+- last_name: string
+- password: string
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Usuario creado con rol asignado
+- [ ] Password hasheado
+- [ ] InvitaciΓ³n marcada como aceptada
+- [ ] Usuario puede hacer login
+
+---
+
+### RF-PMC-007-004: Editar Usuario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-004 |
+| **Nombre** | Editar Usuario |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos editables:**
+- first_name, last_name
+- role_id
+- status
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Campos se actualizan
+- [ ] Cambio de rol aplica inmediatamente
+- [ ] Audit log registra cambios
+
+---
+
+### RF-PMC-007-005: Suspender Usuario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-005 |
+| **Nombre** | Suspender Usuario |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+Bloquear acceso de un usuario temporalmente.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "suspended"
+- [ ] Sesiones invalidadas
+- [ ] Usuario no puede hacer login
+- [ ] Admin no puede suspenderse a sΓ mismo
+
+---
+
+### RF-PMC-007-006: Reactivar Usuario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-006 |
+| **Nombre** | Reactivar Usuario |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "active"
+- [ ] Usuario puede hacer login
+
+---
+
+### RF-PMC-007-007: Eliminar Usuario
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-007 |
+| **Nombre** | Eliminar Usuario |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Status cambia a "deactivated"
+- [ ] Soft delete
+- [ ] Datos preservados (para auditorΓa)
+- [ ] No puede ser el ΓΊltimo admin
+
+---
+
+### RF-PMC-007-008: Reenviar InvitaciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-008 |
+| **Nombre** | Reenviar InvitaciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Nuevo email enviado
+- [ ] Token regenerado
+- [ ] Expiry extendido
+
+---
+
+## GestiΓ³n de Roles
+
+### RF-PMC-007-009: Listar Roles
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-009 |
+| **Nombre** | Listar Roles |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Roles de sistema
+- Roles custom del tenant
+- Usuarios por rol
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todos los roles listados
+- [ ] IdentificaciΓ³n clara de roles de sistema
+
+---
+
+### RF-PMC-007-010: Ver Permisos de Rol
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-010 |
+| **Nombre** | Ver Permisos de Rol |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Lista de permisos agrupados por mΓ³dulo
+- Checkbox de cada permiso
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Permisos organizados por mΓ³dulo
+- [ ] Visual claro de lo que puede/no puede hacer
+
+---
+
+### RF-PMC-007-011: Crear Rol Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-011 |
+| **Nombre** | Crear Rol Custom |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Datos de entrada:**
+- name: string
+- description: text
+- permissions: array[string]
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Rol creado con is_system=false
+- [ ] Permisos asignados
+- [ ] Disponible para asignar a usuarios
+
+---
+
+### RF-PMC-007-012: Editar Rol Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-012 |
+| **Nombre** | Editar Rol Custom |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Restricciones:**
+- Roles de sistema no editables
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Permisos actualizables
+- [ ] Cambios aplican inmediatamente a usuarios
+
+---
+
+### RF-PMC-007-013: Eliminar Rol Custom
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-013 |
+| **Nombre** | Eliminar Rol Custom |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Restricciones:**
+- No puede tener usuarios asignados
+- Roles de sistema no eliminables
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ValidaciΓ³n de usuarios previo a eliminar
+- [ ] Error si tiene usuarios
+
+---
+
+## ConfiguraciΓ³n
+
+### RF-PMC-007-014: Ver ConfiguraciΓ³n del Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-014 |
+| **Nombre** | Ver ConfiguraciΓ³n del Tenant |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Secciones:**
+- General (nombre, timezone, idioma)
+- Branding
+- GeneraciΓ³n (defaults)
+- Integraciones
+- Notificaciones
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Todas las secciones accesibles
+- [ ] Valores actuales mostrados
+
+---
+
+### RF-PMC-007-015: Editar ConfiguraciΓ³n General
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-015 |
+| **Nombre** | Editar ConfiguraciΓ³n General |
+| **Prioridad** | P1 |
+| **Actor** | Tenant Admin |
+
+**Datos editables:**
+- Nombre del tenant
+- Timezone
+- Idioma por defecto
+- Formato de fecha
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Cambios guardados
+- [ ] Aplican a nuevos usuarios
+- [ ] Usuarios existentes pueden tener preferencia propia
+
+---
+
+### RF-PMC-007-016: Configurar Integraciones
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-016 |
+| **Nombre** | Configurar Integraciones |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Integraciones configurables:**
+- n8n webhook URL
+- Slack webhook
+- SMTP custom (opcional)
+- CRM externo URL
+
+**Criterios de aceptaciΓ³n:**
+- [ ] URLs validadas
+- [ ] Test de conexiΓ³n disponible
+- [ ] Secrets seguros
+
+---
+
+## AuditorΓa
+
+### RF-PMC-007-017: Ver Logs de AuditorΓa
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-017 |
+| **Nombre** | Ver Logs de AuditorΓa |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Filtros:**
+- Usuario
+- AcciΓ³n
+- Entidad
+- Fecha
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Logs listados con paginaciΓ³n
+- [ ] Filtros combinables
+- [ ] Detalle expandible
+
+---
+
+### RF-PMC-007-018: Exportar Logs de AuditorΓa
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-018 |
+| **Nombre** | Exportar Logs de AuditorΓa |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Formatos:**
+- CSV
+- JSON
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtros aplicados en export
+- [ ] Archivo descargable generado
+
+---
+
+## Sistema (Super Admin)
+
+### RF-PMC-007-019: Ver Estado del Sistema
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-019 |
+| **Nombre** | Ver Estado del Sistema |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**MΓ©tricas:**
+- Estado de servicios (API, ComfyUI, Redis, DB)
+- Uso de GPU
+- Cola de generaciΓ³n
+- Storage total
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Dashboard de salud
+- [ ] Alertas en problemas
+
+---
+
+### RF-PMC-007-020: Ver Uso por Tenant
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-007-020 |
+| **Nombre** | Ver Uso por Tenant |
+| **Prioridad** | P2 |
+| **Actor** | Super Admin |
+
+**MΓ©tricas por tenant:**
+- Generaciones
+- Storage
+- Usuarios activos
+- API calls
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Comparativa entre tenants
+- [ ] Exportable
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 8 |
+| P2 | 10 |
+| P3 | 2 |
+| **Total** | **20** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-008-ANALYTICS.md b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-008-ANALYTICS.md
new file mode 100644
index 0000000..6069127
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/RF-PMC-008-ANALYTICS.md
@@ -0,0 +1,356 @@
+# Requerimientos Funcionales - PMC-008 Analytics
+
+**MΓ³dulo:** Analytics
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## Dashboards
+
+### RF-PMC-008-001: Ver Dashboard Principal
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-001 |
+| **Nombre** | Ver Dashboard Principal |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Widgets:**
+- Quick stats (campaΓ±as activas, assets mes, tasa aprobaciΓ³n)
+- Actividad reciente
+- Acciones pendientes
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Dashboard carga correctamente
+- [ ] Datos actualizados
+- [ ] Responsive en diferentes pantallas
+
+---
+
+### RF-PMC-008-002: Ver Dashboard de ProducciΓ³n
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-002 |
+| **Nombre** | Ver Dashboard de ProducciΓ³n |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**Widgets:**
+- Volumen de generaciΓ³n (grΓ‘fico de lΓneas)
+- Estado de cola (gauge)
+- Uso de modelos/workflows (pie chart)
+- Tasa de error
+- Tiempo promedio de procesamiento
+
+**Criterios de aceptaciΓ³n:**
+- [ ] GrΓ‘ficos interactivos
+- [ ] Filtro de perΓodo funciona
+- [ ] Datos en tiempo real para cola
+
+---
+
+### RF-PMC-008-003: Ver Dashboard de CampaΓ±as
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-003 |
+| **Nombre** | Ver Dashboard de CampaΓ±as |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Analyst, Tenant Admin |
+
+**Widgets:**
+- Funnel de campaΓ±as por estado
+- Tasa de aprobaciΓ³n primera iteraciΓ³n
+- Tiempo promedio brief β aprobaciΓ³n
+- Assets por campaΓ±a
+- Top clientes
+
+**Criterios de aceptaciΓ³n:**
+- [ ] MΓ©tricas calculadas correctamente
+- [ ] Drill-down en grΓ‘ficos
+- [ ] Filtro por cliente/perΓodo
+
+---
+
+### RF-PMC-008-004: Ver Dashboard de Recursos
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-004 |
+| **Nombre** | Ver Dashboard de Recursos |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Widgets:**
+- Storage usado vs cuota
+- Generaciones mes vs lΓmite
+- DistribuciΓ³n de storage por tipo
+- ProyecciΓ³n de uso
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Progress bars claras
+- [ ] Alertas en >80% uso
+- [ ] Breakdown por tipo de asset
+
+---
+
+### RF-PMC-008-005: Aplicar Filtros Globales
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-005 |
+| **Nombre** | Aplicar Filtros Globales |
+| **Prioridad** | P1 |
+| **Actor** | Todos los roles |
+
+**Filtros:**
+- PerΓodo (hoy, semana, mes, custom)
+- Cliente
+- Usuario
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtros aplican a todos los widgets
+- [ ] Persistencia durante sesiΓ³n
+- [ ] Reset disponible
+
+---
+
+## Reportes
+
+### RF-PMC-008-006: Generar Reporte de Actividad Mensual
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-006 |
+| **Nombre** | Generar Reporte de Actividad Mensual |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**Contenido:**
+- Resumen ejecutivo
+- CampaΓ±as del perΓodo
+- Assets generados
+- Uso de recursos
+- Comparativa con perΓodo anterior
+
+**Formatos:**
+- PDF
+- Excel
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Reporte generado correctamente
+- [ ] Datos precisos
+- [ ] Formato profesional
+
+---
+
+### RF-PMC-008-007: Generar Reporte de CampaΓ±a
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-007 |
+| **Nombre** | Generar Reporte de CampaΓ±a |
+| **Prioridad** | P2 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- campaign_id: UUID
+
+**Contenido:**
+- Datos de campaΓ±a y brief
+- Assets generados/aprobados
+- Timeline de actividad
+- Participantes
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Reporte especΓfico de campaΓ±a
+- [ ] Incluye thumbnails de assets
+- [ ] PDF descargable
+
+---
+
+### RF-PMC-008-008: Generar Reporte de Cliente
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-008 |
+| **Nombre** | Generar Reporte de Cliente |
+| **Prioridad** | P3 |
+| **Actor** | Analyst, Tenant Admin |
+
+**Datos de entrada:**
+- client_id: UUID
+- date_range: object
+
+**Contenido:**
+- Proyectos y campaΓ±as
+- Assets entregados
+- HistΓ³rico de actividad
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtro de perΓodo funciona
+- [ ] Exportable en PDF/Excel
+
+---
+
+### RF-PMC-008-009: Programar Reporte AutomΓ‘tico
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-009 |
+| **Nombre** | Programar Reporte AutomΓ‘tico |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Opciones:**
+- Frecuencia (semanal, mensual)
+- Destinatarios (emails)
+- Tipo de reporte
+
+**Criterios de aceptaciΓ³n:**
+- [ ] ProgramaciΓ³n guardada
+- [ ] Email enviado automΓ‘ticamente
+- [ ] PDF adjunto
+
+---
+
+### RF-PMC-008-010: Ver Historial de Reportes
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-010 |
+| **Nombre** | Ver Historial de Reportes |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Datos de salida:**
+- Lista de reportes generados
+- Fecha, tipo, generador
+- Link de descarga
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Reportes listados
+- [ ] Descarga disponible (30 dΓas)
+- [ ] Filtro por tipo/fecha
+
+---
+
+## MΓ©tricas
+
+### RF-PMC-008-011: Consultar MΓ©tricas Raw
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-011 |
+| **Nombre** | Consultar MΓ©tricas Raw |
+| **Prioridad** | P2 |
+| **Actor** | Tenant Admin |
+
+**DescripciΓ³n:**
+API para consultar mΓ©tricas agregadas.
+
+**ParΓ‘metros:**
+- metric_type
+- dimensions
+- period
+- filters
+
+**Criterios de aceptaciΓ³n:**
+- [ ] API retorna datos correctos
+- [ ] Agregaciones funcionan
+- [ ] PaginaciΓ³n para grandes volΓΊmenes
+
+---
+
+### RF-PMC-008-012: Exportar Datos de MΓ©tricas
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-012 |
+| **Nombre** | Exportar Datos de MΓ©tricas |
+| **Prioridad** | P3 |
+| **Actor** | Tenant Admin |
+
+**Formatos:**
+- CSV
+- JSON
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Filtros aplicados
+- [ ] Formato correcto
+- [ ] Γtil para BI externo
+
+---
+
+## PersonalizaciΓ³n
+
+### RF-PMC-008-013: Guardar Vista Personalizada
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-013 |
+| **Nombre** | Guardar Vista Personalizada |
+| **Prioridad** | P3 |
+| **Actor** | Creative, Tenant Admin |
+
+**Datos de entrada:**
+- name: string
+- dashboard: string
+- config: object (filtros, widgets visibles)
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Vista guardada
+- [ ] Cargable posteriormente
+- [ ] Por usuario
+
+---
+
+### RF-PMC-008-014: Establecer Vista por Defecto
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-014 |
+| **Nombre** | Establecer Vista por Defecto |
+| **Prioridad** | P3 |
+| **Actor** | Creative, Tenant Admin |
+
+**DescripciΓ³n:**
+Marcar una vista guardada como la que se carga al abrir dashboard.
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Vista se carga automΓ‘ticamente
+- [ ] Una sola vista por defecto por dashboard
+
+---
+
+### RF-PMC-008-015: Eliminar Vista Guardada
+
+| Campo | Valor |
+|-------|-------|
+| **ID** | RF-PMC-008-015 |
+| **Nombre** | Eliminar Vista Guardada |
+| **Prioridad** | P3 |
+| **Actor** | Creative, Tenant Admin |
+
+**Criterios de aceptaciΓ³n:**
+- [ ] Vista eliminada
+- [ ] Si era default, se usa vista estΓ‘ndar
+
+---
+
+## Resumen
+
+| Prioridad | Cantidad |
+|-----------|----------|
+| P1 | 2 |
+| P2 | 6 |
+| P3 | 7 |
+| **Total** | **15** |
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/03-requerimientos/_INDEX.md b/projects/platform_marketing_content/docs/03-requerimientos/_INDEX.md
new file mode 100644
index 0000000..fc9f3f1
--- /dev/null
+++ b/projects/platform_marketing_content/docs/03-requerimientos/_INDEX.md
@@ -0,0 +1,58 @@
+# Γndice de Requerimientos Funcionales
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## Documentos de Requerimientos
+
+| ID | MΓ³dulo | Documento | RFs | Estado |
+|----|--------|-----------|-----|--------|
+| RF-001 | Tenants | [RF-PMC-001-TENANTS.md](./RF-PMC-001-TENANTS.md) | 15 | Definido |
+| RF-002 | CRM | [RF-PMC-002-CRM.md](./RF-PMC-002-CRM.md) | 25 | Definido |
+| RF-003 | Projects | [RF-PMC-003-PROJECTS.md](./RF-PMC-003-PROJECTS.md) | 22 | Definido |
+| RF-004 | Generation | [RF-PMC-004-GENERATION.md](./RF-PMC-004-GENERATION.md) | 28 | Definido |
+| RF-005 | Automation | [RF-PMC-005-AUTOMATION.md](./RF-PMC-005-AUTOMATION.md) | 18 | Definido |
+| RF-006 | Assets | [RF-PMC-006-ASSETS.md](./RF-PMC-006-ASSETS.md) | 24 | Definido |
+| RF-007 | Admin | [RF-PMC-007-ADMIN.md](./RF-PMC-007-ADMIN.md) | 20 | Definido |
+| RF-008 | Analytics | [RF-PMC-008-ANALYTICS.md](./RF-PMC-008-ANALYTICS.md) | 15 | Definido |
+
+**Total de Requerimientos Funcionales:** 167
+
+---
+
+## Nomenclatura
+
+```
+RF-PMC-XXX-YYY
+
+Donde:
+- RF: Requerimiento Funcional
+- PMC: Platform Marketing Content
+- XXX: ID del mΓ³dulo (001-008)
+- YYY: NΓΊmero secuencial del requerimiento
+```
+
+---
+
+## Prioridades
+
+| Prioridad | DescripciΓ³n | Criterio |
+|-----------|-------------|----------|
+| **P1** | CrΓtico | Bloquea el MVP, sin esto no funciona |
+| **P2** | Alto | Necesario para MVP, funcionalidad core |
+| **P3** | Medio | Deseable para MVP, mejora UX |
+| **P4** | Bajo | Post-MVP, mejoras futuras |
+
+---
+
+## Referencias
+
+- [DefiniciΓ³n de MΓ³dulos](../02-definicion-modulos/_INDEX.md)
+- [Arquitectura TΓ©cnica](../00-vision-general/ARQUITECTURA-TECNICA.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/docs/04-modelado/MODELO-DOMINIO.md b/projects/platform_marketing_content/docs/04-modelado/MODELO-DOMINIO.md
new file mode 100644
index 0000000..5cad5f7
--- /dev/null
+++ b/projects/platform_marketing_content/docs/04-modelado/MODELO-DOMINIO.md
@@ -0,0 +1,275 @@
+# Modelo de Dominio - Platform Marketing Content
+
+**VersiΓ³n:** 1.0.0
+**Fecha:** 2025-12-08
+
+---
+
+## Diagrama de Entidades
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β CORE ENTITIES β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ββββββββββββ ββββββββββββ ββββββββββββ β
+β β Tenant βββββββββββ Plan β β User β β
+β ββββββ¬ββββββ ββββββββββββ ββββββ¬ββββββ β
+β β β β
+β β 1:N β N:1 β
+β βΌ βΌ β
+β ββββββββββββ ββββββββββββ β
+β β Client β β Role β β
+β ββββββ¬ββββββ ββββββββββββ β
+β β β
+β β 1:N β
+β βΌ β
+β ββββββββββββ ββββββββββββ β
+β β Contact β β Brand βββββββββββ β
+β ββββββββββββ ββββββ¬ββββββ β β
+β β β N:N β
+β β 1:N β β
+β βΌ β β
+β ββββββββββββ ββββββ΄ββββββ β
+β β Product β βCustomModelβ β
+β ββββββββββββ ββββββββββββ β
+β β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β PROJECT ENTITIES β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ββββββββββββ β
+β β Project βββββββββββββββββββββ β
+β ββββββ¬ββββββ β β
+β β β N:1 (Client) β
+β β 1:N β β
+β βΌ β β
+β ββββββββββββ βββββββββββ΄β ββββββββββββ β
+β β Campaign βββββββββββOpportunityβ β BriefTpl β β
+β ββββββ¬ββββββ ββββββββββββ ββββββββββββ β
+β β β
+β β 1:N β
+β βΌ β
+β ββββββββββββββββ β
+β βCampaignAsset ββββββββββββ β
+β ββββββββββββββββ β N:1 β
+β βΌ β
+β ββββββββββββ β
+β β Asset β β
+β ββββββββββββ β
+β β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β GENERATION ENTITIES β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ββββββββββββββββββ ββββββββββββββββββ β
+β βGenerationJob βββββββββββββββββββββWorkflowTemplateβ β
+β βββββββββ¬βββββββββ ββββββββββββββββββ β
+β β β
+β β 1:N β
+β βΌ β
+β ββββββββββββββββββ ββββββββββββββββββ β
+β β Asset β β TextGeneration β β
+β βββββββββ¬βββββββββ ββββββββββββββββββ β
+β β β
+β β 1:N β
+β βΌ β
+β ββββββββββββββββββ ββββββββββββββββββ β
+β β AssetVersion β β AssetComment β β
+β ββββββββββββββββββ ββββββββββββββββββ β
+β β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β AUTOMATION ENTITIES β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ββββββββββββββββββ ββββββββββββββββββ β
+β βAutomationFlow βββββββββββββββββββββ AutomationRun β β
+β βββββββββ¬βββββββββ ββββββββββββββββββ β
+β β β
+β β N:1 β
+β βΌ β
+β ββββββββββββββββββ β
+β βWebhookEndpoint β β
+β ββββββββββββββββββ β
+β β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β SUPPORT ENTITIES β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β
+β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
+β βCollectionβ βInvitationβ β AuditLog β β Setting β β
+β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
+β β
+β ββββββββββββ ββββββββββββ ββββββββββββ β
+β β Download β β Metric β β Report β β
+β ββββββββββββ ββββββββββββ ββββββββββββ β
+β β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+---
+
+## Entidades por MΓ³dulo
+
+### PMC-001: Tenants
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **Tenant** | OrganizaciΓ³n que usa la plataforma | 1:N User, Client, Project, Asset |
+| **Plan** | Plan de suscripciΓ³n con lΓmites | 1:N Tenant |
+
+### PMC-002: CRM
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **Client** | Empresa cliente de la agencia | N:1 Tenant, 1:N Contact, Brand, Project |
+| **Contact** | Persona de contacto | N:1 Client |
+| **Brand** | Marca con identidad visual | N:1 Client, 1:N Product, Campaign |
+| **Product** | Producto o servicio | N:1 Brand |
+| **Opportunity** | Oportunidad comercial | N:1 Client, Contact |
+
+### PMC-003: Projects
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **Project** | Contenedor de campaΓ±as | N:1 Client, Tenant, 1:N Campaign |
+| **Campaign** | CampaΓ±a de marketing con brief | N:1 Project, Brand, 1:N CampaignAsset |
+| **CampaignAsset** | RelaciΓ³n campaΓ±a-asset con estado | N:1 Campaign, Asset |
+
+### PMC-004: Generation
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **GenerationJob** | Tarea de generaciΓ³n | N:1 Tenant, Campaign, WorkflowTemplate |
+| **WorkflowTemplate** | Plantilla de workflow ComfyUI | 1:N GenerationJob |
+| **CustomModel** | LoRA/Checkpoint personalizado | N:1 Tenant, Brand |
+| **TextGeneration** | GeneraciΓ³n de texto/copy | N:1 Tenant, GenerationJob |
+
+### PMC-005: Automation
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **AutomationFlow** | DefiniciΓ³n de flujo automatizado | N:1 Tenant, 1:N AutomationRun |
+| **AutomationRun** | EjecuciΓ³n de un flujo | N:1 AutomationFlow |
+| **WebhookEndpoint** | Endpoint para webhooks externos | N:1 Tenant, AutomationFlow |
+
+### PMC-006: Assets
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **Asset** | Recurso digital (imagen, video, etc.) | N:1 Tenant, GenerationJob |
+| **AssetVersion** | VersiΓ³n histΓ³rica de asset | N:1 Asset |
+| **Collection** | AgrupaciΓ³n de assets | N:1 Tenant, N:N Asset |
+| **AssetComment** | Comentario sobre asset | N:1 Asset, User |
+| **Download** | Registro de descarga | N:1 Asset, User |
+
+### PMC-007: Admin
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **User** | Usuario del sistema | N:1 Tenant, Role |
+| **Role** | Rol con permisos | 1:N User |
+| **Invitation** | InvitaciΓ³n pendiente | N:1 Tenant, Role |
+| **AuditLog** | Registro de auditorΓa | N:1 Tenant, User |
+| **Setting** | ConfiguraciΓ³n del sistema | N:1 Tenant (opcional) |
+
+### PMC-008: Analytics
+
+| Entidad | DescripciΓ³n | Relaciones Principales |
+|---------|-------------|------------------------|
+| **Metric** | Dato mΓ©trico agregado | N:1 Tenant |
+| **Report** | Reporte generado | N:1 Tenant, User |
+| **SavedView** | Vista personalizada guardada | N:1 Tenant, User |
+
+---
+
+## Matriz de Relaciones
+
+```
+ βTenβPlnβUsrβRolβCliβConβBraβProβOppβPrjβCamβCAsβJobβWflβModβTxtβFloβRunβWhkβAstβVerβColβComβDwnβInvβAudβSetβMetβRepβViwβ
+ββββββββββββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββΌββββ€
+Tenant β βN:1β1:Nβ β1:Nβ β β β β1:Nβ β β1:Nβ β1:Nβ β1:Nβ β1:Nβ1:Nβ β1:Nβ β β1:Nβ1:Nβ1:Nβ1:Nβ1:Nβ1:Nβ
+Plan β1:Nβ β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+User βN:1β β βN:1β β β β β β1:Nβ β β1:Nβ β β β β β β1:Nβ β β1:Nβ1:Nβ β1:Nβ β β1:Nβ1:Nβ
+Role β β β1:Nβ β β β β β β β β β β β β β β β β β β β β β1:Nβ β β β β β
+Client βN:1β β β β β1:Nβ1:Nβ β1:Nβ1:Nβ β β β β β β β β β β β β β β β β β β β β
+Contact β β β β βN:1β β β βN:1β β β β β β β β β β β β β β β β β β β β β β
+Brand β β β β βN:1β β β1:Nβ β β1:Nβ β β βN:Nβ β β β β β β β β β β β β β β β
+Product β β β β β β βN:1β β β β β βN:1β βN:1β β β β β β β β β β β β β β β β
+Opportunity β β β β βN:1βN:1β β β β β β β β β β β β β β β β β β β β β β β β β
+Project βN:1β βN:1β βN:1β β β β β β1:Nβ β β β β β β β β β β β β β β β β β β β
+Campaign β β β β β β βN:1β β βN:1β β1:NβN:1β β β β β β β β β β β β β β β β β β
+CampaignAssetβ β β β β β β β β β βN:1β β β β β β β β βN:1β β β β β β β β β β β
+GenJob βN:1β βN:1β β β β βN:1β β βN:1β β βN:1β β1:Nβ β β β1:Nβ β β β β β β β β β β
+Workflow β β β β β β β β β β β β β1:Nβ β β β β β β β β β β β β β β β β β
+CustomModel βN:1β β β β β βN:Nβ β β β β β β β β β β β β β β β β β β β β β β β
+TextGen βN:1β β β β β β β β β βN:1β βN:1β β β β β β β β β β β β β β β β β β
+AutoFlow βN:1β β β β β β β β β β β β β β β β β1:Nβ1:Nβ β β β β β β β β β β β
+AutoRun βN:1β β β β β β β β β β β β β β β βN:1β β β β β β β β β β β β β β
+Webhook βN:1β β β β β β β β β β β β β β β βN:1β β β β β β β β β β β β β β
+Asset βN:1β βN:1β β β β β β β β βN:1βN:1β β β β β β β β1:NβN:Nβ1:Nβ1:Nβ β β β β β β
+AssetVer β β βN:1β β β β β β β β β β β β β β β β βN:1β β β β β β β β β β β
+Collection βN:1β βN:1β β β β β β β β β β β β β β β β βN:Nβ β β β β β β β β β β
+AssetComment β β βN:1β β β β β β β β β β β β β β β β βN:1β β β1:Nβ β β β β β β β
+Download βN:1β βN:1β β β β β β β β β β β β β β β β βN:1β βN:1β β β β β β β β β
+Invitation βN:1β βN:1βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β
+AuditLog βN:1β βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+Setting βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+Metric βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+Report βN:1β βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+SavedView βN:1β βN:1β β β β β β β β β β β β β β β β β β β β β β β β β β β β
+```
+
+---
+
+## Agregados (DDD)
+
+### Aggregate: Tenant
+- **Root:** Tenant
+- **Entities:** Plan (referencia)
+- **Value Objects:** Settings, Branding, Limits
+
+### Aggregate: Client
+- **Root:** Client
+- **Entities:** Contact, Brand, Product
+- **Value Objects:** Identity (en Brand)
+
+### Aggregate: Project
+- **Root:** Project
+- **Entities:** Campaign, CampaignAsset
+- **Value Objects:** Brief (en Campaign)
+
+### Aggregate: Asset
+- **Root:** Asset
+- **Entities:** AssetVersion, AssetComment
+- **Value Objects:** Metadata, Dimensions
+
+### Aggregate: GenerationJob
+- **Root:** GenerationJob
+- **Entities:** (outputs referenciados)
+- **Value Objects:** InputParams, Progress
+
+### Aggregate: User
+- **Root:** User
+- **Entities:** (Role como referencia)
+- **Value Objects:** Preferences
+
+---
+
+## Referencias
+
+- [ARQUITECTURA-TECNICA.md](../00-vision-general/ARQUITECTURA-TECNICA.md)
+- [DefiniciΓ³n de MΓ³dulos](../02-definicion-modulos/_INDEX.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/orchestration/00-guidelines/CONTEXTO-PROYECTO.md b/projects/platform_marketing_content/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
new file mode 100644
index 0000000..a308700
--- /dev/null
+++ b/projects/platform_marketing_content/orchestration/00-guidelines/CONTEXTO-PROYECTO.md
@@ -0,0 +1,188 @@
+# Contexto de Proyecto: Platform Marketing Content
+
+**Versiθ΄Έn:** 1.0.0
+**Fecha:** 2025-12-08
+**Nivel SIMCO:** NIVEL_2B (Proyecto independiente)
+
+---
+
+## Identificaciθ΄Έn del Proyecto
+
+```yaml
+Proyecto: platform_marketing_content
+Alias: PMC
+Tipo: SaaS Platform
+Dominio: Marketing Digital / Generaciθ΄Έn de Contenido IA
+Estado: Anθ°©lisis y Documentaciθ΄Έn
+```
+
+---
+
+## Descripciθ΄Έn
+
+**Platform Marketing Content (PMC)** es una plataforma SaaS para agencias de publicidad que combina:
+
+1. **Motor de Generaciθ΄Έn de Contenido con IA** - Imθ°©genes y copys automθ°©ticos
+2. **CRM Integrado** - Gestiθ΄Έn de clientes, marcas y campaεΈ½as
+3. **Automatizaciθ΄Έn Creativa** - Flujos desde brief hasta entrega
+4. **DAM** - Biblioteca de activos digitales
+
+---
+
+## Stack Tecnolθ΄Έgico
+
+```yaml
+Backend:
+ - NestJS + TypeScript
+ - PostgreSQL 15+
+ - Redis
+ - Bull/BullMQ
+
+Frontend:
+ - React 18 + Vite
+ - TailwindCSS
+ - Shadcn/UI
+
+Motor IA:
+ - ComfyUI
+ - Stable Diffusion XL
+ - ComfyDeploy
+
+Automatizaciθ΄Έn:
+ - n8n
+
+Almacenamiento:
+ - S3/MinIO
+```
+
+---
+
+## Estructura de Documentaciθ΄Έn
+
+```
+projects/platform_marketing_content/
+ιζΊζ’ι? docs/
+ι? ιζΊζ’ι? 00-vision-general/ # Visiθ΄Έn, arquitectura, glosario
+ι? ιζΊζ’ι? 01-analisis-referencias/ # Investigaciθ΄Έn, benchmarks
+ι? ιζΊζ’ι? 02-definicion-modulos/ # Especificaciones por mθ΄Έdulo
+ι? ιζΊζ’ι? 03-requerimientos/ # Requerimientos funcionales
+ι? ιζΊζ’ι? 04-modelado/ # Modelos de dominio, DB design
+ι? ιζΊζ’ι? 05-user-stories/ # Historias de usuario
+ι? ιζΊζ’ι? 95-guias-desarrollo/ # Guιas y convenciones
+ι? ιζΊζ’ι? 97-adr/ # Decisiones arquitectθ΄Έnicas
+ι?
+ιζΊζ’ι? orchestration/
+ι? ιζΊζ’ι? 00-guidelines/ # Contexto, herencias
+ι? ιζΊζ’ι? inventarios/ # Inventarios de implementaciθ΄Έn
+ι? ιζΊζ’ι? trazas/ # Trazas de tareas
+ι?
+ιζΊζ’ι? apps/
+ ιζΊζ’ι? backend/ # Cθ΄Έdigo NestJS
+ ιζΊζ’ι? frontend/ # Cθ΄Έdigo React
+ ιζΊζ’ι? comfyui/ # Workflows ComfyUI
+```
+
+---
+
+## Mθ΄Έdulos Funcionales
+
+| ID | Mθ΄Έdulo | Descripciθ΄Έn | Prioridad |
+|----|--------|-------------|-----------|
+| PMC-001 | Tenants | Arquitectura multi-tenant | Alta |
+| PMC-002 | CRM | Clientes, marcas, productos | Alta |
+| PMC-003 | Projects | Proyectos y campaεΈ½as | Alta |
+| PMC-004 | Generation | Motor de generaciθ΄Έn IA | Alta |
+| PMC-005 | Automation | Flujos automatizados | Media |
+| PMC-006 | Assets | DAM - biblioteca de activos | Alta |
+| PMC-007 | Admin | Administraciθ΄Έn SaaS | Media |
+| PMC-008 | Analytics | Reportes y dashboards | Baja |
+
+---
+
+## Aliases del Proyecto
+
+```yaml
+# Documentaciθ΄Έn
+@PMC_DOCS: projects/platform_marketing_content/docs/
+@PMC_VISION: projects/platform_marketing_content/docs/00-vision-general/
+@PMC_MODULES: projects/platform_marketing_content/docs/02-definicion-modulos/
+@PMC_REQS: projects/platform_marketing_content/docs/03-requerimientos/
+@PMC_ADR: projects/platform_marketing_content/docs/97-adr/
+
+# Orchestration
+@PMC_ORCH: projects/platform_marketing_content/orchestration/
+@PMC_INVENTORY: projects/platform_marketing_content/orchestration/inventarios/
+@PMC_TRAZA: projects/platform_marketing_content/orchestration/trazas/
+
+# Cθ΄Έdigo
+@PMC_BACKEND: projects/platform_marketing_content/apps/backend/
+@PMC_FRONTEND: projects/platform_marketing_content/apps/frontend/
+```
+
+---
+
+## Dependencias del Catθ°©logo Core
+
+Funcionalidades reutilizables del catθ°©logo:
+
+```yaml
+Requeridas:
+ - @CATALOG_AUTH: Autenticaciθ΄Έn JWT + OAuth
+ - @CATALOG_SESSION: Gestiθ΄Έn de sesiones
+ - @CATALOG_TENANT: Multi-tenancy (adaptar)
+ - @CATALOG_NOTIFY: Notificaciones
+
+Opcionales:
+ - @CATALOG_RATELIMIT: Rate limiting
+ - @CATALOG_FLAGS: Feature flags
+```
+
+---
+
+## Roadmap de Fases
+
+```yaml
+Fase 1 - MVP Core (Semanas 1-8):
+ - Arquitectura base
+ - CRM bθ°©sico
+ - Motor de generaciθ΄Έn (2-3 workflows)
+ - DAM bθ°©sico
+ - Admin usuarios
+
+Fase 2 - Personalizaciθ΄Έn (Semanas 9-14):
+ - LoRAs por marca
+ - Avatares consistentes
+ - Integraciθ΄Έn CRMι«ζeneraciθ΄Έn
+
+Fase 3 - Contenido Enriquecido (Semanas 15-22):
+ - GIFs/cinemagraphs
+ - Video bθ°©sico
+ - Portal cliente
+
+Fase 4 - Multi-tenant Comercial (Semanas 23+):
+ - SaaS pη
€blico
+ - Planes de suscripciθ΄Έn
+```
+
+---
+
+## Contactos y Responsables
+
+```yaml
+Product Owner: [Por definir]
+Tech Lead: [Por definir]
+Requirements Analyst: Agente IA
+```
+
+---
+
+## Referencias
+
+- [VISION-GENERAL.md](../../docs/00-vision-general/VISION-GENERAL.md)
+- [ARQUITECTURA-TECNICA.md](../../docs/00-vision-general/ARQUITECTURA-TECNICA.md)
+- [GLOSARIO.md](../../docs/00-vision-general/GLOSARIO.md)
+
+---
+
+**Documento generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/orchestration/PROXIMA-ACCION.md b/projects/platform_marketing_content/orchestration/PROXIMA-ACCION.md
new file mode 100644
index 0000000..1deab0c
--- /dev/null
+++ b/projects/platform_marketing_content/orchestration/PROXIMA-ACCION.md
@@ -0,0 +1,161 @@
+# PrΓ³xima AcciΓ³n - Platform Marketing Content
+
+**Fecha:** 2025-12-08
+**Estado Actual:** DocumentaciΓ³n Completada
+
+---
+
+## Resumen de Progreso
+
+### Completado
+
+- [x] VisiΓ³n general del proyecto consolidada
+- [x] Glosario de tΓ©rminos del dominio
+- [x] Arquitectura tΓ©cnica detallada
+- [x] DefiniciΓ³n de 8 mΓ³dulos funcionales
+- [x] Contexto de proyecto para orchestration
+- [x] Inventario maestro (MASTER_INVENTORY.yml)
+
+### Estructura de DocumentaciΓ³n Creada
+
+```
+projects/platform_marketing_content/
+βββ docs/
+β βββ 00-vision-general/
+β β βββ VISION-GENERAL.md β
+β β βββ ARQUITECTURA-TECNICA.md β
+β β βββ GLOSARIO.md β
+β β βββ MVP_Plataforma_SaaS...md (original)
+β βββ 01-analisis-referencias/ (vacΓo)
+β βββ 02-definicion-modulos/
+β β βββ _INDEX.md β
+β β βββ PMC-001-TENANTS.md β
+β β βββ PMC-002-CRM.md β
+β β βββ PMC-003-PROJECTS.md β
+β β βββ PMC-004-GENERATION.md β
+β β βββ PMC-005-AUTOMATION.md β
+β β βββ PMC-006-ASSETS.md β
+β β βββ PMC-007-ADMIN.md β
+β β βββ PMC-008-ANALYTICS.md β
+β βββ 03-requerimientos/ (pendiente)
+β βββ 04-modelado/ (pendiente)
+β βββ 05-user-stories/ (pendiente)
+β βββ 95-guias-desarrollo/ (pendiente)
+β βββ 97-adr/ (pendiente)
+β
+βββ orchestration/
+ βββ 00-guidelines/
+ β βββ CONTEXTO-PROYECTO.md β
+ βββ inventarios/
+ β βββ MASTER_INVENTORY.yml β
+ βββ trazas/ (vacΓo)
+```
+
+---
+
+## PrΓ³ximas Acciones Sugeridas
+
+### OpciΓ³n A: Continuar DocumentaciΓ³n (Requirements-Analyst)
+
+```yaml
+Prioridad: Alta
+Agente: Requirements-Analyst
+Tareas:
+ 1. Crear requerimientos funcionales detallados:
+ - docs/03-requerimientos/RF-PMC-001-TENANTS.md
+ - docs/03-requerimientos/RF-PMC-002-CRM.md
+ - ... (por cada mΓ³dulo)
+
+ 2. Crear modelo de datos consolidado:
+ - docs/04-modelado/MODELO-DOMINIO.md
+ - docs/04-modelado/ESQUEMA-BD.md
+
+ 3. Crear user stories para MVP:
+ - docs/05-user-stories/EPIC-001-SETUP.md
+ - docs/05-user-stories/EPIC-002-CRM.md
+ - ...
+
+EstimaciΓ³n: 4-6 horas de trabajo de agente
+```
+
+### OpciΓ³n B: Iniciar ImplementaciΓ³n (Feature-Developer)
+
+```yaml
+Prioridad: Alta
+Agente: Feature-Developer
+Prerequisitos:
+ - DocumentaciΓ³n actual es suficiente para MVP
+ - Usar docs/02-definicion-modulos/* como referencia
+
+Tareas:
+ 1. Setup del proyecto backend:
+ - Crear proyecto NestJS
+ - Configurar TypeORM + PostgreSQL
+ - Implementar estructura de mΓ³dulos
+
+ 2. Implementar PMC-001-TENANTS:
+ - Entidades: Tenant, Plan
+ - RLS para multi-tenancy
+ - Endpoints bΓ‘sicos
+
+ 3. Implementar PMC-007-ADMIN (parcial):
+ - User, Role, permisos
+ - AutenticaciΓ³n JWT
+
+EstimaciΓ³n: 16-24 horas para setup + 2 mΓ³dulos base
+```
+
+### OpciΓ³n C: Revisar y Validar (Documentation-Validator)
+
+```yaml
+Prioridad: Media
+Agente: Documentation-Validator
+Tareas:
+ 1. Validar consistencia entre documentos
+ 2. Verificar que todas las entidades estΓ©n definidas
+ 3. Revisar endpoints duplicados o faltantes
+ 4. Generar checklist de validaciΓ³n
+
+EstimaciΓ³n: 2-3 horas
+```
+
+---
+
+## RecomendaciΓ³n
+
+Para avanzar de manera eficiente, se sugiere:
+
+1. **Si se quiere documentaciΓ³n exhaustiva**: Continuar con OpciΓ³n A
+2. **Si se quiere iniciar desarrollo pronto**: Ir con OpciΓ³n B usando la documentaciΓ³n actual
+3. **Enfoque hΓbrido**: Ejecutar OpciΓ³n B mientras otro agente avanza en OpciΓ³n A
+
+La documentaciΓ³n actual (8 mΓ³dulos definidos con entidades, funcionalidades, APIs) es suficiente para comenzar implementaciΓ³n del MVP.
+
+---
+
+## Comandos de ActivaciΓ³n
+
+```bash
+# Para continuar documentaciΓ³n
+@Requirements-Analyst continuar con requerimientos funcionales para PMC
+
+# Para iniciar implementaciΓ³n
+@Feature-Developer setup proyecto backend PMC con mΓ³dulos Tenants y Admin
+
+# Para validaciΓ³n
+@Documentation-Validator validar documentaciΓ³n de PMC
+```
+
+---
+
+## Notas Adicionales
+
+- El proyecto usa stack NestJS + React + ComfyUI
+- Priorizar mΓ³dulos: PMC-001, PMC-007, PMC-002, PMC-006 (en ese orden)
+- La integraciΓ³n con ComfyUI (PMC-004) requiere servidor GPU configurado
+- n8n (PMC-005) puede ejecutarse en contenedor Docker local
+
+---
+
+**Generado por:** Requirements-Analyst
+**Fecha:** 2025-12-08
diff --git a/projects/platform_marketing_content/orchestration/inventarios/MASTER_INVENTORY.yml b/projects/platform_marketing_content/orchestration/inventarios/MASTER_INVENTORY.yml
new file mode 100644
index 0000000..cfdeb31
--- /dev/null
+++ b/projects/platform_marketing_content/orchestration/inventarios/MASTER_INVENTORY.yml
@@ -0,0 +1,339 @@
+# MASTER_INVENTORY.yml - Platform Marketing Content
+# Inventario maestro de implementaciΓ³n
+# VersiΓ³n: 1.0.0
+# Fecha: 2025-12-08
+
+project:
+ name: Platform Marketing Content
+ alias: PMC
+ nivel_simco: NIVEL_2B
+ status: documentacion
+
+# =============================================================================
+# MΓDULOS
+# =============================================================================
+modules:
+ PMC-001-TENANTS:
+ name: Tenants
+ priority: alta
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-001-TENANTS.md
+ dependencies:
+ catalog:
+ - "@CATALOG_TENANT"
+ entities:
+ - Tenant
+ - Plan
+ endpoints_count: 8
+ features_count: 10
+
+ PMC-002-CRM:
+ name: CRM
+ priority: alta
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-002-CRM.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-003-PROJECTS
+ - PMC-004-GENERATION
+ - PMC-006-ASSETS
+ entities:
+ - Client
+ - Contact
+ - Brand
+ - Product
+ - Opportunity
+ endpoints_count: 25
+ features_count: 18
+
+ PMC-003-PROJECTS:
+ name: Projects
+ priority: alta
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-003-PROJECTS.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-002-CRM
+ - PMC-004-GENERATION
+ - PMC-006-ASSETS
+ entities:
+ - Project
+ - Campaign
+ - CampaignAsset
+ endpoints_count: 20
+ features_count: 16
+
+ PMC-004-GENERATION:
+ name: Generation (Motor IA)
+ priority: alta
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-004-GENERATION.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-002-CRM
+ - PMC-003-PROJECTS
+ - PMC-006-ASSETS
+ catalog:
+ - "@CATALOG_RATELIMIT"
+ external:
+ - ComfyUI
+ - OpenAI/Claude API
+ - Redis
+ - S3/MinIO
+ entities:
+ - GenerationJob
+ - WorkflowTemplate
+ - CustomModel
+ - TextGeneration
+ endpoints_count: 18
+ features_count: 20
+ workflows_predefinidos:
+ - product_photo_synthetic
+ - social_media_post
+ - ad_variations
+ - virtual_avatar
+
+ PMC-005-AUTOMATION:
+ name: Automation
+ priority: media
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-005-AUTOMATION.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-002-CRM
+ - PMC-003-PROJECTS
+ - PMC-004-GENERATION
+ - PMC-006-ASSETS
+ external:
+ - n8n
+ - SMTP/SendGrid
+ entities:
+ - AutomationFlow
+ - AutomationRun
+ - WebhookEndpoint
+ endpoints_count: 15
+ features_count: 12
+ flows_predefinidos:
+ - product_asset_kit
+ - campaign_initial_batch
+ - campaign_delivery_prep
+ - job_failure_handler
+
+ PMC-006-ASSETS:
+ name: Assets (DAM)
+ priority: alta
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-006-ASSETS.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-003-PROJECTS
+ - PMC-004-GENERATION
+ external:
+ - S3/MinIO
+ - Sharp
+ entities:
+ - Asset
+ - AssetVersion
+ - Collection
+ - AssetComment
+ - Download
+ endpoints_count: 25
+ features_count: 18
+
+ PMC-007-ADMIN:
+ name: Admin
+ priority: media
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-007-ADMIN.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ catalog:
+ - "@CATALOG_AUTH"
+ - "@CATALOG_SESSION"
+ entities:
+ - User
+ - Role
+ - Invitation
+ - AuditLog
+ - Setting
+ endpoints_count: 20
+ features_count: 14
+ roles_sistema:
+ - super_admin
+ - tenant_admin
+ - creative
+ - analyst
+ - viewer
+ - client_portal
+
+ PMC-008-ANALYTICS:
+ name: Analytics
+ priority: baja
+ status: definido
+ doc_path: docs/02-definicion-modulos/PMC-008-ANALYTICS.md
+ dependencies:
+ modules:
+ - PMC-001-TENANTS
+ - PMC-003-PROJECTS
+ - PMC-004-GENERATION
+ - PMC-006-ASSETS
+ external:
+ - Redis
+ entities:
+ - Metric
+ - Report
+ - SavedView
+ endpoints_count: 12
+ features_count: 10
+ dashboards:
+ - home
+ - production
+ - campaigns
+ - resources
+
+# =============================================================================
+# STACK TECNOLΓGICO
+# =============================================================================
+tech_stack:
+ backend:
+ framework: NestJS
+ language: TypeScript
+ database: PostgreSQL 15+
+ cache: Redis
+ queue: Bull/BullMQ
+ orm: TypeORM
+
+ frontend:
+ framework: React 18
+ bundler: Vite
+ styling: TailwindCSS
+ components: Shadcn/UI
+ state: Zustand o React Query
+
+ ia_engine:
+ image_generation: ComfyUI + SDXL
+ text_generation: OpenAI API / Claude API
+ deployment: ComfyDeploy
+
+ automation:
+ orchestrator: n8n
+
+ storage:
+ files: S3/MinIO
+
+ infrastructure:
+ containers: Docker + Docker Compose
+ gpu: NVIDIA (12-24GB VRAM)
+
+# =============================================================================
+# CATΓLOGO DE DEPENDENCIAS
+# =============================================================================
+catalog_dependencies:
+ required:
+ - id: "@CATALOG_AUTH"
+ description: AutenticaciΓ³n JWT + OAuth
+ module: PMC-007-ADMIN
+
+ - id: "@CATALOG_SESSION"
+ description: GestiΓ³n de sesiones
+ module: PMC-007-ADMIN
+
+ - id: "@CATALOG_TENANT"
+ description: Multi-tenancy (adaptar)
+ module: PMC-001-TENANTS
+
+ optional:
+ - id: "@CATALOG_RATELIMIT"
+ description: Rate limiting
+ module: PMC-004-GENERATION
+
+ - id: "@CATALOG_NOTIFY"
+ description: Notificaciones
+ module: PMC-005-AUTOMATION
+
+# =============================================================================
+# FASES DE IMPLEMENTACIΓN
+# =============================================================================
+roadmap:
+ fase_1_mvp_core:
+ duration: "Semanas 1-8"
+ modules:
+ - PMC-001-TENANTS
+ - PMC-007-ADMIN
+ - PMC-002-CRM
+ - PMC-006-ASSETS
+ - PMC-003-PROJECTS
+ - PMC-004-GENERATION
+ deliverables:
+ - Arquitectura base multi-tenant
+ - AutenticaciΓ³n y usuarios
+ - CRM bΓ‘sico (clientes, marcas, productos)
+ - DAM bΓ‘sico
+ - CampaΓ±as con brief
+ - Motor de generaciΓ³n (2-3 workflows)
+
+ fase_2_personalizacion:
+ duration: "Semanas 9-14"
+ modules:
+ - PMC-004-GENERATION (ampliaciΓ³n)
+ - PMC-005-AUTOMATION
+ deliverables:
+ - Entrenamiento de LoRAs
+ - Avatares consistentes
+ - Flujos automatizados CRM β Generation
+
+ fase_3_contenido_enriquecido:
+ duration: "Semanas 15-22"
+ modules:
+ - PMC-004-GENERATION (video)
+ - PMC-008-ANALYTICS
+ deliverables:
+ - GIFs/cinemagraphs
+ - Video bΓ‘sico
+ - Dashboards y reportes
+ - Portal cliente
+
+ fase_4_saas_comercial:
+ duration: "Semanas 23+"
+ modules:
+ - PMC-001-TENANTS (planes)
+ - PMC-007-ADMIN (billing)
+ deliverables:
+ - SaaS pΓΊblico
+ - Planes de suscripciΓ³n
+ - Onboarding automΓ‘tico
+
+# =============================================================================
+# MΓTRICAS
+# =============================================================================
+metrics:
+ total_modules: 8
+ total_entities: 28
+ total_endpoints: ~143
+ total_features: 118
+ features_priority:
+ alta: 64
+ media: 41
+ baja: 13
+ documentation_status:
+ vision_general: completado
+ glosario: completado
+ arquitectura: completado
+ modulos: completado
+ requerimientos: pendiente
+ user_stories: pendiente
+
+# =============================================================================
+# METADATOS
+# =============================================================================
+metadata:
+ created_by: Requirements-Analyst
+ created_at: "2025-12-08"
+ last_updated: "2025-12-08"
+ version: "1.0.0"