---
id: "ARQUITECTURA-TECNICA"
title: "Arquitectura T茅cnica - Platform Marketing Content"
type: "Architecture"
status: "Active"
project: "platform_marketing_content"
version: "1.0.0"
created_date: "2026-01-04"
updated_date: "2026-01-04"
---
# 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<string> {
    // 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<Buffer> {
    // 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
