- Frontend React (SKEEN Brand) con Vite, TypeScript, Tailwind - Frontend Homenest (versión alternativa) - Módulos Odoo 17 custom (citas, pacientes, monedero, pagos, ventas, inventario, whatsapp) - WACRM fork (Next.js 16 + Supabase) - Hermes + Bridge + Skills (Qwen3.6 via Nan Builders) - Scripts de migración y operación - Documentación extensiva en docs/
20 KiB
20 KiB
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
- Sin vendor lock-in: Todo self-hostable, código MIT/LGPL.
- Escalable: Componentes desacoplados, comunicación via APIs y webhooks.
- Seguro: RLS, HMAC, autenticación JWT, secretos fuera del código.
- Mantenible: Código modular, documentación extensiva, tests automatizados.
- 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
- Meta Cloud API recibe mensaje del paciente.
- Meta envía webhook a WACRM (
/api/whatsapp/webhook). - WACRM crea/actualiza:
- Contacto (por número de teléfono).
- Conversación.
- Mensaje con
sender_type: customer.
- WACRM dispara automatización
new_message_received. - Automatización ejecuta step
send_webhook:- URL:
http://localhost:8090/webhook/wacrm - Body:
{from, text, conversation_id, contact_id}
- URL:
- 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.
- 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).
- Primero intenta
- WACRM guarda mensaje con
sender_type: agent. - WACRM envía mensaje a Meta Cloud API (si hay token real).
- Paciente recibe respuesta en WhatsApp.
3.2 Agendamiento de cita vía IA
- Paciente pide agendar cita en WhatsApp.
- Sofía (Hermes) detecta intención y activa skill
skeen-agendar. - Skill consulta Odoo API (
/skeen/api/v1/available_slots) para disponibilidad. - Sofía presenta opciones al paciente.
- Paciente confirma fecha/hora.
- 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.
- Skill envía confirmación via WACRM.
- Cita aparece en Frontend React y WACRM (sincronización).
3.3 Sincronización WACRM ↔ Odoo
- Contactos: WACRM crea contacto → webhook → Odoo crea
res.partnerconis_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
- Webhooks WACRM: Firma HMAC-SHA256 en header
X-WACRM-Signature. - API Keys: Todas las APIs usan Bearer tokens.
- JWT: Frontend React usa JWT firmado por Odoo.
- RLS: Row-Level Security en Supabase.
- Secretos: Nunca commiteados, en variables de entorno.
- HTTPS: Configurar en producción.
- Rate limiting: Configurar en nginx y WACRM.
- Input validation: Validación en todos los endpoints.
- 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) |