# Analisis de Requerimientos SaaS Transversales - ERP Suite

**Version:** 1.0.0
**Fecha:** 2025-12-05
**Autor:** Requirements-Analyst
**Estado:** Draft - Pendiente Aprobacion

---

## Resumen Ejecutivo

Este documento analiza los nuevos requerimientos transversales que impactan a todo el ERP Suite y sus verticales. Los requerimientos incluyen:

1. **Modelo SaaS completo** con usuario cliente administrador
2. **Suscripciones por usuario** con Stripe
3. **Apps moviles** por perfil de usuario
4. **Integracion WhatsApp Business** con agente IA
5. **Onboarding y configuracion inicial** ($10,000 - $100,000 MXN)
6. **Control y facturacion de tokens IA**

---

## 1. Modelo de Negocio SaaS

### 1.1 Estructura de Tenants

```
+------------------------------------------+
|            PLATAFORMA ERP SUITE          |
+------------------------------------------+
          |
          v
+------------------------------------------+
|      TENANT (Cliente Empresa)            |
|  +------------------------------------+  |
|  | Owner (Usuario Administrador)      |  |
|  | - Gestiona usuarios               |  |
|  | - Gestiona suscripcion            |  |
|  | - Gestiona metodos de pago        |  |
|  | - Configura integraciones         |  |
|  +------------------------------------+  |
|           |                              |
|           v                              |
|  +------------------------------------+  |
|  | Usuarios del Tenant               |  |
|  | - Roles asignados por Owner       |  |
|  | - Permisos segun rol              |  |
|  | - Acceso a app segun perfil       |  |
|  +------------------------------------+  |
+------------------------------------------+
```

### 1.2 Flujo de Adquisicion de Cliente

```
1. CONTRATACION INICIAL
   └── Levantamiento de requerimientos
   └── Analisis de necesidades
   └── Cotizacion de implementacion ($10K - $100K MXN)
   └── Configuracion e integracion
   └── Capacitacion

2. ONBOARDING
   └── Creacion de tenant
   └── Configuracion inicial
   └── Migracion de datos (opcional)
   └── Pruebas de aceptacion

3. OPERACION CONTINUA
   └── Suscripcion mensual por usuario
   └── Cobro de tokens IA por uso
   └── Soporte y mantenimiento
```

### 1.3 Modelo de Precios Actualizado

#### Suscripcion por Usuario (Mensual)

| Vertical | Precio Base/Usuario | Usuarios Min | Descuento Volumen |
|----------|---------------------|--------------|-------------------|
| Construccion | $25 USD/usuario | 5 | >20: 15%, >50: 25% |
| Vidrio Templado | $20 USD/usuario | 3 | >10: 10%, >30: 20% |
| Mecanicas Diesel | $15 USD/usuario | 2 | >10: 10% |
| Retail | $12 USD/usuario | 1 | >20: 15% |
| Clinicas | $30 USD/usuario | 3 | >10: 10% |

#### Cargo por Implementacion (Unico)

| Nivel | Rango MXN | Incluye |
|-------|-----------|---------|
| Basico | $10,000 - $25,000 | Config estandar, 1 capacitacion, datos muestra |
| Medio | $25,000 - $50,000 | Config personalizada, migracion basica, 3 capacitaciones |
| Avanzado | $50,000 - $75,000 | Config avanzada, migracion completa, integraciones |
| Enterprise | $75,000 - $100,000+ | Todo lo anterior + desarrollo custom, SLA premium |

#### Tokens IA (Pago por Uso)

| Tipo | Precio por 1K tokens | Uso tipico |
|------|---------------------|------------|
| Input tokens | $0.003 USD | Prompts de usuario |
| Output tokens | $0.015 USD | Respuestas del agente |
| Embeddings | $0.0001 USD | Busqueda semantica |

---

## 2. Arquitectura de Suscripciones con Stripe

### 2.1 Integracion Stripe

**Razon de Stripe sobre MercadoPago:**
- API mas robusta para suscripciones
- Mejor soporte para prorratas
- Webhooks mas confiables
- Soporte para multiple moneda
- Facturacion automatizada

### 2.2 Modelo de Datos Extendido

```sql
-- Extensiones al schema billing existente

-- Tabla: stripe_customers
CREATE TABLE billing.stripe_customers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL UNIQUE REFERENCES core_tenants.tenants(id),
    stripe_customer_id VARCHAR(50) NOT NULL UNIQUE,
    stripe_subscription_id VARCHAR(50),
    stripe_price_id VARCHAR(50),

    -- Metadatos sincronizados
    email VARCHAR(200),
    default_payment_method VARCHAR(50),

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Tabla: stripe_webhook_events
CREATE TABLE billing.stripe_webhook_events (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    stripe_event_id VARCHAR(50) NOT NULL UNIQUE,
    event_type VARCHAR(100) NOT NULL,
    tenant_id UUID REFERENCES core_tenants.tenants(id),
    payload JSONB NOT NULL,
    processed BOOLEAN DEFAULT false,
    processed_at TIMESTAMPTZ,
    error_message TEXT,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

-- Tabla: implementation_projects
CREATE TABLE billing.implementation_projects (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES core_tenants.tenants(id),

    -- Cotizacion
    quote_number VARCHAR(20) NOT NULL UNIQUE,
    quote_amount DECIMAL(10,2) NOT NULL,
    quote_currency VARCHAR(3) DEFAULT 'MXN',
    quote_status VARCHAR(20) DEFAULT 'draft',

    -- Detalles
    requirements_summary TEXT,
    scope_document_url VARCHAR(500),

    -- Pagos (pueden ser parciales)
    amount_paid DECIMAL(10,2) DEFAULT 0,

    -- Fechas
    quoted_at TIMESTAMPTZ,
    accepted_at TIMESTAMPTZ,
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,

    created_by UUID,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT chk_quote_status CHECK (quote_status IN (
        'draft', 'sent', 'accepted', 'in_progress', 'completed', 'cancelled'
    ))
);

-- Tabla: implementation_payments
CREATE TABLE billing.implementation_payments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID NOT NULL REFERENCES billing.implementation_projects(id),

    description VARCHAR(200) NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    payment_type VARCHAR(20) NOT NULL, -- deposit, milestone, final

    stripe_payment_intent_id VARCHAR(50),
    status VARCHAR(20) DEFAULT 'pending',

    paid_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT chk_payment_type CHECK (payment_type IN ('deposit', 'milestone', 'final'))
);
```

### 2.3 Flujo de Suscripcion con Stripe

```
ALTA DE CLIENTE
     |
     v
[1. Crear Customer en Stripe]
     |
     v
[2. Guardar stripe_customer_id]
     |
     v
[3. Crear Payment Method (tarjeta)]
     |
     v
[4. Crear Subscription]
     |
     └── price_id: segun plan/vertical
     └── quantity: numero de usuarios
     └── billing_cycle_anchor: dia de facturacion
     |
     v
[5. Webhook: invoice.payment_succeeded]
     |
     v
[6. Activar tenant]

CAMBIO DE USUARIOS
     |
     v
[Stripe API: Update subscription quantity]
     |
     └── proration: create_prorations
     |
     v
[Webhook: invoice.created (prorata)]
     |
     v
[Cobro automatico]

CANCELACION
     |
     v
[Stripe API: Cancel subscription at_period_end]
     |
     v
[Webhook: customer.subscription.deleted]
     |
     v
[Desactivar tenant al final del periodo]
```

---

## 3. Arquitectura de Apps Moviles por Perfil

### 3.1 Matriz de Apps por Vertical

| Vertical | App | Perfiles | Funciones Principales |
|----------|-----|----------|----------------------|
| **Construccion** | App Encargado Obra | Residente, Supervisor | Check in/out biometrico, avances, fotos, materiales |
| | App Almacen | Almacenista | Entradas, salidas, inventario, requisiciones |
| | App Derechohabiente | Cliente final | Estado vivienda, citas, documentos |
| **Vidrio Templado** | App Produccion | Operador | Ordenes, calidad, escaneo |
| | App Instalador | Instalador | Asignaciones, fotos, firmas |
| **Mecanicas Diesel** | App Tecnico | Mecanico | Ordenes servicio, diagnosticos, refacciones |
| **Retail** | App Vendedor | Vendedor | POS movil, inventario, clientes |
| **Clinicas** | App Doctor | Medico | Citas, expedientes, recetas |
| | App Paciente | Paciente | Citas, resultados, mensajes |

### 3.2 Arquitectura Tecnica de Apps

```
+--------------------------------------------------+
|              MONOREPO APPS MOVILES               |
+--------------------------------------------------+
|  packages/                                        |
|  ├── core/                    # Logica compartida |
|  │   ├── auth/               # Autenticacion      |
|  │   ├── api/                # Cliente API        |
|  │   ├── storage/            # Almacenamiento     |
|  │   ├── biometrics/         # Facial/Huella      |
|  │   ├── camera/             # Camara/Fotos       |
|  │   ├── location/           # GPS                |
|  │   └── sync/               # Sincronizacion     |
|  │                                                |
|  ├── ui/                     # Componentes UI     |
|  │   ├── components/                              |
|  │   ├── theme/                                   |
|  │   └── navigation/                              |
|  │                                                |
|  apps/                                            |
|  ├── construccion-encargado/  # App Encargado    |
|  ├── construccion-almacen/    # App Almacen      |
|  ├── construccion-cliente/    # App Cliente      |
|  ├── vidrio-produccion/       # App Produccion   |
|  ├── mecanicas-tecnico/       # App Tecnico      |
|  ├── retail-vendedor/         # App Vendedor     |
|  └── clinicas-doctor/         # App Doctor       |
+--------------------------------------------------+
```

### 3.3 Funcionalidades Biometricas

#### Reconocimiento Facial

```typescript
interface FacialRecognitionConfig {
  provider: 'aws-rekognition' | 'azure-face' | 'local-ml';
  livenessDetection: boolean;  // Detectar que es persona real
  matchThreshold: number;       // 0.80 - 0.95
  maxAttempts: number;          // Intentos antes de bloquear
}

interface AttendanceRecord {
  userId: string;
  tenantId: string;
  projectId?: string;          // Para construccion
  type: 'check_in' | 'check_out';
  method: 'facial' | 'fingerprint' | 'manual';
  confidence: number;           // Score de match
  location: {
    latitude: number;
    longitude: number;
    accuracy: number;
  };
  photoUrl?: string;            // Foto del check
  deviceId: string;
  timestamp: Date;
}
```

#### Huella Dactilar

```typescript
interface FingerprintConfig {
  provider: 'device-native' | 'external-scanner';
  fallbackToPin: boolean;
  templateStorage: 'local' | 'server';
}
```

### 3.4 Modo Offline

```typescript
interface OfflineCapabilities {
  // Datos pre-cargados
  projectData: boolean;          // Datos del proyecto
  productCatalog: boolean;       // Catalogo de productos
  employeeList: boolean;         // Lista de empleados

  // Operaciones offline
  createRecords: boolean;        // Crear registros
  updateRecords: boolean;        // Actualizar registros
  capturePhotos: boolean;        // Capturar fotos

  // Sincronizacion
  syncStrategy: 'manual' | 'auto' | 'wifi-only';
  conflictResolution: 'server-wins' | 'client-wins' | 'manual';
  maxOfflineHours: number;       // Tiempo maximo sin sincronizar
}
```

---

## 4. Integracion WhatsApp Business + Agente IA

### 4.1 Arquitectura del Agente

```
+--------------------------------------------------+
|           WHATSAPP BUSINESS INTEGRATION          |
+--------------------------------------------------+
|                                                   |
|  [Usuario WhatsApp]                               |
|         |                                         |
|         v                                         |
|  +---------------+                                |
|  | Meta Cloud API|   <-- Webhook                  |
|  +---------------+                                |
|         |                                         |
|         v                                         |
|  +---------------+     +-------------------+      |
|  | Message Router| --> | User Identification|     |
|  +---------------+     +-------------------+      |
|         |                      |                  |
|         |              [Lookup by phone]          |
|         |                      |                  |
|         v                      v                  |
|  +---------------+     +-------------------+      |
|  | Intent Detect | <-- | User Permissions  |      |
|  +---------------+     +-------------------+      |
|         |                                         |
|         v                                         |
|  +---------------+                                |
|  | AI Agent      |   <-- Claude/GPT              |
|  | (Contexto ERP)|                                |
|  +---------------+                                |
|         |                                         |
|         v                                         |
|  +---------------+                                |
|  | Action Handler|                                |
|  +---------------+                                |
|         |                                         |
|    +----+----+----+                               |
|    |    |    |    |                               |
|    v    v    v    v                               |
| Query Create Update Notify                        |
|                                                   |
+--------------------------------------------------+
```

### 4.2 Casos de Uso por Perfil

#### Usuario Interno (Empleado Registrado)

| Intent | Accion | Ejemplo |
|--------|--------|---------|
| Consultar inventario | Query ERP | "Cuanto cemento hay en bodega principal?" |
| Ver mis tareas | Query ERP | "Que tareas tengo pendientes hoy?" |
| Reportar avance | Update ERP | "Termine la partida de cimentacion" |
| Solicitar material | Create ERP | "Necesito 50 bultos de cemento para manana" |
| Consultar estado | Query ERP | "Como va el proyecto Valle Verde?" |

#### Usuario Externo (Cliente/Prospecto)

| Intent | Accion | Ejemplo |
|--------|--------|---------|
| Estado de servicio | Query ERP | "Como va mi orden de servicio?" |
| Agendar cita | Create ERP | "Quiero agendar una cita para la semana que viene" |
| Soporte | Create Ticket | "Tengo un problema con..." |
| Informacion general | FAQ + IA | "Que servicios ofrecen?" |
| Cotizacion | Create Lead | "Quiero una cotizacion para..." |

### 4.3 Modelo de Datos WhatsApp

```sql
-- Schema: whatsapp
CREATE SCHEMA IF NOT EXISTS whatsapp;

-- Numeros de WhatsApp Business registrados
CREATE TABLE whatsapp.business_numbers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES core_tenants.tenants(id),

    phone_number VARCHAR(20) NOT NULL,
    waba_id VARCHAR(50) NOT NULL,        -- WhatsApp Business Account ID
    phone_number_id VARCHAR(50) NOT NULL, -- Meta Phone Number ID

    display_name VARCHAR(100),
    verification_status VARCHAR(20),

    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT uq_business_numbers UNIQUE (phone_number)
);

-- Contactos conocidos
CREATE TABLE whatsapp.contacts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES core_tenants.tenants(id),

    phone_number VARCHAR(20) NOT NULL,
    whatsapp_id VARCHAR(50),              -- WA ID del usuario

    -- Vinculacion con usuario ERP (si existe)
    user_id UUID REFERENCES core_users.users(id),

    -- Datos del contacto
    name VARCHAR(200),
    profile_picture_url VARCHAR(500),

    -- Tipo de contacto
    contact_type VARCHAR(20) DEFAULT 'unknown',
    -- internal: empleado registrado
    -- customer: cliente
    -- lead: prospecto
    -- unknown: no identificado

    -- Consentimiento
    opted_in BOOLEAN DEFAULT false,
    opted_in_at TIMESTAMPTZ,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    last_message_at TIMESTAMPTZ,

    CONSTRAINT uq_whatsapp_contacts UNIQUE (tenant_id, phone_number)
);

-- Conversaciones
CREATE TABLE whatsapp.conversations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES core_tenants.tenants(id),
    business_number_id UUID NOT NULL REFERENCES whatsapp.business_numbers(id),
    contact_id UUID NOT NULL REFERENCES whatsapp.contacts(id),

    status VARCHAR(20) DEFAULT 'active',

    -- Contexto del agente IA
    ai_context JSONB DEFAULT '{}'::jsonb,
    current_intent VARCHAR(100),

    -- Metricas
    message_count INT DEFAULT 0,
    ai_token_count INT DEFAULT 0,

    started_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    last_activity_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    ended_at TIMESTAMPTZ,

    CONSTRAINT chk_conversation_status CHECK (status IN ('active', 'resolved', 'escalated', 'expired'))
);

-- Mensajes
CREATE TABLE whatsapp.messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id UUID NOT NULL REFERENCES whatsapp.conversations(id),

    -- Meta IDs
    wamid VARCHAR(100) UNIQUE,            -- WhatsApp Message ID

    direction VARCHAR(10) NOT NULL,       -- inbound | outbound
    message_type VARCHAR(20) NOT NULL,    -- text, image, document, audio, template

    -- Contenido
    content TEXT,
    media_url VARCHAR(500),
    template_name VARCHAR(100),

    -- AI Processing
    ai_processed BOOLEAN DEFAULT false,
    ai_intent VARCHAR(100),
    ai_response JSONB,
    ai_tokens_used INT DEFAULT 0,

    -- Estado
    status VARCHAR(20) DEFAULT 'sent',
    error_message TEXT,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    delivered_at TIMESTAMPTZ,
    read_at TIMESTAMPTZ,

    CONSTRAINT chk_message_direction CHECK (direction IN ('inbound', 'outbound')),
    CONSTRAINT chk_message_type CHECK (message_type IN ('text', 'image', 'document', 'audio', 'video', 'template', 'interactive'))
);

-- Acciones ejecutadas por el agente
CREATE TABLE whatsapp.ai_actions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    message_id UUID NOT NULL REFERENCES whatsapp.messages(id),
    conversation_id UUID NOT NULL REFERENCES whatsapp.conversations(id),

    action_type VARCHAR(50) NOT NULL,     -- query, create, update, notify
    entity_type VARCHAR(50),              -- project, task, material, etc.
    entity_id UUID,

    input_params JSONB,
    result JSONB,
    success BOOLEAN,
    error_message TEXT,

    tokens_used INT DEFAULT 0,
    execution_time_ms INT,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
```

### 4.4 Facturacion de WhatsApp

```
COSTOS A CONSIDERAR:

1. Meta Platform Fee
   - Conversaciones de negocio: $0.0088 USD por mensaje
   - Conversaciones de servicio: $0.0066 USD por mensaje
   - Primeras 1000 conversaciones/mes: GRATIS

2. Tokens IA (nuestro costo)
   - Procesar mensaje: ~500 tokens input
   - Generar respuesta: ~200 tokens output
   - Costo por mensaje: ~$0.005 USD

3. Modelo de cobro al cliente
   - Incluir X conversaciones en plan base
   - Cobrar excedente por conversacion
   - O cobrar por tokens IA usados
```

---

## 5. Onboarding y Configuracion Inicial

### 5.1 Proceso de Onboarding

```
FASE 1: PRE-VENTA (1-2 semanas)
├── Contacto inicial
├── Demo del sistema
├── Levantamiento de requerimientos
│   ├── Cuestionario de necesidades
│   ├── Catalogo de procesos actuales
│   ├── Volumenes estimados (usuarios, transacciones)
│   └── Integraciones requeridas
├── Propuesta tecnica y comercial
└── Aceptacion y anticipo

FASE 2: CONFIGURACION (2-4 semanas)
├── Creacion de tenant
├── Configuracion de catalogos
│   ├── Usuarios y roles
│   ├── Centros de costo
│   ├── Proyectos/Sucursales
│   └── Productos/Materiales
├── Personalizacion de flujos
├── Configuracion de integraciones
│   ├── Facturacion electronica (CFDI)
│   ├── Bancos
│   ├── WhatsApp Business
│   └── Otras APIs
└── Migracion de datos (si aplica)

FASE 3: CAPACITACION (1-2 semanas)
├── Capacitacion administradores
├── Capacitacion usuarios finales
├── Capacitacion especifica por rol
├── Material de consulta
└── Certificacion de usuarios clave

FASE 4: PILOTO (2-4 semanas)
├── Operacion en paralelo
├── Soporte intensivo
├── Ajustes y correcciones
├── Validacion de reportes
└── Aceptacion formal

FASE 5: GO-LIVE
├── Corte de operacion legacy
├── Operacion productiva
├── Soporte post-go-live (1 mes)
└── Traspaso a soporte regular
```

### 5.2 Modelo de Datos Onboarding

```sql
-- Schema: onboarding
CREATE SCHEMA IF NOT EXISTS onboarding;

-- Proyectos de implementacion
CREATE TABLE onboarding.projects (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES core_tenants.tenants(id),

    -- Identificacion
    project_code VARCHAR(20) NOT NULL UNIQUE,
    company_name VARCHAR(200) NOT NULL,
    vertical VARCHAR(50) NOT NULL,

    -- Contacto principal
    contact_name VARCHAR(200),
    contact_email VARCHAR(200),
    contact_phone VARCHAR(50),

    -- Comercial
    sales_rep_id UUID,
    quote_amount DECIMAL(12,2),
    quote_currency VARCHAR(3) DEFAULT 'MXN',

    -- Estado
    status VARCHAR(30) DEFAULT 'lead',
    current_phase VARCHAR(30),

    -- Fechas
    first_contact_at TIMESTAMPTZ,
    quote_sent_at TIMESTAMPTZ,
    quote_accepted_at TIMESTAMPTZ,
    kickoff_at TIMESTAMPTZ,
    go_live_at TIMESTAMPTZ,
    closed_at TIMESTAMPTZ,

    -- Notas
    requirements_notes TEXT,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT chk_project_status CHECK (status IN (
        'lead', 'qualified', 'quoted', 'negotiating', 'accepted',
        'in_progress', 'pilot', 'live', 'cancelled', 'lost'
    )),
    CONSTRAINT chk_project_phase CHECK (current_phase IN (
        'requirements', 'configuration', 'data_migration',
        'training', 'pilot', 'go_live', 'support'
    ))
);

-- Tareas de implementacion
CREATE TABLE onboarding.tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID NOT NULL REFERENCES onboarding.projects(id),

    phase VARCHAR(30) NOT NULL,
    task_code VARCHAR(20) NOT NULL,
    title VARCHAR(200) NOT NULL,
    description TEXT,

    -- Asignacion
    assigned_to UUID,

    -- Estado
    status VARCHAR(20) DEFAULT 'pending',
    priority VARCHAR(10) DEFAULT 'medium',

    -- Fechas
    due_date DATE,
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,

    -- Dependencias
    depends_on UUID[],

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT uq_task_code UNIQUE (project_id, task_code),
    CONSTRAINT chk_task_status CHECK (status IN ('pending', 'in_progress', 'blocked', 'completed', 'cancelled'))
);

-- Checklist de configuracion
CREATE TABLE onboarding.configuration_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID NOT NULL REFERENCES onboarding.projects(id),

    category VARCHAR(50) NOT NULL,
    item_name VARCHAR(200) NOT NULL,
    description TEXT,

    is_required BOOLEAN DEFAULT true,
    is_completed BOOLEAN DEFAULT false,
    completed_at TIMESTAMPTZ,
    completed_by UUID,

    notes TEXT,

    sort_order INT DEFAULT 0,

    CONSTRAINT uq_config_item UNIQUE (project_id, category, item_name)
);

-- Documentos de proyecto
CREATE TABLE onboarding.documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID NOT NULL REFERENCES onboarding.projects(id),

    document_type VARCHAR(50) NOT NULL,
    title VARCHAR(200) NOT NULL,
    file_url VARCHAR(500),

    uploaded_by UUID,
    uploaded_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT chk_document_type CHECK (document_type IN (
        'quote', 'contract', 'requirements', 'scope', 'migration_spec',
        'training_material', 'acceptance', 'invoice', 'other'
    ))
);

-- Pagos de implementacion
CREATE TABLE onboarding.payments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID NOT NULL REFERENCES onboarding.projects(id),

    concept VARCHAR(100) NOT NULL,
    amount DECIMAL(12,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'MXN',

    payment_type VARCHAR(20) NOT NULL,

    -- Referencia de pago
    invoice_id UUID REFERENCES billing.invoices(id),
    stripe_payment_id VARCHAR(50),

    status VARCHAR(20) DEFAULT 'pending',
    paid_at TIMESTAMPTZ,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT chk_payment_type CHECK (payment_type IN ('deposit', 'milestone', 'final', 'extra'))
);
```

---

## 6. Control de Tokens IA y Facturacion por Uso

### 6.1 Metricas de Uso de IA

```sql
-- Extender tabla billing.usage_records para tokens IA

-- Tipos de metricas IA:
-- 'ai_input_tokens': Tokens de entrada (prompts)
-- 'ai_output_tokens': Tokens de salida (respuestas)
-- 'ai_embeddings': Tokens de embeddings
-- 'whatsapp_ai_conversations': Conversaciones WA procesadas por IA

-- Vista agregada de uso de IA
CREATE VIEW billing.vw_ai_usage_summary AS
SELECT
    tenant_id,
    period,
    SUM(CASE WHEN metric_type = 'ai_input_tokens' THEN value ELSE 0 END) AS input_tokens,
    SUM(CASE WHEN metric_type = 'ai_output_tokens' THEN value ELSE 0 END) AS output_tokens,
    SUM(CASE WHEN metric_type = 'ai_embeddings' THEN value ELSE 0 END) AS embedding_tokens,
    SUM(CASE WHEN metric_type = 'whatsapp_ai_conversations' THEN value ELSE 0 END) AS wa_conversations,

    -- Costo calculado
    SUM(CASE WHEN metric_type = 'ai_input_tokens' THEN value * 0.003 / 1000 ELSE 0 END) +
    SUM(CASE WHEN metric_type = 'ai_output_tokens' THEN value * 0.015 / 1000 ELSE 0 END) +
    SUM(CASE WHEN metric_type = 'ai_embeddings' THEN value * 0.0001 / 1000 ELSE 0 END) AS total_cost_usd

FROM billing.usage_records
WHERE metric_type LIKE 'ai_%' OR metric_type = 'whatsapp_ai_conversations'
GROUP BY tenant_id, period;
```

### 6.2 Flujo de Registro de Tokens

```
[Llamada a AI API]
       |
       v
[Token Counter Middleware]
       |
       ├── input_tokens = count(prompt)
       ├── output_tokens = count(response)
       |
       v
[Usage Logger Service]
       |
       ├── Incrementar usage_records (async)
       ├── Verificar limites del plan
       |
       v
[Rate Limiter]
       |
       ├── Si excede limite: bloquear o alertar
       └── Si OK: continuar

[Fin del Periodo (Billing Job)]
       |
       v
[Calcular costo total]
       |
       v
[Generar linea en factura]
       |
       └── type: 'usage'
       └── description: 'Tokens IA - Diciembre 2025'
       └── quantity: total_tokens
       └── unit_price: costo_por_token
       └── amount: total_cost
```

### 6.3 Alertas de Consumo

```typescript
interface UsageAlertConfig {
  // Thresholds por tipo de metrica
  thresholds: {
    ai_tokens: {
      warning: 80,      // % del limite
      critical: 95,     // % del limite
      action: 'notify' | 'block' | 'auto_upgrade'
    },
    whatsapp_conversations: {
      warning: 75,
      critical: 90,
      action: 'notify'
    }
  };

  // Notificaciones
  notifications: {
    email: boolean;
    push: boolean;
    whatsapp: boolean;
  };

  // Destinatarios
  recipients: string[];  // user_ids de administradores
}
```

---

## 7. Impacto en Verticales

### 7.1 Construccion

| Componente | Impacto | Nuevos Modulos |
|------------|---------|----------------|
| Apps Moviles | Alto | App Encargado, App Almacen, App Cliente |
| WhatsApp | Alto | Notificaciones, Consultas |
| Biometricos | Alto | Check in/out con facial |
| Tokens IA | Medio | Asistente de obra |
| Onboarding | Alto | Migracion de proyectos |

### 7.2 Otras Verticales

| Vertical | Apps Moviles | WhatsApp | Biometricos | IA |
|----------|--------------|----------|-------------|-----|
| Vidrio Templado | Produccion, Instalador | Si | Opcional | Medio |
| Mecanicas | Tecnico | Si | No | Alto |
| Retail | Vendedor | Si | Opcional | Medio |
| Clinicas | Doctor, Paciente | Si | Opcional | Alto |

---

## 8. Plan de Implementacion

### 8.1 Fases

```
FASE 1: INFRAESTRUCTURA BASE (8 semanas)
├── Integracion Stripe
├── Sistema de onboarding
├── Control de tokens IA
└── Base de apps moviles

FASE 2: WHATSAPP (6 semanas)
├── Integracion Meta Cloud API
├── Agente IA basico
├── Registro de conversaciones
└── Facturacion WhatsApp

FASE 3: APPS MOVILES - CONSTRUCCION (10 semanas)
├── App Encargado de Obra
├── App Almacen
├── App Derechohabiente
└── Biometricos

FASE 4: APPS MOVILES - OTRAS VERTICALES (12 semanas)
├── Apps por vertical
└── Personalizaciones
```

### 8.2 Recursos Requeridos

| Rol | Cantidad | Dedicacion |
|-----|----------|------------|
| Backend Developer | 2 | Full-time |
| Mobile Developer (React Native) | 2 | Full-time |
| Frontend Developer | 1 | Part-time |
| DevOps | 1 | Part-time |
| QA | 1 | Full-time |
| Product Owner | 1 | Part-time |

---

## 9. Proximos Pasos

1. **Validar** este documento con stakeholders
2. **Crear epicas** para cada modulo nuevo
3. **Disenar** arquitectura detallada de cada componente
4. **Priorizar** features para MVP
5. **Estimar** esfuerzo y crear roadmap

---

## 10. Referencias

- [EPIC-MGN-016-billing.md](/home/isem/workspace/projects/erp-suite/apps/erp-core/docs/08-epicas/EPIC-MGN-016-billing.md)
- [DDL-SPEC-billing.md](/home/isem/workspace/projects/erp-suite/apps/erp-core/docs/04-modelado/database-design/DDL-SPEC-billing.md)
- [Stripe Billing Documentation](https://stripe.com/docs/billing)
- [Meta WhatsApp Business API](https://developers.facebook.com/docs/whatsapp)

---

*Ultima actualizacion: 2025-12-05*
