# Arquitectura Técnica — SKEEN Derma Experts **Versión:** 2.0 **Fecha:** 16 de julio de 2026 **Proyecto:** SKEEN Derma Experts — Sistema Integral de Gestión Clínica --- ## 1. Visión General SKEEN Derma Experts es un sistema integral de gestión clínica que unifica: - **Comunicación:** WhatsApp Business API (Meta Cloud API) - **IA Conversacional:** Hermes + Qwen3.6 (Nan Builders) - **ERP/CRM:** Odoo 17 Community - **Inbox CRM:** WACRM (Next.js 16 + Supabase) - **Panel de Control:** Frontend React 18 - **Base de Datos WACRM:** Supabase self-hosted (PostgreSQL + Auth + Realtime) ### 1.1 Objetivos de Arquitectura 1. **Sin vendor lock-in:** Todo self-hostable, código MIT/LGPL. 2. **Escalable:** Componentes desacoplados, comunicación via APIs y webhooks. 3. **Seguro:** RLS, HMAC, autenticación JWT, secretos fuera del código. 4. **Mantenible:** Código modular, documentación extensiva, tests automatizados. 5. **Proactivo:** IA que actúa sin input del usuario (recordatorios, follow-ups). --- ## 2. Diagrama de Componentes ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ USUARIOS │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Paciente │ │ Recepcionista│ │ Médico │ │ Admin │ │ │ │ (WhatsApp) │ │ (Frontend) │ │ (Frontend) │ │ (Frontend) │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ └─────────┼─────────────────┼─────────────────┼─────────────────┼────────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ FRONTEND REACT │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ React 18 + Vite + TypeScript + Tailwind CSS + React Router │ │ │ │ Proxy /api/odoo → Odoo REST API │ │ │ │ Proxy /api/wacrm → WACRM API │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ nginx (static + reverse proxy) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ ODOO 17 │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Módulos Custom: │ │ │ │ skeen_citas — Citas médicas, disponibilidad, paquetes │ │ │ │ skeen_pacientes — Pacientes, expedientes médicos │ │ │ │ skeen_monedero — Sistema de puntos/fidelidad │ │ │ │ skeen_pagos — Pagos, adeudos, Stripe/MercadoPago (futuro) │ │ │ │ skeen_ventas — Ventas, corte de caja, comisiones, metas │ │ │ │ skeen_inventario — Inventario de productos y consumibles │ │ │ │ skeen_whatsapp — API REST para Hermes/WACRM/Frontend │ │ │ │ │ │ │ │ PostgreSQL: skeen_odoo │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ▲ │ XML-RPC / JSON-RPC │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ HERMES + BRIDGE │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Hermes Gateway (daemon) │ │ │ │ - Gateway API :8080 │ │ │ │ - Heartbeat cada 30 min │ │ │ │ - Skills: skeen-rag, skeen-agendar, skeen-pagos, ... │ │ │ │ │ │ │ │ Bridge Webhook SKEEN (:8090) │ │ │ │ - Recibe webhooks de WACRM │ │ │ │ - Consulta Nan Builders API (Qwen3.6) │ │ │ │ - Responde a WACRM vía API │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ▲ │ Webhook HMAC-SHA256 │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ WACRM │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Next.js 16 App Router │ │ │ │ - Shared inbox multi-agente │ │ │ │ - Contactos + tags + custom fields │ │ │ │ - Pipelines Kanban (Lead → Consulta → Tratamiento → Recurrente) │ │ │ │ - Automatizaciones no-code │ │ │ │ - Broadcasts con templates Meta │ │ │ │ - API REST pública /api/v1/* │ │ │ │ - Webhooks outbound firmados HMAC-SHA256 │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Supabase self-hosted (Docker) │ │ │ │ - PostgreSQL :5433 │ │ │ │ - Auth (JWT) │ │ │ │ - Realtime subscriptions │ │ │ │ - Storage │ │ │ │ - Kong API Gateway :8000 │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ▲ │ Meta Cloud API │ ┌─────────────────────────────────────────────────────────────────────────────┐ │ META WHATSAPP CLOUD API │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ - Recepción de mensajes de WhatsApp │ │ │ │ - Envío de mensajes de WhatsApp │ │ │ │ - Templates aprobados │ │ │ │ - Webhooks a WACRM │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 3. Flujo de Datos Paso a Paso ### 3.1 Mensaje entrante de WhatsApp 1. **Meta Cloud API** recibe mensaje del paciente. 2. **Meta** envía webhook a **WACRM** (`/api/whatsapp/webhook`). 3. **WACRM** crea/actualiza: - Contacto (por número de teléfono). - Conversación. - Mensaje con `sender_type: customer`. 4. **WACRM** dispara automatización `new_message_received`. 5. **Automatización** ejecuta step `send_webhook`: - URL: `http://localhost:8090/webhook/wacrm` - Body: `{from, text, conversation_id, contact_id}` 6. **Bridge SKEEN** recibe el webhook: - Extrae datos. - Construye contexto (historial reciente si existe). - Consulta **Nan Builders API** (Qwen3.6) con el system prompt de Sofía. - Obtiene respuesta de la IA. 7. **Bridge** envía respuesta a **WACRM**: - Primero intenta `POST /api/v1/messages` (si hay token Meta). - Si falla, fallback a `POST /api/v1/messages/simulate` (modo demo). 8. **WACRM** guarda mensaje con `sender_type: agent`. 9. **WACRM** envía mensaje a **Meta Cloud API** (si hay token real). 10. **Paciente** recibe respuesta en WhatsApp. ### 3.2 Agendamiento de cita vía IA 1. Paciente pide agendar cita en WhatsApp. 2. Sofía (Hermes) detecta intención y activa skill `skeen-agendar`. 3. Skill consulta **Odoo API** (`/skeen/api/v1/available_slots`) para disponibilidad. 4. Sofía presenta opciones al paciente. 5. Paciente confirma fecha/hora. 6. Skill llama **Odoo API** (`/skeen/api/v1/create_appointment`): - Busca o crea paciente por teléfono. - Crea cita con estado `confirmed`. - Si es paquete, crea N citas separadas. 7. Skill envía confirmación via WACRM. 8. Cita aparece en **Frontend React** y **WACRM** (sincronización). ### 3.3 Sincronización WACRM ↔ Odoo - **Contactos:** WACRM crea contacto → webhook → Odoo crea `res.partner` con `is_patient=True`. - **Conversaciones:** WACRM → Odoo cachea en `skeen.wacrm.conversation`. - **Mensajes:** WACRM → Odoo cachea en `skeen.wacrm.message`. - **Leads/Deals:** WACRM pipeline → Odoo cachea en `skeen.wacrm.deal`. - **Frontend:** Lee de Odoo vía `/skeen/frontend/v1/wacrm/*`. --- ## 4. Comunicación entre Componentes | Canal | Tecnología | Autenticación | Frecuencia | |-------|-----------|---------------|------------| | Meta → WACRM | Webhook HTTPS | Verify Token | Evento | | WACRM → Bridge | Webhook HTTP | HMAC-SHA256 | Evento | | Bridge → Nan Builders | HTTPS REST | API Key | Bajo demanda | | Bridge → WACRM | HTTPS REST | API Key (Bearer) | Bajo demanda | | Hermes → Odoo | XML-RPC / JSON-RPC | API Key | Bajo demanda | | Frontend → Odoo | HTTPS REST | JWT | Bajo demanda | | WACRM → Odoo | HTTPS REST | API Key | Sync cada 5 min | | Odoo → Supabase | PostgreSQL directo | Service Role Key | Bajo demanda | --- ## 5. Stack Tecnológico | Capa | Tecnología | Versión | Rol | |------|-----------|---------|-----| | **IA** | Hermes (Nous Research) | latest | Agente autónomo | | **IA Modelo** | Qwen3.6 (Nan Builders) | latest | Generación de respuestas | | **CRM WhatsApp** | WACRM | MIT | Inbox, pipelines, automatizaciones | | **Backend IA** | Node.js | 20+ | Bridge webhook | | **ERP** | Odoo | 17 Community | Citas, ventas, pagos, monedero | | **Base de Datos ERP** | PostgreSQL | 16 | Datos clínicos | | **Base de Datos WACRM** | PostgreSQL (Supabase) | 16 | Datos WACRM | | **Frontend** | React | 18 | Panel de control | | **Frontend Build** | Vite | 5+ | Bundler | | **Frontend Estilos** | Tailwind CSS | 3+ | UI | | **Frontend Lenguaje** | TypeScript | 5+ | Type safety | | **Web Server** | nginx | 1.24+ | Reverse proxy + static | | **Containerización** | Docker + Docker Compose | latest | Supabase self-hosted | | **Sistema Operativo** | Ubuntu | 22.04 | VM Hetzner | --- ## 6. Decisiones de Arquitectura ### 6.1 WACRM vs Inbox Custom **Decisión:** Usar WACRM en lugar de construir inbox propio. **Justificación:** - Inbox funcional desde el día 1. - Shared inbox multi-agente nativo. - Pipelines Kanban nativos. - Automatizaciones no-code. - Broadcasts con templates Meta. - Dashboard real-time nativo. - API REST pública completa. - Comunidad activa (MIT). - 60% menos código custom. ### 6.2 Hermes vs FastAPI + GPT-4o Directo **Decisión:** Usar Hermes + Bridge Node.js en lugar de FastAPI custom. **Justificación:** - Hermes ya tiene gateway, memoria, skills, heartbeat. - 25+ tools built-in + customs. - Multi-model (OpenAI, Anthropic, Google, Ollama, Nan Builders). - Heartbeat permite acciones proactivas (recordatorios). - Skills modulares fáciles de mantener. - Bridge simple (~200 líneas) vs backend completo. - Comunidad 150k+ stars. ### 6.3 Supabase Self-Hosted vs Supabase Cloud **Decisión:** Self-hosted. **Justificación:** - Control total de datos. - Sin límites de tier gratuito. - Sin costos mensuales de Supabase Pro ($25/mes). - Datos en la misma VM que el resto del sistema. - PostgreSQL completo sin restricciones. **Costo:** 22 GB RAM de la VM soporta Supabase + Odoo + WACRM + Frontend sin problemas. ### 6.4 Odoo 17 vs CRM Custom **Decisión:** Odoo 17 Community. **Justificación:** - ERP/CRM maduro y probado. - Módulos custom fáciles de crear. - PostgreSQL nativo. - API XML-RPC/JSON-RPC completa. - Escalable. - Sin costo de licencia. --- ## 7. Consideraciones de Escalabilidad | Componente | Estrategia de Escalabilidad | |------------|----------------------------| | **Frontend** | Static files en CDN (Cloudflare) | | **Odoo** | Múltiples workers, Redis cache, read replicas | | **WACRM** | Horizontal scaling con Supabase, load balancer | | **Hermes** | Múltiples gateways, queue de mensajes | | **Bridge** | Stateless, múltiples instancias | | **PostgreSQL** | Read replicas, connection pooling (pgbouncer) | | **Supabase** | Múltiples nodos, load balancer | --- ## 8. Consideraciones de Seguridad 1. **Webhooks WACRM:** Firma HMAC-SHA256 en header `X-WACRM-Signature`. 2. **API Keys:** Todas las APIs usan Bearer tokens. 3. **JWT:** Frontend React usa JWT firmado por Odoo. 4. **RLS:** Row-Level Security en Supabase. 5. **Secretos:** Nunca commiteados, en variables de entorno. 6. **HTTPS:** Configurar en producción. 7. **Rate limiting:** Configurar en nginx y WACRM. 8. **Input validation:** Validación en todos los endpoints. 9. **Audit logs:** Odoo tracking, WACRM audit, bridge logs. --- ## 9. Alta Disponibilidad y Recuperación | Componente | Estrategia | |------------|-----------| | **Supabase** | Docker restart policy `always`, backups diarios | | **Odoo** | systemd auto-restart, backups de PostgreSQL | | **WACRM** | systemd auto-restart | | **Hermes** | systemd auto-restart | | **Bridge** | systemd auto-restart | | **PostgreSQL** | Backups diarios, point-in-time recovery | | **Frontend** | Static, sin estado | | **Monitoreo** | Uptime Kuma (a configurar) | --- ## 10. Referencias - [WACRM GitHub](https://github.com/ArnasDon/wacrm) - [Hermes Agent](https://github.com/NousResearch/Hermes-Agent) - [Odoo 17 Documentation](https://www.odoo.com/documentation/17.0) - [Supabase Self-Hosting](https://supabase.com/docs/guides/self-hosting) - [Meta WhatsApp Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api) - [Nan Builders API](https://api.nan.builders)