- 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/
325 lines
20 KiB
Markdown
325 lines
20 KiB
Markdown
# 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)
|