Initial commit: SKEEN Derma Experts - Sistema Integral de Gestión Clínica
- 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/
This commit is contained in:
289
docs/ANALISIS_SKEEN_SISTEMA.md
Normal file
289
docs/ANALISIS_SKEEN_SISTEMA.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# Análisis del Sistema Actual de SKEEN Derma Experts
|
||||
## URL analizada: https://sistema.skeenmx.app/
|
||||
|
||||
**Fecha:** 6 de julio de 2026
|
||||
**Usuario de análisis:** JoseSkeen
|
||||
**Restricción:** Solo lectura, sin modificaciones en el sistema original.
|
||||
|
||||
---
|
||||
|
||||
## 1. Tecnología base
|
||||
|
||||
- **Framework:** Laravel (PHP) — se identifican tokens `_token`, cookies `laravel_session`, estructura de rutas RESTful.
|
||||
- **Frontend:** jQuery 1.12 + Bootstrap/AdminLTE 2.3.5 + CSS propio (`panel.css`, `app.css`).
|
||||
- **Iconos:** Font Awesome 6.2.0 (regular, solid, brands).
|
||||
- **Componentes UI:** DataTables, datepickers, modales Bootstrap, bxslider (comentado).
|
||||
- **No es SPA:** cada sección recarga la página; el layout es sidebar izquierdo + header superior + contenido central.
|
||||
|
||||
---
|
||||
|
||||
## 2. Identidad visual
|
||||
|
||||
### Paleta de colores predominante
|
||||
| Color | Uso |
|
||||
|-------|-----|
|
||||
| `#1abc9c` / `#16a085` | Acento principal (botones, iconos, estados activos) |
|
||||
| `#BED4AD` | Verde pastel secundario (usado en badges / categorías) |
|
||||
| `#34495e` / `#2c3e50` / `#222f3d` | Textos oscuros, sidebar, header |
|
||||
| `#f1c40f` | Amarillo alerta / metas |
|
||||
| `#e74c3c` | Rojo error / cancelaciones |
|
||||
| `#2ecc71` | Verde éxito |
|
||||
| `#3498db` / `#48c9b0` | Azules informativos |
|
||||
| `#ffffff` / `#f5f5f5` | Fondos claros |
|
||||
| `#bdc3c7` / `#ccc` / `#999` | Grises de borde y texto secundario |
|
||||
|
||||
### Tipografía
|
||||
- **Principal:** `Lato`, Helvetica, Arial, sans-serif.
|
||||
- **Iconos:** Font Awesome (versión 6.2).
|
||||
- **Logo:** `logo_skeen.png` — tipografía sans-serif negra, letras mayúsculas, registro ®.
|
||||
|
||||
### Layout
|
||||
- **Sidebar izquierdo** con menú principal + submenús desplegables (`treeview`).
|
||||
- **Header superior** fijo con:
|
||||
- Contactos rápidos (teléfono, WhatsApp, Facebook, Instagram, email, sitio web).
|
||||
- Tipo de cambio (TC: 16.50).
|
||||
- Selector de sucursal (Rosarito / Tijuana).
|
||||
- Meta de ventas con progress bar (ej. "Noviembre 2020 — 60% Complete — 600 USD / 1000 USD").
|
||||
- Perfil de usuario, notas y chat interno.
|
||||
- **Contenido central** con breadcrumb "Inicio / Sección", título de página, filtros, tablas DataTables y modales para acciones.
|
||||
|
||||
---
|
||||
|
||||
## 3. Mapa de navegación
|
||||
|
||||
### Menú principal (top-level)
|
||||
| Ruta | Sección |
|
||||
|------|---------|
|
||||
| `/dashboard` | Inicio / Movimientos diarios |
|
||||
| `/agenda` | Agenda de citas |
|
||||
| `/visitas` | Visitas registradas |
|
||||
| `/expedientes` | Expedientes de pacientes |
|
||||
| `/medicos` | Médicos |
|
||||
| `/cosmetologos` | Cosmetología |
|
||||
| `/consultas` | Consultas Médicas |
|
||||
|
||||
### Configuración
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/usuarios/consulta/activados` | Usuarios del sistema |
|
||||
| `/recetas` | Catálogo de recetas |
|
||||
| `/diagnosticos` | Catálogo de diagnósticos |
|
||||
| `/procedimientos` | Catálogo de procedimientos médicos |
|
||||
| `/servicios` | Catálogo de servicios |
|
||||
| `/etiquetas` | Etiquetas |
|
||||
| `/productos` | Productos |
|
||||
| `/inventarios` | Inventarios de productos |
|
||||
| `/tipo_cambio` | Tipo de cambio USD/MXN |
|
||||
|
||||
### Reportes
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/reportes/diario` | Mov. diario |
|
||||
| `/reportes/medicos` | Mov. diario por médico |
|
||||
| `/reportes/recepcion` | Mov. diario por recepcionista |
|
||||
| `/reportes/cortes` | Cortes de caja |
|
||||
| `/reportes/ingresos` | Ingresos |
|
||||
| `/reportes/comisiones` | Comisiones |
|
||||
|
||||
### Administrativo
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/reportes/adeudos` | Adeudos clientes |
|
||||
| `/reportes/pagos` | Pagos por servicios |
|
||||
| `/reportes/clientes` | Pagos por clientes |
|
||||
| `/reportes/visitas` | Visitas |
|
||||
| `/reportes/devoluciones` | Devoluciones |
|
||||
| `/reportes/vendedores` | Vendedores |
|
||||
| `/reportes/recomendaciones` | Recomendaciones |
|
||||
| `/reportes/concentrado` | Concentrado |
|
||||
| `/reportes/top/clientes` | Top ventas |
|
||||
| `/reportes/agenda` | Horas agenda |
|
||||
| `/reportes/paquetes` | Paquetes |
|
||||
|
||||
### Monedero
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/monederos/consulta` | Monederos electrónicos |
|
||||
| `/reportes/monedero` | Reporte de puntos |
|
||||
| `/configuracion/monedero` | Lista de precios y % de puntos |
|
||||
|
||||
### Comunicación
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/reportes/cumple` | Cumpleañeros |
|
||||
|
||||
### Consumibles
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/consumibles/inventario` | Inventario actual |
|
||||
| `/consumibles/ventas/consulta` | Comprobantes de consumibles |
|
||||
| `/consumibles/compras/consulta` | Compras |
|
||||
| `/consumibles/bajas` | Bajas |
|
||||
| `/consumibles/consulta` | Consumibles |
|
||||
|
||||
### CRM
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/crm` | Inicio CRM (prospectos, clientes potenciales, expedientes) |
|
||||
| `/crm/medio/{id}` | Filtrar por medio (llamada, WhatsApp, Facebook, Instagram, email, sitio web) |
|
||||
|
||||
### Ventas / Pedidos
|
||||
| Ruta | Función |
|
||||
|------|---------|
|
||||
| `/admin/pedidos/dia` | Ventas del día |
|
||||
| `/admin/pedidos/factura` | Factura |
|
||||
| `/admin/pedidos/anticipo` | Anticipo |
|
||||
| `/admin/pedidos/clientes` | Clientes con adeudos |
|
||||
|
||||
---
|
||||
|
||||
## 4. Funcionalidades clave identificadas
|
||||
|
||||
### Agenda
|
||||
- Filtro por sucursal (Rosarito / Tijuana).
|
||||
- Filtro por médico.
|
||||
- Tabs: Citas, Nueva cita, Lista de espera.
|
||||
- Estados de cita: Pre-consulta, Link enviado, Aprobación, Asignar expediente, Agendar.
|
||||
- Medio: Videollamada / Consultorio.
|
||||
- Acciones: Forma de pago, agendar, enviar WhatsApp.
|
||||
|
||||
### Expedientes
|
||||
- Filtros: VIP, visitó en últimos 6 meses, no ha visitado en 6 meses.
|
||||
- Columnas: ID, folio, nombre, motivo, médico, cosmetología, estatus, cabina, consentimientos, ticket.
|
||||
- Estados: Nueva visita, visita recurrente.
|
||||
|
||||
### Médicos / Cosmetología
|
||||
- Directorio de personal con nombre, apellidos, celular, WhatsApp.
|
||||
- Últimos 30 días de actividad.
|
||||
- Roles: médico, cosmetología, recepción, administrador.
|
||||
|
||||
### Servicios
|
||||
- Catálogo con: ID, Categoría, Concepto, Precio, Activado, Favoritos, Color, Grupo, Etiquetas.
|
||||
- Ordenar favoritos.
|
||||
|
||||
### Productos
|
||||
- Catálogo con: ID, Línea/Categoría, Producto, Descripción, Precio, Activado, Favoritos.
|
||||
|
||||
### Monedero
|
||||
- Configuración de porcentajes de puntos por forma de pago y moneda.
|
||||
- Transferencia USD: 0%
|
||||
- Transferencia M.N.: 0%
|
||||
- Tarjeta USD: 1.5%
|
||||
- Tarjeta M.N.: 1.5%
|
||||
- Efectivo USD: 2%
|
||||
- Efectivo M.N.: 2%
|
||||
- Lista de precios con flags: Otorga puntos, Canjeable por puntos.
|
||||
|
||||
### Movimientos diarios / Ventas
|
||||
- Tabla de ventas con: ID, Expediente, Dr. principal, Concepto, Subtotal, Desc., Pagado, Adeudo, Pendiente.
|
||||
- Formas de pago: Efectivo M.N./USD, Tarjeta M.N./USD, Transferencia M.N./USD, Saldo a favor M.N./USD, Monedero electrónico M.N./USD.
|
||||
- Acciones: Cancelar venta, paquete terminado, devolución.
|
||||
- Modal "Valoración Express" para captura rápida de prospectos.
|
||||
|
||||
### Cortes de caja
|
||||
- Histórico por día.
|
||||
- Totales por médico, recepcionista, productos entregados.
|
||||
- Modal para establecer corte con monto M.N., dólares, observaciones.
|
||||
|
||||
### Adeudos
|
||||
- Separación: adeudos activos (1 año y medio a la fecha) vs pasivos (anteriores).
|
||||
- Agrupación por médico.
|
||||
- Totales por clínica y por doctor.
|
||||
|
||||
### Inventarios
|
||||
- Productos: stock, niveles (óptimo, bajo, crítico, sin existencias).
|
||||
- Consumibles: valor de inventario, niveles, caducidad, último conteo físico.
|
||||
- Ajustes, compras, bajas.
|
||||
|
||||
### CRM
|
||||
- Prospectos por medio de contacto.
|
||||
- Ficha de prospecto con:
|
||||
- Datos personales (nombre, teléfonos, WhatsApp, correo).
|
||||
- Historial de visitas.
|
||||
- Citas futuras.
|
||||
- Saldo / adeudo.
|
||||
- Notas internas.
|
||||
- Perfil, mensajes, settings.
|
||||
- Botones rápidos: llamada, WhatsApp, Facebook, Instagram, email, sitio web.
|
||||
|
||||
### Comunicación
|
||||
- Cumpleañeros: lista de pacientes con fecha de cumpleaños, edad, concepto, subtotal, promo, pagado, adeudo.
|
||||
|
||||
---
|
||||
|
||||
## 5. Flujos de negocio identificados
|
||||
|
||||
1. **Captación de prospecto**
|
||||
- Medio: WhatsApp / llamada / FB / IG / email / sitio web.
|
||||
- Registro en CRM → seguimiento → agenda de valoración.
|
||||
|
||||
2. **Agendamiento**
|
||||
- Agenda con médico, sucursal, tipo de cita (videollamada/presencial).
|
||||
- Estados: pre-consulta, aprobación, link enviado, asignar expediente.
|
||||
|
||||
3. **Visita / Expediente**
|
||||
- Llegada del paciente → creación de visita → expediente médico.
|
||||
- Diagnóstico, procedimiento, receta.
|
||||
|
||||
4. **Venta**
|
||||
- Concepto (servicio/producto), subtotal, descuento, pagado, adeudo.
|
||||
- Múltiples formas de pago y monedas.
|
||||
- Acumulación de puntos según forma de pago.
|
||||
|
||||
5. **Pago / Adeudo**
|
||||
- Pagos parciales, saldo a favor, monedero electrónico.
|
||||
- Reportes de adeudos por edad y por médico.
|
||||
|
||||
6. **Corte de caja**
|
||||
- Cierre diario con totales por recepcionista y médico.
|
||||
|
||||
7. **Inventario**
|
||||
- Entradas (compras), salidas (ventas/bajas), ajustes, niveles de stock.
|
||||
|
||||
---
|
||||
|
||||
## 6. Gaps y oportunidades de mejora
|
||||
|
||||
| # | Gap actual | Oportunidad en nuevo sistema |
|
||||
|---|-----------|------------------------------|
|
||||
| 1 | UI antigua (jQuery/Bootstrap 2015) | Migrar a React 19 + Tailwind con diseño moderno y responsive |
|
||||
| 2 | Sin chatbot / IA | Integrar WACRM + Hermes (Sofía) para atención 24/7 vía WhatsApp |
|
||||
| 3 | CRM básico | Usar WACRM pipelines + contactos + automatizaciones no-code |
|
||||
| 4 | Agenda manual sin recordatorios automáticos | Heartbeat/cron de Hermes para recordatorios 24h y follow-ups |
|
||||
| 5 | No hay inbox multi-agente | WACRM shared inbox con asignación, notas internas, handoff |
|
||||
| 6 | Pagos no integrados con Stripe/MP | Módulo `skeen_pagos` + skills de Hermes para links de pago |
|
||||
| 7 | Monedero sin reglas claras de redención | Reglas: 1 punto = $1 MXN, máx 50% redimible, vencimiento 12 meses |
|
||||
| 8 | Reportes estáticos | Dashboards interactivos con Recharts en frontend |
|
||||
| 9 | Sin unificación Odoo ↔ frontend | API REST propia en Odoo (`skeen_whatsapp/controllers/frontend.py`) |
|
||||
| 10 | Login propio, sin single sign-on | Evaluar Supabase Auth para WACRM + Odoo (opcional) |
|
||||
| 11 | Dependencia de sistema legacy | Replicar funcionalidad en Odoo 17 + módulos custom |
|
||||
| 12 | No hay broadcasting de campañas | WACRM broadcasts con templates aprobados por Meta |
|
||||
|
||||
---
|
||||
|
||||
## 7. Datos maestros a migrar
|
||||
|
||||
- **Pacientes/Clientes:** nombre, apellidos, teléfonos, WhatsApp, correo, fecha de nacimiento, médico principal, etiquetas, VIP.
|
||||
- **Expedientes médicos:** diagnósticos, procedimientos, recetas, visitas, consentimientos.
|
||||
- **Servicios:** categoría, concepto, precio, favorito, color, grupo, etiquetas.
|
||||
- **Productos:** línea/categoría, producto, descripción, precio, stock, inventario mínimo.
|
||||
- **Médicos / Cosmetólogos / Usuarios:** datos de contacto, roles, comisiones.
|
||||
- **Monederos:** saldo, historial de puntos, reglas de acumulación/redención.
|
||||
- **Adeudos / Pagos:** saldo pendiente, historial de pagos, formas de pago.
|
||||
- **Consumibles:** inventario, caducidad, compras, bajas.
|
||||
- **Agenda:** citas históricas y futuras.
|
||||
|
||||
---
|
||||
|
||||
## 8. Notas técnicas
|
||||
|
||||
- El sistema original usa Apache + Laravel + PHP.
|
||||
- Algunas imágenes están rotas (`img_logo_derma_blanco.png` devuelve 404).
|
||||
- El login expone el logo en blanco (`logo_skeen_white.png`) sobre fondo oscuro.
|
||||
- Hay chat interno (`chat_conversaciones`, `chat_usuarios`) implementado en el frontend.
|
||||
- El header muestra "TC: 16.50" como tipo de cambio dinámico.
|
||||
- La meta de ventas es visible en el header con progress bar.
|
||||
|
||||
---
|
||||
|
||||
*Documento generado para análisis. No se realizaron modificaciones en https://sistema.skeenmx.app/*
|
||||
246
docs/ESTADO_PROYECTO.md
Normal file
246
docs/ESTADO_PROYECTO.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Estado del Proyecto SKEEN Derma Experts
|
||||
## WACRM + Hermes + Odoo + Frontend
|
||||
|
||||
**Fecha:** 6 de julio de 2026 (actualizado)
|
||||
**VM:** Hetzner VPS (22 GB RAM / 6 vCPU / 77 GB SSD)
|
||||
**Objetivo:** Sistema instalado y funcionando con datos demo; análisis del sistema actual de SKEEN completado; roadmap de mejora definido.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Resumen de lo que funciona
|
||||
|
||||
| Componente | Estado | URL / Puerto | Notas |
|
||||
|------------|--------|--------------|-------|
|
||||
| Supabase self-hosted | ✅ | http://localhost:8000 (Kong), PostgreSQL :5433 | Contenedores Docker healthy. Datos persistentes en volúmenes Docker. |
|
||||
| WACRM | ✅ | http://localhost:3000 | Build Next.js 16 con endpoint `/api/v1/messages/simulate` para modo demo. |
|
||||
| Odoo 17 | ✅ | http://localhost:8069 | Datos demo y de migración importados. Nuevos modelos WACRM cachean conversaciones/mensajes/leads. |
|
||||
| Frontend React | ✅ | http://localhost:5173 / http://192.168.10.114/ | Diseño "SKEEN Brand". Menú WACRM con Mensajes y Leads. Build desplegado en nginx. |
|
||||
| Hermes Gateway | ✅ | API :8080 | Corriendo; bridge propio complementa la integración. |
|
||||
| Bridge Webhook SKEEN | ✅ | http://localhost:8090 | Recibe webhooks de WACRM, consulta Nan builders, responde como Sofía. |
|
||||
| Integración WACRM ↔ Hermes | ✅ | Via automatización `send_webhook` | Flujo end-to-end validado: mensaje de prueba → Sofía → respuesta en WACRM. |
|
||||
| Frontend ↔ Odoo | ✅ | Proxy Vite `/api/odoo` | Dashboard `medical` muestra stats reales. |
|
||||
| WACRM ↔ Odoo proxy | ✅ | `/skeen/frontend/v1/wacrm/*` | Odoo cachea contactos, conversaciones, mensajes y leads de Supabase. Frontend los consume. |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 URLs de acceso
|
||||
|
||||
Desde la VM:
|
||||
- WACRM: http://localhost:3000
|
||||
- Frontend: http://localhost:5173
|
||||
- Odoo: http://localhost:8069
|
||||
- Supabase Studio: http://localhost:8000/project/default
|
||||
- Bridge health: http://localhost:8090/health
|
||||
|
||||
Desde red externa (si los puertos están abiertos):
|
||||
- Reemplaza `localhost` por la IP pública de la VM.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Diseño de frontend
|
||||
|
||||
Se mantiene un único diseño oficial: **SKEEN Brand** (`/designs/brand`).
|
||||
|
||||
- Inspirado directamente en la identidad de marca de SKEEN.
|
||||
- Tipografía serif (Playfair Display), tonos stone/cálidos, hero con tagline, navegación redondeada, contacto visible.
|
||||
- La raíz (`/`) redirige automáticamente a `/designs/brand`.
|
||||
- Consume datos reales de Odoo vía el proxy `/api/odoo`.
|
||||
|
||||
Los otros 9 diseños experimentales fueron eliminados para enfocar el trabajo en una sola identidad visual.
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Flujo end-to-end validado
|
||||
|
||||
Se simuló un mensaje de WhatsApp entrante usando `/root/simular_meta_webhook.py` y también directamente al bridge:
|
||||
|
||||
1. Meta webhook simulado → `POST /api/whatsapp/webhook` (WACRM)
|
||||
2. WACRM crea contacto + conversación + mensaje `customer`
|
||||
3. WACRM dispara automatización `new_message_received`
|
||||
4. Automatización ejecuta `send_webhook` a `http://localhost:8090/webhook/wacrm`
|
||||
5. Bridge extrae `from`, `text`, `conversation_id`, `contact_id`
|
||||
6. Bridge consulta a Nan builders (`deepseek-v4-flash`) con el system prompt de Sofía
|
||||
7. Nan builders genera respuesta
|
||||
8. Bridge envía respuesta a WACRM `/api/v1/messages` → falla porque no hay token Meta
|
||||
9. Bridge hace fallback a `/api/v1/messages/simulate` → respuesta guardada en WACRM como mensaje `agent`
|
||||
|
||||
**Resultado:** la conversación en WACRM muestra mensaje del paciente + respuesta de Sofía.
|
||||
|
||||
## ✅ Ronda de pruebas recientes (5 jul 2026)
|
||||
|
||||
| Prueba | Resultado | Detalle |
|
||||
|--------|-----------|---------|
|
||||
| Build frontend (`npm run build`) | ✅ | CSS 56 kB, JS 816 kB, sin errores de Tailwind |
|
||||
| Linter (`npm run lint`) | ✅ | 0 warnings, 0 errors |
|
||||
| Odoo update módulos custom | ✅ | `skeen_pacientes`, `skeen_citas`, `skeen_monedero`, `skeen_pagos`, `skeen_whatsapp` actualizados |
|
||||
| Odoo endpoints | ✅ | `/health`, `/dashboard`, `/appointments`, `/patients`, `/wallets`, `/services`, `/weekly_chart` responden |
|
||||
| Frontend proxy a Odoo | ✅ | `/api/odoo/skeen/frontend/v1/health` responde vía Vite proxy |
|
||||
| 10 diseños cargan | ✅ | Diseño "brand" responde HTTP 200; los otros 9 fueron eliminados |
|
||||
| Bridge webhook | ✅ | `POST /webhook/wacrm` responde con respuesta de Sofía |
|
||||
| WACRM app | ✅ | Responde en `:3000`, modo demo con simulate endpoint |
|
||||
| Supabase self-hosted | ✅ | Todos los contenedores healthy |
|
||||
|
||||
## 🔧 Cambios técnicos recientes en Odoo
|
||||
|
||||
- **WACRM proxy en Odoo**: se agregaron modelos `skeen.wacrm.*` y controladores REST en `skeen_whatsapp/controllers/wacrm_proxy.py` para sincronizar contactos, conversaciones, mensajes, pipelines, stages y deals desde Supabase hacia Odoo.
|
||||
- **Menú WACRM en frontend**: nuevas páginas `/wacrm/messages` y `/wacrm/leads` con sincronización manual y visualización de datos.
|
||||
- **Script de migración mejorado**: `/root/migracion/importar_a_odoo.py` ahora importa pacientes, servicios, productos, médicos, citas, ventas, pagos, adeudos y monederos desde CSVs.
|
||||
- **Variables de entorno Supabase**: `skeen-start-all.sh` exporta `SUPABASE_URL` y `SUPABASE_SERVICE_ROLE_KEY` para que Odoo pueda leer WACRM directamente.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Cómo iniciar / detener todo
|
||||
|
||||
```bash
|
||||
# Iniciar todo
|
||||
/root/skeen-start-all.sh
|
||||
|
||||
# Detener todo
|
||||
/root/skeen-stop-all.sh
|
||||
```
|
||||
|
||||
Esperar ~20-30 segundos después de iniciar. Verificar puertos:
|
||||
```bash
|
||||
ss -tlnp | grep -E "3000|5173|8069|8000|8090|8644|8080"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Archivos clave modificados/creados
|
||||
|
||||
| Ruta | Propósito |
|
||||
|------|-----------|
|
||||
| `/root/ANALISIS_SKEEN_SISTEMA.md` | Análisis completo del sistema actual https://sistema.skeenmx.app/ |
|
||||
| `/root/ROADMAP_SKEEN_MEJORA.md` | Roadmap para replicar/mejorar el sistema actual en Odoo + WACRM + Frontend + Hermes |
|
||||
| `/root/skeen-frontend/src/App.tsx` | Rutas simplificadas: solo diseño SKEEN Brand, `/` redirige a `/designs/brand`. |
|
||||
| `/root/skeen-frontend/src/designs/brand/Dashboard.tsx` | Único diseño oficial del frontend. |
|
||||
| `/root/skeen-frontend/vite.config.ts` | Plugin `@tailwindcss/vite` configurado. |
|
||||
| `/root/skeen-odoo/addons/skeen_monedero/models/res_partner.py` | Campos `wallet_points` y `monedero_ids` en el módulo correcto. |
|
||||
| `/root/skeen-odoo/addons/skeen_citas/models/cita.py` | Campo `time_str` compute. |
|
||||
| `/root/skeen-odoo/addons/skeen_*/security/ir.model.access.csv` | Permisos de acceso completados. |
|
||||
| `/root/skeen-odoo/addons/skeen_whatsapp/controllers/wacrm_proxy.py` | Proxy/caché WACRM ↔ Odoo. |
|
||||
| `/root/skeen-odoo/addons/skeen_whatsapp/models/wacrm_sync.py` | Modelos Odoo para cachear datos de WACRM. |
|
||||
| `/root/skeen-frontend/src/pages/WacrmMessages.tsx` | Página de conversaciones/mensajes de WACRM. |
|
||||
| `/root/skeen-frontend/src/pages/WacrmLeads.tsx` | Página de leads/deals de WACRM. |
|
||||
| `/root/migracion/importar_a_odoo.py` | Script de migración CSV → Odoo. |
|
||||
| `/root/migracion/README.md` | Instrucciones y formatos de migración. |
|
||||
| `/root/skeen-start-all.sh` | Inicia todo el ecosistema (con env vars de Supabase). |
|
||||
| `/root/skeen-stop-all.sh` | Detiene todo el ecosistema. |
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Datos del cliente pendientes por conectar
|
||||
|
||||
Cuando SKEEN entregue estos datos, se conectan en los siguientes lugares:
|
||||
|
||||
| Dato | Dónde se usa | Archivo / UI |
|
||||
|------|--------------|--------------|
|
||||
| Número WhatsApp Business verificado | Meta Developers + WACRM | WACRM Settings → WhatsApp |
|
||||
| Meta App ID + App Secret | WACRM webhook signature | `/root/skeen-wacrm/.env.local` (`META_APP_SECRET`) |
|
||||
| Meta Access Token + WABA ID + Phone Number ID | Envío/recepción WhatsApp | WACRM Settings → WhatsApp |
|
||||
| Templates de WhatsApp aprobados | Automatizaciones y campañas | WACRM + Meta Business Manager |
|
||||
| Lista de servicios y precios | Skill de catálogo + Odoo | `/root/skeen-roadmap-hermes/hermes/webhook-bridge.js` (SKEEN_SYSTEM_PROMPT) y Odoo `product.template` |
|
||||
| Horarios de atención | Agendamiento | Skill `skeen-agendar` (a crear) + Odoo `skeen_citas` |
|
||||
| Stripe / MercadoPago keys | Pagos | Odoo módulo `skeen_pagos` y skill `skeen-pagos` |
|
||||
| Dominio skeen.mx | DNS + Nginx | Aún no configurado; actualmente todo en localhost |
|
||||
| Logo / branding | WACRM fork + frontend | `/root/skeen-wacrm` y `/root/skeen-frontend` |
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Notas técnicas importantes
|
||||
|
||||
1. **Modo demo / Meta no conectado**
|
||||
- Como no hay tokens reales de Meta, WACRM no puede enviar mensajes reales por WhatsApp.
|
||||
- Se creó el endpoint `/api/v1/messages/simulate` para que el flujo end-to-end funcione en demo.
|
||||
- Cuando Meta se conecte, el bridge usará automáticamente `/api/v1/messages` real; el fallback solo se activa ante errores de Meta.
|
||||
|
||||
2. **API key de WACRM**
|
||||
- Creada en Supabase tabla `api_keys` con scopes: `messages:send`, `messages:read`, `contacts:read`, `contacts:write`, `conversations:read`, `broadcasts:send`, `webhooks:manage`.
|
||||
- El bridge la lee de `WACRM_API_KEY` (ver `/root/skeen-roadmap-hermes/hermes/webhook-bridge.js`).
|
||||
|
||||
3. **Automatización en WACRM**
|
||||
- Nombre: "Nuevo mensaje → Webhook Hermes Bridge"
|
||||
- Trigger: `new_message_received`
|
||||
- Step: `send_webhook` a `http://localhost:8090/webhook/wacrm`
|
||||
- Body template: `{"from":"{{ vars.contact_phone }}","text":"{{ message.text }}","conversation_id":"{{ vars.conversation_id }}","contact_id":"{{ vars.contact_id }}"}`
|
||||
|
||||
4. **Supabase self-hosted**
|
||||
- PostgreSQL expuesto en puerto `5433` (no el 5432 directo).
|
||||
- Para conectar `psql` desde fuera del contenedor usar el puerto 5433 con `external_id` o conectarse por `docker exec supabase-db psql -U postgres -d postgres`.
|
||||
|
||||
5. **Hermes vs OpenClaw / Bridge actual**
|
||||
- El roadmap original usaba OpenClaw; se sustituyó por Hermes (`https://api.nan.builders/v1`).
|
||||
- El chat nativo de Hermes no se configuró; en su lugar el bridge llama directamente a la API REST de nan.builders para generar respuestas de Sofía.
|
||||
- Los skills de Hermes (`skeen-rag`, `skeen-agendar`, etc.) están creados en `/root/skeen-roadmap-hermes/hermes/skills/` y se activarán cuando el gateway de Hermes se integre formalmente como receptor de webhooks.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Próximos pasos sugeridos
|
||||
|
||||
Ahora que se completó el análisis del sistema actual, el trabajo se enfoca en replicar y mejorar cada sección. Ver el roadmap completo en `/root/ROADMAP_SKEEN_MEJORA.md`.
|
||||
|
||||
1. **Migración de datos maestros (FASE 0)** — *listo para ejecutar*
|
||||
- SKEEN debe proporcionar exportación autorizada de su sistema actual.
|
||||
- Colocar CSVs en `/root/migracion/datos/` y ejecutar `python3 /root/migracion/importar_a_odoo.py`.
|
||||
|
||||
2. **Frontend fiel al sistema actual (FASE 1)**
|
||||
- El menú WACRM ya está operativo. Siguiente: replicar secciones restantes del sistema legacy (visitas, expedientes médicos, catálogos, reportes).
|
||||
|
||||
3. **Conexión Odoo ↔ Frontend (FASE 2)**
|
||||
- Extender endpoints REST de Odoo para todas las secciones.
|
||||
- Crear cliente API en React y conectar cada pantalla.
|
||||
|
||||
4. **WhatsApp + WACRM + Hermes (FASE 3)**
|
||||
- Conectar número de WhatsApp Business de SKEEN.
|
||||
- Configurar automatizaciones, skills de Hermes, templates de Meta.
|
||||
- Habilitar inbox multi-agente y handoff a humano.
|
||||
|
||||
5. **Reportes, analytics y go-live (FASES 4-5)**
|
||||
- Dashboards con Recharts, metas de ventas, exportaciones.
|
||||
- Dominios SSL, backups, capacitación y go-live gradual.
|
||||
|
||||
---
|
||||
|
||||
## 📞 Comandos útiles
|
||||
|
||||
```bash
|
||||
# Ver todos los servicios
|
||||
ss -tlnp | grep -E "3000|5173|8069|8000|8090|8644|8080|5433|6379"
|
||||
|
||||
# Logs en tiempo real
|
||||
tail -f /tmp/wacrm.log
|
||||
tail -f /tmp/hermes-bridge.log
|
||||
tail -f /tmp/odoo.log
|
||||
tail -f /tmp/frontend.log
|
||||
tail -f /tmp/hermes-gateway.log
|
||||
|
||||
# Simular mensaje de WhatsApp entrante
|
||||
python3 /root/simular_meta_webhook.py
|
||||
|
||||
# Estado de contenedores Supabase
|
||||
cd /root/skeen-supabase/docker && docker compose ps
|
||||
|
||||
# Acceder a PostgreSQL de Supabase
|
||||
docker exec supabase-db psql -U postgres -d postgres
|
||||
|
||||
# Recompilar WACRM tras cambios
|
||||
cd /root/skeen-wacrm && npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✉️ Handoff
|
||||
|
||||
El sistema está instalado y funcionando. Se completó:
|
||||
|
||||
- ✅ Menú WACRM en el frontend (Mensajes y Leads) con sincronización manual desde Supabase.
|
||||
- ✅ Modelos y endpoints proxy en Odoo para cachear contactos, conversaciones, mensajes, pipelines, stages y deals de WACRM.
|
||||
- ✅ Script de migración mejorado (`/root/migracion/importar_a_odoo.py`) probado con datos de ejemplo.
|
||||
- ✅ Frontend desplegado en nginx (`http://192.168.10.114/`).
|
||||
- ✅ Odoo actualizado y corriendo con variables de entorno de Supabase.
|
||||
|
||||
**Bloqueo ético/legal:** no se realizó extracción masiva de datos desde `https://sistema.skeenmx.app/` porque requiere autorización documentada del cliente. El script de migración está listo para ejecutarse tan pronto como SKEEN entregue una exportación autorizada (CSVs o dump SQL).
|
||||
|
||||
Próximo paso prioritario: que SKEEN proporcione exportación autorizada de pacientes, citas, historial, ventas, pagos y monederos para ejecutar la migración real.
|
||||
|
||||
Para cualquier duda, revisar los logs, `/root/ANALISIS_SKEEN_SISTEMA.md` y `/root/ROADMAP_SKEEN_MEJORA.md`.
|
||||
167
docs/ROADMAP_SKEEN_MEJORA.md
Normal file
167
docs/ROADMAP_SKEEN_MEJORA.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Roadmap de Mejora — SKEEN Derma Experts
|
||||
## Unificación: Odoo 17 + WACRM + Frontend React + Hermes
|
||||
|
||||
**Fecha:** 6 de julio de 2026
|
||||
**Base del análisis:** Sistema actual https://sistema.skeenmx.app/ (Laravel + AdminLTE)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo general
|
||||
|
||||
Replicar y mejorar toda la funcionalidad del sistema actual de SKEEN en una nueva arquitectura unificada:
|
||||
|
||||
- **Odoo 17** como ERP/ backend maestro (pacientes, expedientes, citas, ventas, pagos, inventarios, contabilidad).
|
||||
- **WACRM** como CRM WhatsApp + shared inbox + automatizaciones.
|
||||
- **Hermes** como agente IA (Sofía) para atención automática, agendamiento, pagos, recordatorios.
|
||||
- **Frontend React 19 + Tailwind CSS** como interfaz moderna, replicando la identidad visual y los flujos del sistema actual.
|
||||
|
||||
---
|
||||
|
||||
## Fases del roadmap
|
||||
|
||||
### FASE 0: Fundamentos y migración de datos (1 semana)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
|---|-------|------------|
|
||||
| 0.1 | Exportar datos maestros del sistema Laravel | CSV/Excel de pacientes, servicios, productos, médicos, usuarios, citas, ventas, adeudos, monederos |
|
||||
| 0.2 | Definir mapeo de datos Laravel → Odoo | Documento de migración |
|
||||
| 0.3 | Cargar pacientes en Odoo (`res.partner`) | Pacientes en Odoo con teléfono, email, etiquetas, médico principal |
|
||||
| 0.4 | Cargar servicios y productos | `skeen.servicio` + `product.template` |
|
||||
| 0.5 | Cargar médicos, cosmetólogos y usuarios | `hr.employee` / `res.users` |
|
||||
| 0.6 | Cargar saldos de monedero | `skeen.monedero` |
|
||||
| 0.7 | Cargar adeudos históricos | `account.move` en estado posted |
|
||||
|
||||
---
|
||||
|
||||
### FASE 1: Frontend fiel al sistema actual (2 semanas)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
|---|-------|------------|
|
||||
| 1.1 | Crear tema "SKEEN Classic" en el frontend | Layout con sidebar + header superior + contenido central, colores `#1abc9c`, `#BED4AD`, `#34495e` |
|
||||
| 1.2 | Implementar login con logo SKEEN | Pantalla de login estilo sistema actual |
|
||||
| 1.3 | Replicar menú de navegación completo | Sidebar con grupos: principal, configuración, reportes, administrativo, monedero, comunicación, consumibles, CRM, ventas |
|
||||
| 1.4 | Dashboard / Movimientos diarios | Totales por forma de pago, tabla de ventas del día, filtros por médico/sucursal |
|
||||
| 1.5 | Agenda | Calendario/semana con citas, filtros, estados, acciones |
|
||||
| 1.6 | Expedientes | Lista con filtros VIP/visitas, ficha del paciente |
|
||||
| 1.7 | Catálogos (servicios, productos, diagnósticos, procedimientos, recetas, etiquetas) | CRUD completo |
|
||||
| 1.8 | Médicos, cosmetólogos, usuarios | Directorio con roles y permisos |
|
||||
| 1.9 | Inventarios | Productos + consumibles con niveles de stock |
|
||||
| 1.10 | Monedero | Configuración de % y reporte de puntos |
|
||||
| 1.11 | Reportes administrativos | Adeudos, pagos, visitas, devoluciones, comisiones, concentrado, top clientes, paquetes |
|
||||
| 1.12 | Cortes de caja | Histórico diario, establecer corte |
|
||||
| 1.13 | Tipo de cambio | Pantalla de configuración USD/MXN |
|
||||
| 1.14 | Comunicación / Cumpleañeros | Lista de pacientes cumpleañeros |
|
||||
|
||||
---
|
||||
|
||||
### FASE 2: Conexión Odoo ↔ Frontend (1 semana)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
| 2.1 | Extender controladores Odoo (`skeen_whatsapp/controllers/frontend.py`) | Endpoints REST para todas las secciones |
|
||||
| 2.2 | Crear servicios en React (`services/skeenApi.ts`) | Cliente tipado para todos los endpoints |
|
||||
| 2.3 | Conectar dashboard con datos reales | Stats y ventas del día desde Odoo |
|
||||
| 2.4 | Conectar agenda, expedientes, catálogos | CRUD funcional end-to-end |
|
||||
| 2.5 | Autenticación frontend ↔ Odoo | Login validado contra Odoo o token JWT |
|
||||
| 2.6 | Manejo de permisos por rol | Ocultar/mostrar secciones según rol |
|
||||
|
||||
---
|
||||
|
||||
### FASE 3: WhatsApp + WACRM + Hermes (2 semanas)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
|---|-------|------------|
|
||||
| 3.1 | Conectar número de WhatsApp Business de SKEEN en WACRM | WACRM enviando/recibiendo mensajes reales |
|
||||
| 3.2 | Configurar automatizaciones en WACRM | Nuevo mensaje → webhook → Hermes bridge |
|
||||
| 3.3 | Entrenar a Sofía con el catálogo real | Skill `skeen-rag` con servicios/precios de SKEEN |
|
||||
| 3.4 | Skill de agendamiento con Odoo | `skeen-agendar` consulta disponibilidad y crea citas |
|
||||
| 3.5 | Skill de pagos | `skeen-pagos` genera links Stripe/MP |
|
||||
| 3.6 | Skill de monedero | `skeen-monedero` consulta saldo y redime puntos |
|
||||
| 3.7 | Skill de recordatorios | `skeen-recordatorios` vía cron cada 30 min |
|
||||
| 3.8 | Templates de Meta aprobados | Bienvenida, confirmación cita, recordatorio, follow-up, re-engage |
|
||||
| 3.9 | WACRM inbox para equipo SKEEN | Recepcionistas y médicos con acceso |
|
||||
| 3.10 | Handoff a humano | Trigger "AGENTE"/"HUMANO" en WhatsApp |
|
||||
|
||||
---
|
||||
|
||||
### FASE 4: Reportes, analytics y mejoras UX (1 semana)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
| 4.1 | Dashboards interactivos con Recharts | Ingresos, visitas, top servicios, conversiones |
|
||||
| 4.2 | Meta de ventas en header | Progress bar igual al sistema actual |
|
||||
| 4.3 | Filtros avanzados en tablas | DataTables-like con búsqueda, ordenamiento, exportación |
|
||||
| 4.4 | Exportar a Excel/PDF | Botones de exportación en reportes |
|
||||
| 4.5 | Chat interno | Mensajería entre usuarios (opcional, puede usarse WACRM) |
|
||||
| 4.6 | Notas internas en pacientes | Igual al sistema actual |
|
||||
| 4.7 | Modales rápidos | Valoración Express, cancelar venta, devolución, paquete terminado |
|
||||
|
||||
---
|
||||
|
||||
### FASE 5: Migración final, testing y go-live (1 semana)
|
||||
|
||||
| # | Tarea | Entregable |
|
||||
| 5.1 | Migración completa de datos históricos | Odoo con datos reales de SKEEN |
|
||||
| 5.2 | Testing de todos los flujos | Documento de pruebas firmado |
|
||||
| 5.3 | Capacitación del equipo | Sesiones con recepción, médicos, administración |
|
||||
| 5.4 | Configurar dominios y SSL | `crm.skeen.mx`, `erp.skeen.mx`, `app.skeen.mx` |
|
||||
| 5.5 | Monitoreo y backups | Uptime Kuma + dumps diarios |
|
||||
| 5.6 | Go-live gradual | Soft launch + soporte presencial/remoto |
|
||||
|
||||
---
|
||||
|
||||
## Arquitectura objetivo
|
||||
|
||||
```
|
||||
Paciente → WhatsApp → Meta Cloud API → WACRM
|
||||
↓ (webhook)
|
||||
Hermes Bridge
|
||||
↓
|
||||
Hermes Gateway (Sofía)
|
||||
↓
|
||||
Odoo 17 (ERP maestro)
|
||||
↗ ↖
|
||||
Frontend React Supabase Auth/Storage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stack tecnológico final
|
||||
|
||||
| Capa | Tecnología |
|
||||
|------|-----------|
|
||||
| Backend ERP | Odoo 17 Community + módulos custom |
|
||||
| CRM WhatsApp | WACRM (fork propio) |
|
||||
| Agente IA | Hermes / Nan builders API |
|
||||
| Frontend | React 19 + TypeScript + Tailwind CSS + Vite |
|
||||
| Base de datos | PostgreSQL (Odoo) + Supabase PostgreSQL (WACRM) |
|
||||
| Auth | Supabase Auth para WACRM; Odoo para backend |
|
||||
| Charts | Recharts |
|
||||
| Tablas | TanStack Table |
|
||||
| Deploy | Docker Compose + Nginx + Let's Encrypt |
|
||||
|
||||
---
|
||||
|
||||
## Priorización MVP
|
||||
|
||||
Para el go-live mínimo viable, se deben tener listas estas 5 áreas:
|
||||
|
||||
1. **Pacientes + Expedientes** (Odoo + Frontend)
|
||||
2. **Agenda + Citas** (Odoo + Frontend + recordatorios por WhatsApp)
|
||||
3. **Ventas + Pagos + Monedero** (Odoo + Frontend + Hermes)
|
||||
4. **WhatsApp con Sofía** (WACRM + Hermes)
|
||||
5. **Dashboard de ingresos y cortes de caja**
|
||||
|
||||
Las demás secciones (consumibles, reportes avanzados, CRM pipelines, comisiones) pueden activarse en iteraciones posteriores.
|
||||
|
||||
---
|
||||
|
||||
## Métricas de éxito
|
||||
|
||||
- Todos los usuarios del sistema actual pueden realizar sus tareas diarias en el nuevo sistema.
|
||||
- Reducción de no-shows ≥ 30% gracias a recordatorios automáticos.
|
||||
- Tiempo de atención a prospectos por WhatsApp reducido con Sofía 24/7.
|
||||
- Datos históricos accesibles y consultables en Odoo.
|
||||
- Cero dependencia del sistema Laravel legacy para operaciones diarias.
|
||||
|
||||
---
|
||||
|
||||
*Roadmap basado en el análisis de https://sistema.skeenmx.app/ sin realizar modificaciones.*
|
||||
738
docs/api.md
Normal file
738
docs/api.md
Normal file
@@ -0,0 +1,738 @@
|
||||
# API Reference — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Introducción
|
||||
|
||||
Esta documentación describe todos los endpoints REST expuestos por el sistema SKEEN. Los endpoints están organizados por componente:
|
||||
|
||||
- **Odoo Frontend API** (`/skeen/frontend/v1/*`): Para el Frontend React.
|
||||
- **Odoo Hermes API** (`/skeen/api/v1/*`): Para Hermes/skills (JSON-RPC/XML-RPC).
|
||||
- **WACRM API** (`/api/v1/*`): Para WACRM público.
|
||||
- **Bridge API** (`:8090/*`): Para webhooks WACRM → Hermes.
|
||||
|
||||
---
|
||||
|
||||
## 2. Autenticación
|
||||
|
||||
### 2.1 Frontend API (JWT)
|
||||
|
||||
```bash
|
||||
# Login
|
||||
curl -X POST http://localhost:8069/skeen/frontend/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"login":"admin","password":"SkeenAdmin2026!"}'
|
||||
|
||||
# Respuesta
|
||||
{
|
||||
"status": "success",
|
||||
"token": "eyJ1aWQiOjEsImxvZ2luIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3ODQyMzI3NDV9...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"login": "admin",
|
||||
"name": "Administrador SKEEN",
|
||||
"role": "admin"
|
||||
}
|
||||
}
|
||||
|
||||
# Uso del token
|
||||
curl -H "Authorization: Bearer <token>" http://localhost:8069/skeen/frontend/v1/appointments
|
||||
```
|
||||
|
||||
### 2.2 Hermes API (API Key)
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8069/skeen/api/v1/available_slots \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer skeen_api_key_2026" \
|
||||
-d '{"service_id":1,"date_from":"2026-07-17","date_to":"2026-07-20"}'
|
||||
```
|
||||
|
||||
### 2.3 WACRM API (Bearer Token)
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/messages \
|
||||
-H "Authorization: Bearer wacrm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"to":"+526641234567","type":"text","text":"Hola"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Odoo Frontend API
|
||||
|
||||
### 3.1 Health
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/health
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"service": "skeen-frontend-api",
|
||||
"version": "1.1.0"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Auth
|
||||
|
||||
#### Login
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/auth/login
|
||||
```
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"login": "admin",
|
||||
"password": "SkeenAdmin2026!"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"token": "eyJ...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"login": "admin",
|
||||
"name": "Administrador SKEEN",
|
||||
"role": "admin",
|
||||
"must_change_password": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Me
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/auth/me
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Logout
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/auth/logout
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Listar Usuarios (admin)
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/auth/users
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Crear Usuario (admin)
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/auth/users
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"login": "recepcion1",
|
||||
"name": "Recepción 1",
|
||||
"password": "Password123!",
|
||||
"role": "recepcion"
|
||||
}
|
||||
```
|
||||
|
||||
#### Actualizar Usuario (admin)
|
||||
|
||||
```http
|
||||
PUT /skeen/frontend/v1/auth/users/<user_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.3 Citas
|
||||
|
||||
#### Listar Citas
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/appointments?page=1&page_size=50&date_from=2026-07-01&date_to=2026-07-31&state=confirmed&search=Nombre
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Parámetros de query:**
|
||||
- `page`: Número de página (default: 1)
|
||||
- `page_size`: Items por página (default: 50, max: 200)
|
||||
- `date_from`: Fecha inicio (YYYY-MM-DD)
|
||||
- `date_to`: Fecha fin (YYYY-MM-DD)
|
||||
- `state`: Estado (`pending`, `confirmed`, `arrived`, `in_progress`, `done`, `cancelled`, `no_show`)
|
||||
- `patient_id`: ID del paciente
|
||||
- `doctor_id`: ID del médico
|
||||
- `search`: Búsqueda por nombre, paciente o servicio
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"appointments": [
|
||||
{
|
||||
"id": 1,
|
||||
"reference": "CITA-001",
|
||||
"patient_id": 45044,
|
||||
"patient": "Negrete Ca Mou Cecile",
|
||||
"phone": "526634347178",
|
||||
"service_id": 1,
|
||||
"service": "Consulta Dermatologica",
|
||||
"service_category": "consulta",
|
||||
"date": "2026-07-17",
|
||||
"time": "10:00",
|
||||
"state": "pending",
|
||||
"payment_state": "not_paid",
|
||||
"price": 800.0,
|
||||
"doctor_id": null,
|
||||
"doctor": null,
|
||||
"branch": "rosarito",
|
||||
"medium": "onsite",
|
||||
"notes": "",
|
||||
"package_finished": false,
|
||||
"package_finished_date": null
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### Crear Cita
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/appointments
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"partner_id": 45044,
|
||||
"servicio_id": 1,
|
||||
"date": "2026-07-17",
|
||||
"time": 10.0,
|
||||
"sessions": 1,
|
||||
"branch": "rosarito",
|
||||
"medium": "onsite",
|
||||
"notes": "",
|
||||
"state": "pending"
|
||||
}
|
||||
```
|
||||
|
||||
**Campos:**
|
||||
- `partner_id` (required): ID del paciente
|
||||
- `servicio_id` (required): ID del servicio
|
||||
- `date` (required): Fecha (YYYY-MM-DD)
|
||||
- `time` (required): Hora en float (10.0 = 10:00, 10.5 = 10:30)
|
||||
- `sessions` (optional): Número de sesiones (default: 1). Si el servicio tiene `package_sessions > 0`, se usa ese valor por defecto.
|
||||
- `branch` (optional): `rosarito` o `tijuana`
|
||||
- `medium` (optional): `onsite` o `videocall`
|
||||
- `notes` (optional): Notas
|
||||
- `state` (optional): Estado inicial
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"appointment": { /* primera cita */ },
|
||||
"appointments": [ /* todas las citas creadas */ ],
|
||||
"sessions": 3
|
||||
}
|
||||
```
|
||||
|
||||
**Nota:** Si `sessions > 1`, se crean N citas separadas. La primera usa la fecha/hora proporcionada; las siguientes se programan cada 7 días a las 9:00 AM.
|
||||
|
||||
#### Obtener Cita
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/appointments/<appointment_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Actualizar Cita
|
||||
|
||||
```http
|
||||
PUT /skeen/frontend/v1/appointments/<appointment_id>
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"date": "2026-07-18",
|
||||
"time": 11.0,
|
||||
"state": "confirmed",
|
||||
"notes": "Paciente confirmó por teléfono"
|
||||
}
|
||||
```
|
||||
|
||||
#### Eliminar Cita
|
||||
|
||||
```http
|
||||
DELETE /skeen/frontend/v1/appointments/<appointment_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.4 Servicios
|
||||
|
||||
#### Listar Servicios
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/services
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"services": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "CONS-DERM",
|
||||
"name": "Consulta Dermatologica",
|
||||
"category": "consulta",
|
||||
"price": 800.0,
|
||||
"package_price": 0.0,
|
||||
"package_sessions": 0,
|
||||
"package_notes": "",
|
||||
"duration_min": 30,
|
||||
"description": "Evaluación completa...",
|
||||
"color": "#1abc9c",
|
||||
"service_group": "Consultas",
|
||||
"is_favorite": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Crear Servicio (admin)
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/services
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Peel Quimico",
|
||||
"code": "PEEL-QUI",
|
||||
"category": "tratamiento",
|
||||
"price": 1500.0,
|
||||
"duration_min": 30,
|
||||
"package_price": 4000.0,
|
||||
"package_sessions": 3,
|
||||
"package_notes": "Ahorro de $500",
|
||||
"description": "Exfoliación química...",
|
||||
"color": "#9b59b6",
|
||||
"service_group": "Faciales",
|
||||
"is_favorite": false
|
||||
}
|
||||
```
|
||||
|
||||
#### Actualizar Servicio (admin)
|
||||
|
||||
```http
|
||||
PUT /skeen/frontend/v1/services/<service_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.5 Pacientes
|
||||
|
||||
#### Listar Pacientes
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/patients?page=1&page_size=50&search=Nombre
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Crear Paciente
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/patients
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Juan Pérez",
|
||||
"phone": "526641234567",
|
||||
"email": "juan@example.com",
|
||||
"birthdate": "1990-01-15",
|
||||
"gender": "male",
|
||||
"blood_type": "O+",
|
||||
"allergies": "Penicilina",
|
||||
"notes": "Paciente nuevo"
|
||||
}
|
||||
```
|
||||
|
||||
#### Obtener Paciente
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/patients/<patient_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Actualizar Paciente
|
||||
|
||||
```http
|
||||
PUT /skeen/frontend/v1/patients/<patient_id>
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.6 Monedero
|
||||
|
||||
#### Listar Monederos
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/wallets
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"wallets": [
|
||||
{
|
||||
"id": 1,
|
||||
"patient_id": 45044,
|
||||
"patient": "Negrete Ca Mou Cecile",
|
||||
"points": 450,
|
||||
"equivalent_mxn": 450,
|
||||
"transactions": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.7 Ventas
|
||||
|
||||
#### Listar Ventas
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/sales?date_from=2026-07-01&date_to=2026-07-31
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Crear Venta
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/sales
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"partner_id": 45044,
|
||||
"lines": [
|
||||
{
|
||||
"service_id": 1,
|
||||
"qty": 1,
|
||||
"price_unit": 800.0
|
||||
}
|
||||
],
|
||||
"payment_method": "cash",
|
||||
"notes": ""
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.8 Inventario
|
||||
|
||||
#### Listar Inventario
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/inventory
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.9 WACRM Proxy
|
||||
|
||||
#### Listar Contactos
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/wacrm/contacts?page=1&page_size=50&search=Nombre
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Listar Conversaciones
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/wacrm/conversations?page=1&page_size=50
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Listar Mensajes
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/wacrm/messages?conversation_id=123
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Listar Deals
|
||||
|
||||
```http
|
||||
GET /skeen/frontend/v1/wacrm/deals
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Sincronizar WACRM → Odoo
|
||||
|
||||
```http
|
||||
POST /skeen/frontend/v1/wacrm/sync
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"sync_contacts": true,
|
||||
"sync_conversations": true,
|
||||
"sync_messages": true,
|
||||
"sync_deals": true
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Odoo Hermes API
|
||||
|
||||
Estos endpoints usan `type='json'` y `auth='api_key'`.
|
||||
|
||||
### 4.1 Slots Disponibles
|
||||
|
||||
```http
|
||||
POST /skeen/api/v1/available_slots
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <api_key>
|
||||
|
||||
{
|
||||
"service_id": 1,
|
||||
"date_from": "2026-07-17",
|
||||
"date_to": "2026-07-20"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"slots": [
|
||||
{
|
||||
"date": "2026-07-17",
|
||||
"time": "09:00",
|
||||
"datetime": "2026-07-17 09:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 Crear Cita
|
||||
|
||||
```http
|
||||
POST /skeen/api/v1/create_appointment
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <api_key>
|
||||
|
||||
{
|
||||
"phone": "526641234567",
|
||||
"name": "Juan Pérez",
|
||||
"service_id": 1,
|
||||
"date": "2026-07-17",
|
||||
"time": "10:00"
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 Saldo del Paciente
|
||||
|
||||
```http
|
||||
POST /skeen/api/v1/patient_balance
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <api_key>
|
||||
|
||||
{
|
||||
"phone": "526641234567"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"pending_balance": 1500.0,
|
||||
"pending_invoices": [
|
||||
{
|
||||
"amount_residual": 1500.0,
|
||||
"name": "INV/2026/0001"
|
||||
}
|
||||
],
|
||||
"wallet_points": 450,
|
||||
"wallet_mxn": 450
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 Redimir Puntos
|
||||
|
||||
```http
|
||||
POST /skeen/api/v1/wallet_redeem
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <api_key>
|
||||
|
||||
{
|
||||
"phone": "526641234567",
|
||||
"points": 200,
|
||||
"appointment_id": 123
|
||||
}
|
||||
```
|
||||
|
||||
### 4.5 Cancelar Cita
|
||||
|
||||
```http
|
||||
POST /skeen/api/v1/cancel_appointment
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <api_key>
|
||||
|
||||
{
|
||||
"phone": "526641234567",
|
||||
"booking_id": 123
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. WACRM API
|
||||
|
||||
### 5.1 Enviar Mensaje
|
||||
|
||||
```http
|
||||
POST /api/v1/messages
|
||||
Authorization: Bearer <api_key>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"to": "+526641234567",
|
||||
"type": "text",
|
||||
"text": "Hola, tu cita está confirmada"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 Simular Mensaje (Demo)
|
||||
|
||||
```http
|
||||
POST /api/v1/messages/simulate
|
||||
Authorization: Bearer <api_key>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"to": "+526641234567",
|
||||
"type": "text",
|
||||
"text": "Hola, tu cita está confirmada"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 Contactos
|
||||
|
||||
```http
|
||||
GET /api/v1/contacts
|
||||
Authorization: Bearer <api_key>
|
||||
```
|
||||
|
||||
### 5.4 Webhooks
|
||||
|
||||
```http
|
||||
POST /api/v1/webhooks
|
||||
Authorization: Bearer <api_key>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"url": "https://openclaw.skeen.mx/webhook/wacrm",
|
||||
"events": ["message.received", "message.status_updated"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Bridge API
|
||||
|
||||
### 6.1 Health
|
||||
|
||||
```http
|
||||
GET /health
|
||||
```
|
||||
|
||||
### 6.2 Webhook WACRM
|
||||
|
||||
```http
|
||||
POST /webhook/wacrm
|
||||
Content-Type: application/json
|
||||
X-WACRM-Signature: t=...,v1=...
|
||||
|
||||
{
|
||||
"from": "+526641234567",
|
||||
"text": "Hola, quiero agendar una cita",
|
||||
"conversation_id": "123",
|
||||
"contact_id": "456"
|
||||
}
|
||||
```
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"received": true,
|
||||
"response": "Hola! Soy Sofia de SKEEN. Claro, ¿qué servicio te interesa?"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Códigos de Error
|
||||
|
||||
| Código | Significado |
|
||||
|--------|-------------|
|
||||
| 200 | OK |
|
||||
| 201 | Creado |
|
||||
| 400 | Bad Request — parámetros inválidos |
|
||||
| 401 | Unauthorized — token inválido o faltante |
|
||||
| 403 | Forbidden — permisos insuficientes |
|
||||
| 404 | Not Found — recurso no encontrado |
|
||||
| 409 | Conflict — conflicto (ej. usuario ya existe) |
|
||||
| 500 | Internal Server Error |
|
||||
|
||||
**Formato de error:**
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"message": "Descripción del error"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Rate Limiting
|
||||
|
||||
Actualmente no hay rate limiting implementado. Se recomienda configurar:
|
||||
|
||||
- **nginx:** `limit_req_zone`
|
||||
- **WACRM:** Configurar en middleware
|
||||
- **Odoo:** Configurar en `ir.http`
|
||||
|
||||
---
|
||||
|
||||
## 9. Versionado
|
||||
|
||||
La API está en versión `1.1.0`. Los cambios se documentan en el changelog de cada módulo.
|
||||
324
docs/arquitectura.md
Normal file
324
docs/arquitectura.md
Normal file
@@ -0,0 +1,324 @@
|
||||
# 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)
|
||||
481
docs/configuracion.md
Normal file
481
docs/configuracion.md
Normal file
@@ -0,0 +1,481 @@
|
||||
# Configuración — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Variables de Entorno
|
||||
|
||||
### 1.1 Bridge SKEEN (`/root/skeen-roadmap-hermes/hermes/.env`)
|
||||
|
||||
```env
|
||||
# Nan Builders (IA)
|
||||
NAN_API_KEY=sk-gJ8OWbZVGeWy9ns_H00cxA
|
||||
NAN_BASE_URL=https://api.nan.builders/v1
|
||||
NAN_MODEL=qwen3.6
|
||||
|
||||
# WACRM
|
||||
WACRM_URL=http://localhost:3000
|
||||
WACRM_API_KEY=wacrm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
# Bridge
|
||||
BRIDGE_PORT=8090
|
||||
NODE_ENV=production
|
||||
```
|
||||
|
||||
### 1.2 WACRM (`/root/skeen-wacrm/.env.local`)
|
||||
|
||||
```env
|
||||
# Supabase (self-hosted on localhost)
|
||||
NEXT_PUBLIC_SUPABASE_URL=http://localhost:8000
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDB9.pnl22qqc0WMyNRwqdXq7cEq1hw_YTrdTgWHd0TPsHPU
|
||||
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE2NDE3NjkyMDAsImV4cCI6MTc5OTUzNTYwMH0.XA05Pgn-gkEKaZEaHYFc9DAyP45uNJdsl8DL9axUxbc
|
||||
|
||||
# Encryption key for WACRM (64 hex chars)
|
||||
ENCRYPTION_KEY=8bbf201d9d60488a1e86e5396b31e22d8bbf201d9d60488a1e86e5396b31e22d
|
||||
|
||||
# WhatsApp / Meta (pending client data)
|
||||
WHATSAPP_PHONE_NUMBER_ID=PENDING_PHONE_ID
|
||||
WHATSAPP_BUSINESS_ACCOUNT_ID=PENDING_WABA_ID
|
||||
WHATSAPP_ACCESS_TOKEN=PENDING_TOKEN
|
||||
WHATSAPP_VERIFY_TOKEN=skeen_webhook_verify_2026
|
||||
|
||||
# Meta App Secret for webhook signature verification
|
||||
META_APP_SECRET=skeen_meta_app_secret_2026_demo
|
||||
|
||||
# Application
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||
NODE_ENV=production
|
||||
```
|
||||
|
||||
### 1.3 Odoo (`/root/skeen-odoo/odoo.conf`)
|
||||
|
||||
```ini
|
||||
[options]
|
||||
addons_path = /root/skeen-odoo/addons,/root/skeen-odoo/odoo/addons
|
||||
admin_passwd = skeen_admin_2026
|
||||
csv_internal_sep = ,
|
||||
data_dir = /var/lib/odoo
|
||||
db_host = localhost
|
||||
db_maxconn = 64
|
||||
db_name = skeen_odoo
|
||||
db_password = skeen_dev_2026
|
||||
db_port = 5432
|
||||
db_sslmode = prefer
|
||||
db_user = skeen
|
||||
demo = {}
|
||||
email_from = False
|
||||
geoip_database = /usr/share/GeoIP/GeoLite2-City.mmdb
|
||||
http_enable = True
|
||||
http_interface =
|
||||
http_port = 8069
|
||||
import_partial =
|
||||
limit_memory_hard = 2684354560
|
||||
limit_memory_soft = 2147483648
|
||||
limit_request = 8192
|
||||
limit_time_cpu = 60
|
||||
limit_time_real = 120
|
||||
limit_time_real_cron = -1
|
||||
list_db = True
|
||||
log_db = False
|
||||
log_db_level = warning
|
||||
log_handler = :INFO
|
||||
log_level = info
|
||||
logfile =
|
||||
longpolling_port = 8072
|
||||
max_cron_threads = 2
|
||||
osv_memory_age_limit = False
|
||||
osv_memory_count_limit = False
|
||||
pg_path =
|
||||
pidfile =
|
||||
proxy_mode = True
|
||||
reportgz = False
|
||||
screencasts =
|
||||
screenshots = /tmp/odoo_screenshots
|
||||
server_wide_modules = base,web
|
||||
smtp_password = False
|
||||
smtp_port = 25
|
||||
smtp_server = localhost
|
||||
smtp_ssl = False
|
||||
smtp_ssl_certificate_filename = False
|
||||
smtp_ssl_private_key_filename = False
|
||||
smtp_user = False
|
||||
test_file =
|
||||
test_tags = None
|
||||
translate_modules = ['all']
|
||||
unaccent = False
|
||||
upgrade_path =
|
||||
without_demo = False
|
||||
workers = 0
|
||||
```
|
||||
|
||||
### 1.4 Scripts de Inicio (`/root/skeen-start-all.sh`)
|
||||
|
||||
```bash
|
||||
export SUPABASE_URL="http://localhost:8000"
|
||||
export SUPABASE_SERVICE_ROLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIiwiaXNzIjoic3VwYWJhc2UiLCJpYXQiOjE2NDE3NjkyMDAsImV4cCI6MTc5OTUzNTYwMH0.XA05Pgn-gkEKaZEaHYFc9DAyP45uNJdsl8DL9axUxbc"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Credenciales y Accesos
|
||||
|
||||
| Servicio | URL | Usuario | Contraseña | Notas |
|
||||
|----------|-----|---------|------------|-------|
|
||||
| Odoo | http://localhost:8069 | admin | skeen_admin_2026 | DB: skeen_odoo |
|
||||
| Frontend | http://localhost:5173 | admin | SkeenAdmin2026! | Usuario seed |
|
||||
| WACRM | http://localhost:3000 | ivan@horuxfin.com | (definida por usuario) | Registro manual |
|
||||
| Supabase Studio | http://localhost:8000 | supabase | (definida en .env) | Dashboard |
|
||||
| PostgreSQL Odoo | localhost:5432 | skeen | skeen_dev_2026 | DB: skeen_odoo |
|
||||
| PostgreSQL Supabase | localhost:5433 | postgres | (definida en .env) | Docker |
|
||||
|
||||
---
|
||||
|
||||
## 3. Endpoints Importantes
|
||||
|
||||
### 3.1 Odoo REST API (`skeen_whatsapp`)
|
||||
|
||||
| Endpoint | Método | Descripción | Auth |
|
||||
|----------|--------|-------------|------|
|
||||
| `/skeen/api/v1/available_slots` | POST | Slots disponibles | API Key |
|
||||
| `/skeen/api/v1/create_appointment` | POST | Crear cita | API Key |
|
||||
| `/skeen/api/v1/patient_balance` | POST | Saldo paciente | API Key |
|
||||
| `/skeen/api/v1/wallet_redeem` | POST | Redimir puntos | API Key |
|
||||
| `/skeen/api/v1/cancel_appointment` | POST | Cancelar cita | API Key |
|
||||
|
||||
### 3.2 Odoo Frontend API (`skeen/frontend/v1/*`)
|
||||
|
||||
| Endpoint | Método | Descripción | Auth |
|
||||
|----------|--------|-------------|------|
|
||||
| `/skeen/frontend/v1/health` | GET | Health check | None |
|
||||
| `/skeen/frontend/v1/auth/login` | POST | Login | None |
|
||||
| `/skeen/frontend/v1/auth/me` | GET | Usuario actual | JWT |
|
||||
| `/skeen/frontend/v1/appointments` | GET/POST | Citas | JWT |
|
||||
| `/skeen/frontend/v1/appointments/<id>` | GET/PUT/DELETE | Cita individual | JWT |
|
||||
| `/skeen/frontend/v1/services` | GET/POST | Servicios | JWT |
|
||||
| `/skeen/frontend/v1/services/<id>` | PUT | Actualizar servicio | JWT |
|
||||
| `/skeen/frontend/v1/patients` | GET/POST | Pacientes | JWT |
|
||||
| `/skeen/frontend/v1/patients/<id>` | GET/PUT | Paciente individual | JWT |
|
||||
| `/skeen/frontend/v1/wallets` | GET | Monederos | JWT |
|
||||
| `/skeen/frontend/v1/sales` | GET/POST | Ventas | JWT |
|
||||
| `/skeen/frontend/v1/inventory` | GET | Inventario | JWT |
|
||||
| `/skeen/frontend/v1/wacrm/contacts` | GET | Contactos WACRM | JWT |
|
||||
| `/skeen/frontend/v1/wacrm/conversations` | GET | Conversaciones WACRM | JWT |
|
||||
| `/skeen/frontend/v1/wacrm/messages` | GET | Mensajes WACRM | JWT |
|
||||
| `/skeen/frontend/v1/wacrm/deals` | GET | Deals WACRM | JWT |
|
||||
| `/skeen/frontend/v1/wacrm/sync` | POST | Sincronizar WACRM→Odoo | JWT |
|
||||
|
||||
### 3.3 WACRM API (`/api/v1/*`)
|
||||
|
||||
| Endpoint | Método | Descripción | Auth |
|
||||
|----------|--------|-------------|------|
|
||||
| `/api/v1/messages` | POST | Enviar mensaje | Bearer Token |
|
||||
| `/api/v1/messages/simulate` | POST | Simular mensaje (demo) | Bearer Token |
|
||||
| `/api/v1/contacts` | GET/POST | Contactos | Bearer Token |
|
||||
| `/api/v1/conversations` | GET | Conversaciones | Bearer Token |
|
||||
| `/api/v1/webhooks` | GET/POST | Webhooks | Bearer Token |
|
||||
| `/api/whatsapp/webhook` | POST | Webhook Meta | Verify Token |
|
||||
|
||||
### 3.4 Bridge SKEEN (`:8090`)
|
||||
|
||||
| Endpoint | Método | Descripción |
|
||||
|----------|--------|-------------|
|
||||
| `/health` | GET | Health check |
|
||||
| `/webhook/wacrm` | POST | Webhook WACRM → Hermes |
|
||||
|
||||
---
|
||||
|
||||
## 4. Configuración de Hermes
|
||||
|
||||
### 4.1 Gateway
|
||||
|
||||
```bash
|
||||
# Ver estado
|
||||
hermes gateway status
|
||||
|
||||
# Iniciar
|
||||
hermes gateway run
|
||||
|
||||
# Instalar como servicio
|
||||
hermes gateway install
|
||||
sudo hermes gateway install --system
|
||||
```
|
||||
|
||||
### 4.2 Serve (Dashboard/API)
|
||||
|
||||
```bash
|
||||
hermes serve --host 0.0.0.0 --port 9119 --skip-build
|
||||
```
|
||||
|
||||
### 4.3 Skills Instalados
|
||||
|
||||
```bash
|
||||
hermes skills list
|
||||
```
|
||||
|
||||
Skills disponibles:
|
||||
- `skeen-rag`
|
||||
- `skeen-agendar`
|
||||
- `skeen-pagos`
|
||||
- `skeen-monedero`
|
||||
- `skeen-recordatorios`
|
||||
|
||||
---
|
||||
|
||||
## 5. Configuración de Meta WhatsApp Cloud API
|
||||
|
||||
### 5.1 Crear App en Meta Developers
|
||||
|
||||
1. Ir a https://developers.facebook.com
|
||||
2. Crear app tipo "Business"
|
||||
3. Agregar producto "WhatsApp"
|
||||
4. Obtener:
|
||||
- Phone Number ID
|
||||
- WhatsApp Business Account ID (WABA ID)
|
||||
- Access Token (permanente, System User)
|
||||
- App Secret
|
||||
|
||||
### 5.2 Configurar Webhook en Meta
|
||||
|
||||
| Campo | Valor |
|
||||
|-------|-------|
|
||||
| Callback URL | `https://crm.skeen.mx/api/whatsapp/webhook` |
|
||||
| Verify Token | `skeen_webhook_verify_2026` |
|
||||
| Subscription fields | `messages`, `message_template_status_update` |
|
||||
|
||||
### 5.3 Configurar WACRM
|
||||
|
||||
En WACRM Dashboard → Settings → WhatsApp:
|
||||
|
||||
| Campo | Valor |
|
||||
|-------|-------|
|
||||
| Phone Number ID | De Meta Developers |
|
||||
| Access Token | Token permanente |
|
||||
| Business Account ID | WABA ID |
|
||||
| Verify Token | `skeen_webhook_verify_2026` |
|
||||
|
||||
### 5.4 Templates de WhatsApp
|
||||
|
||||
Templates a subir y aprobar en Meta Business Manager:
|
||||
|
||||
| Template | Categoría | Uso |
|
||||
|----------|-----------|-----|
|
||||
| `bienvenida_skeen` | UTILITY | Primer contacto |
|
||||
| `confirmacion_cita` | UTILITY | Confirmación de agendamiento |
|
||||
| `recordatorio_cita` | UTILITY | Recordatorio 24h antes |
|
||||
| `followup_tratamiento` | UTILITY | Seguimiento post-tratamiento |
|
||||
| `reengage_skeen` | MARKETING | Re-engagement pacientes inactivos |
|
||||
| `comprobante_pago` | UTILITY | Confirmación de pago recibido |
|
||||
|
||||
---
|
||||
|
||||
## 6. Configuración de Supabase
|
||||
|
||||
### 6.1 Docker Compose
|
||||
|
||||
```bash
|
||||
cd /root/skeen-supabase/docker
|
||||
docker compose up -d
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
### 6.2 Variables de Entorno Clave
|
||||
|
||||
```env
|
||||
POSTGRES_PASSWORD=your_password
|
||||
JWT_SECRET=your_jwt_secret
|
||||
ANON_KEY=your_anon_jwt
|
||||
SERVICE_ROLE_KEY=your_service_role_jwt
|
||||
DASHBOARD_USERNAME=supabase
|
||||
DASHBOARD_PASSWORD=your_dashboard_password
|
||||
```
|
||||
|
||||
### 6.3 Acceso a Base de Datos
|
||||
|
||||
```bash
|
||||
# Desde host
|
||||
psql -h localhost -p 5433 -U postgres -d postgres
|
||||
|
||||
# Desde contenedor
|
||||
docker exec supabase-db psql -U postgres -d postgres
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Configuración de nginx
|
||||
|
||||
### 7.1 Frontend React
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name skeen.consultoria-as.com;
|
||||
root /var/www/skeen-frontend;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/odoo {
|
||||
proxy_pass http://localhost:8069;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location /api/wacrm {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 WACRM (subdominio)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name skeencrm.consultoria-as.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Configuración de Cloudflare Tunnel
|
||||
|
||||
Para exponer servicios sin abrir puertos en el firewall:
|
||||
|
||||
```bash
|
||||
# Instalar cloudflared
|
||||
curl -fsSL https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/apt/sources.list.d/cloudflared.list
|
||||
sudo apt update && sudo apt install cloudflared
|
||||
|
||||
# Autenticar
|
||||
cloudflared tunnel login
|
||||
|
||||
# Crear tunnel
|
||||
cloudflared tunnel create skeen-tunnel
|
||||
|
||||
# Configurar DNS
|
||||
cloudflared tunnel route dns skeen-tunnel skeen.consultoria-as.com
|
||||
|
||||
# Ejecutar tunnel
|
||||
cloudflared tunnel run --token YOUR_TUNNEL_TOKEN
|
||||
```
|
||||
|
||||
**Nota:** El tunnel ya está configurado en esta VM con el token proporcionado.
|
||||
|
||||
---
|
||||
|
||||
## 9. Configuración de systemd (Producción)
|
||||
|
||||
### 9.1 Odoo
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Odoo 17 SKEEN
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Environment=SUPABASE_URL=http://localhost:8000
|
||||
Environment=SUPABASE_SERVICE_ROLE_KEY=your_key
|
||||
ExecStart=/root/odoo-venv/bin/python /root/skeen-odoo/odoo-bin -c /root/skeen-odoo/odoo.conf
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### 9.2 WACRM
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=WACRM SKEEN
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/root/skeen-wacrm
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=/usr/bin/npm start
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
### 9.3 Bridge SKEEN
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Bridge Webhook SKEEN
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/root/skeen-roadmap-hermes/hermes
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=/usr/bin/node webhook-bridge.js
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Configuración de Backups
|
||||
|
||||
```bash
|
||||
# Backup PostgreSQL Odoo
|
||||
pg_dump -U skeen -h localhost skeen_odoo > /root/backups/odoo_$(date +%Y%m%d_%H%M%S).sql
|
||||
|
||||
# Backup PostgreSQL Supabase
|
||||
docker exec supabase-db pg_dump -U postgres postgres > /root/backups/supabase_$(date +%Y%m%d_%H%M%S).sql
|
||||
|
||||
# Backup archivos
|
||||
tar -czf /root/backups/skeen-files_$(date +%Y%m%d_%H%M%S).tar.gz \
|
||||
/root/skeen-frontend \
|
||||
/root/skeen-wacrm \
|
||||
/root/skeen-odoo/addons/skeen_* \
|
||||
/root/skeen-roadmap-hermes \
|
||||
/root/migracion
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Checklist de Configuración para Go-Live
|
||||
|
||||
- [ ] Número WhatsApp Business verificado por Meta
|
||||
- [ ] Meta App ID + Secret configurados
|
||||
- [ ] Access Token permanente generado
|
||||
- [ ] Phone Number ID y WABA ID configurados en WACRM
|
||||
- [ ] Templates de WhatsApp aprobados por Meta
|
||||
- [ ] Dominio skeen.mx apuntando a la VM
|
||||
- [ ] SSL certificado instalado (Let's Encrypt)
|
||||
- [ ] Firewall configurado (solo 80, 443, 22)
|
||||
- [ ] Backups automatizados configurados
|
||||
- [ ] Monitoreo Uptime Kuma activo
|
||||
- [ ] API keys de WACRM generadas y configuradas
|
||||
- [ ] Variables de entorno en producción
|
||||
- [ ] systemd services habilitados
|
||||
- [ ] Logs rotando correctamente
|
||||
363
docs/estructura.md
Normal file
363
docs/estructura.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# Estructura del Repositorio — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Estructura General
|
||||
|
||||
```
|
||||
SKEEN-Proyecto/
|
||||
├── README.md # Documentación principal
|
||||
├── .gitignore # Archivos excluidos de Git
|
||||
├── docs/ # Documentación extensiva
|
||||
│ ├── arquitectura.md # Arquitectura técnica
|
||||
│ ├── instalacion.md # Guía de instalación
|
||||
│ ├── configuracion.md # Variables y credenciales
|
||||
│ ├── api.md # Referencia de endpoints
|
||||
│ ├── skills-hermes.md # Skills de IA
|
||||
│ ├── migracion.md # Guía de migración
|
||||
│ ├── seguridad.md # Políticas de seguridad
|
||||
│ ├── mantenimiento.md # Operación y troubleshooting
|
||||
│ ├── estructura.md # Este archivo
|
||||
│ ├── ANALISIS_SKEEN_SISTEMA.md # Análisis sistema legacy
|
||||
│ ├── ESTADO_PROYECTO.md # Estado detallado
|
||||
│ └── ROADMAP_SKEEN_MEJORA.md # Roadmap de mejoras
|
||||
├── frontend/ # Frontend React (SKEEN Brand)
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # Componentes reutilizables
|
||||
│ │ ├── pages/ # Páginas/rutas
|
||||
│ │ ├── services/ # Cliente API (odoo.ts)
|
||||
│ │ ├── designs/ # Diseños de UI
|
||||
│ │ │ └── brand/ # Diseño oficial SKEEN Brand
|
||||
│ │ ├── hooks/ # Custom hooks
|
||||
│ │ ├── utils/ # Utilidades
|
||||
│ │ ├── App.tsx # Componente raíz
|
||||
│ │ └── main.tsx # Punto de entrada
|
||||
│ ├── public/ # Assets estáticos
|
||||
│ ├── index.html # HTML base
|
||||
│ ├── package.json # Dependencias npm
|
||||
│ ├── vite.config.ts # Configuración Vite
|
||||
│ ├── tailwind.config.js # Configuración Tailwind
|
||||
│ └── tsconfig.json # Configuración TypeScript
|
||||
├── frontend-homenest/ # Frontend alternativo (Homenest)
|
||||
│ └── (misma estructura que frontend/)
|
||||
├── odoo-addons/ # Módulos Odoo custom
|
||||
│ ├── skeen_citas/ # Citas médicas
|
||||
│ │ ├── models/
|
||||
│ │ │ └── cita.py # Modelo skeen.cita, skeen.servicio
|
||||
│ │ ├── views/
|
||||
│ │ ├── security/
|
||||
│ │ │ └── ir.model.access.csv
|
||||
│ │ ├── data/
|
||||
│ │ │ └── sequences.xml
|
||||
│ │ └── __manifest__.py
|
||||
│ ├── skeen_pacientes/ # Pacientes y expedientes
|
||||
│ │ ├── models/
|
||||
│ │ │ ├── res_partner.py # Extensión res.partner
|
||||
│ │ │ └── hr_employee.py # Extensión hr.employee
|
||||
│ │ └── __manifest__.py
|
||||
│ ├── skeen_monedero/ # Sistema de puntos/fidelidad
|
||||
│ │ ├── models/
|
||||
│ │ │ ├── monedero.py # Modelo skeen.monedero
|
||||
│ │ │ └── res_partner.py # Campos en res.partner
|
||||
│ │ └── __manifest__.py
|
||||
│ ├── skeen_pagos/ # Pagos y adeudos
|
||||
│ │ ├── models/
|
||||
│ │ │ └── pago.py # Modelo skeen.pago
|
||||
│ │ └── __manifest__.py
|
||||
│ ├── skeen_ventas/ # Ventas y corte de caja
|
||||
│ │ ├── models/
|
||||
│ │ │ ├── venta.py # Modelo skeen.venta
|
||||
│ │ │ └── tipo_cambio.py # Tipo de cambio
|
||||
│ │ ├── views/
|
||||
│ │ └── __manifest__.py
|
||||
│ ├── skeen_inventario/ # Inventario
|
||||
│ │ ├── models/
|
||||
│ │ │ └── inventario.py # Modelo skeen.inventario.item
|
||||
│ │ └── __manifest__.py
|
||||
│ └── skeen_whatsapp/ # API REST para integraciones
|
||||
│ ├── controllers/
|
||||
│ │ ├── frontend.py # Endpoints para Frontend React
|
||||
│ │ ├── main.py # Endpoints para Hermes/WACRM
|
||||
│ │ └── wacrm_proxy.py # Proxy WACRM ↔ Odoo
|
||||
│ ├── models/
|
||||
│ │ ├── frontend_user.py # Usuarios del frontend
|
||||
│ │ └── wacrm_sync.py # Modelos cache WACRM
|
||||
│ ├── data/
|
||||
│ │ └── frontend_users.xml # Usuario seed admin
|
||||
│ └── __manifest__.py
|
||||
├── wacrm/ # WACRM (fork)
|
||||
│ ├── src/ # Código fuente Next.js
|
||||
│ ├── public/ # Assets
|
||||
│ ├── docs/ # Documentación WACRM
|
||||
│ ├── .env.local.example # Template de variables
|
||||
│ └── package.json
|
||||
├── hermes/ # Hermes + Bridge + Skills
|
||||
│ ├── hermes/ # Configuración Hermes
|
||||
│ │ ├── skills/ # Skills de Hermes
|
||||
│ │ │ ├── skeen-rag/ # Catálogo servicios
|
||||
│ │ │ ├── skeen-agendar/ # Agendamiento
|
||||
│ │ │ ├── skeen-pagos/ # Pagos
|
||||
│ │ │ ├── skeen-monedero/ # Monedero
|
||||
│ │ │ └── skeen-recordatorios/ # Recordatorios
|
||||
│ │ ├── workspace/ # Workspace Hermes
|
||||
│ │ ├── webhook-bridge.js # Bridge WACRM → Hermes
|
||||
│ │ └── config.yaml # Configuración
|
||||
│ ├── skills/ # Skills adicionales
|
||||
│ │ └── hermes-skeen/
|
||||
│ ├── docs/
|
||||
│ ├── infra/
|
||||
│ └── docker-compose.dev.yml
|
||||
├── migracion/ # Scripts de migración
|
||||
│ ├── importar_a_odoo.py # Migración principal
|
||||
│ ├── importar_servicios_inventario.py # Servicios + inventario
|
||||
│ ├── extraer_skeen.py # Extracción legacy
|
||||
│ ├── borrar_datos_demo.py # Limpieza demo
|
||||
│ ├── datos/ # CSVs de datos (no commitear)
|
||||
│ └── README.md # Documentación migración
|
||||
├── scripts/ # Scripts de operación
|
||||
│ ├── skeen-start-all.sh # Iniciar todo
|
||||
│ ├── skeen-stop-all.sh # Detener todo
|
||||
│ ├── skeen-start-odoo.sh # Iniciar solo Odoo
|
||||
│ ├── odoo-test-data.py # Pruebas datos Odoo
|
||||
│ └── simular_meta_webhook.py # Simulador webhook Meta
|
||||
└── infra/ # Infraestructura
|
||||
├── odoo.conf # Configuración Odoo
|
||||
└── docker-compose.dev.yml # Desarrollo local
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Archivos Clave por Componente
|
||||
|
||||
### 2.1 Frontend React
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `frontend/src/App.tsx` | Rutas principales, redirige a `/designs/brand` |
|
||||
| `frontend/src/designs/brand/Dashboard.tsx` | Dashboard principal |
|
||||
| `frontend/src/services/odoo.ts` | Cliente API para Odoo |
|
||||
| `frontend/src/pages/Agenda.tsx` | Calendario de citas |
|
||||
| `frontend/src/pages/Pacientes.tsx` | Gestión de pacientes |
|
||||
| `frontend/src/pages/Servicios.tsx` | Catálogo de servicios |
|
||||
| `frontend/src/pages/WacrmMessages.tsx` | Mensajes de WACRM |
|
||||
| `frontend/src/pages/WacrmLeads.tsx` | Leads/pipelines de WACRM |
|
||||
| `frontend/vite.config.ts` | Proxy `/api/odoo` → Odoo |
|
||||
|
||||
### 2.2 Odoo
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `odoo-addons/skeen_citas/models/cita.py` | Modelos citas y servicios |
|
||||
| `odoo-addons/skeen_whatsapp/controllers/frontend.py` | API Frontend React |
|
||||
| `odoo-addons/skeen_whatsapp/controllers/main.py` | API Hermes/WACRM |
|
||||
| `odoo-addons/skeen_whatsapp/controllers/wacrm_proxy.py` | Proxy WACRM ↔ Odoo |
|
||||
| `odoo-addons/skeen_whatsapp/models/wacrm_sync.py` | Modelos cache WACRM |
|
||||
| `odoo-addons/skeen_monedero/models/monedero.py` | Sistema de puntos |
|
||||
| `infra/odoo.conf` | Configuración Odoo |
|
||||
|
||||
### 2.3 WACRM
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `wacrm/.env.local` | Variables de entorno (no commitear) |
|
||||
| `wacrm/.env.local.example` | Template de variables |
|
||||
| `wacrm/src/app/api/` | API routes de WACRM |
|
||||
|
||||
### 2.4 Hermes
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `hermes/hermes/webhook-bridge.js` | Bridge WACRM → Hermes |
|
||||
| `hermes/hermes/skills/skeen-*/SKILL.md` | Definición de skills |
|
||||
| `/root/.hermes/skills/skeen-services.json` | Catálogo de servicios (generado) |
|
||||
|
||||
### 2.5 Migración
|
||||
|
||||
| Archivo | Propósito |
|
||||
|---------|-----------|
|
||||
| `migracion/importar_a_odoo.py` | Migración principal |
|
||||
| `migracion/importar_servicios_inventario.py` | Servicios e inventario |
|
||||
| `migracion/extraer_skeen.py` | Extracción legacy |
|
||||
|
||||
---
|
||||
|
||||
## 3. Flujo de Archivos
|
||||
|
||||
### 3.1 Agendar Cita (Frontend → Odoo)
|
||||
|
||||
```
|
||||
frontend/src/pages/Agenda.tsx
|
||||
→ frontend/src/services/odoo.ts (createAppointment)
|
||||
→ POST /skeen/frontend/v1/appointments
|
||||
→ odoo-addons/skeen_whatsapp/controllers/frontend.py (create_appointment)
|
||||
→ odoo-addons/skeen_citas/models/cita.py (create)
|
||||
→ PostgreSQL skeen_odoo
|
||||
```
|
||||
|
||||
### 3.2 Mensaje WhatsApp (Meta → WACRM → Hermes → Odoo)
|
||||
|
||||
```
|
||||
Meta Cloud API
|
||||
→ POST /api/whatsapp/webhook (WACRM)
|
||||
→ wacrm/src/app/api/whatsapp/webhook/route.ts
|
||||
→ Supabase (guarda mensaje)
|
||||
→ Automatización send_webhook
|
||||
→ POST http://localhost:8090/webhook/wacrm (Bridge)
|
||||
→ hermes/hermes/webhook-bridge.js
|
||||
→ Nan Builders API (Qwen3.6)
|
||||
→ Respuesta
|
||||
→ POST /api/v1/messages (WACRM)
|
||||
→ Meta Cloud API
|
||||
→ Paciente
|
||||
```
|
||||
|
||||
### 3.3 Consulta de Servicios (Hermes → Odoo)
|
||||
|
||||
```
|
||||
Usuario: "¿Cuánto cuesta la depilación láser?"
|
||||
→ WACRM → Bridge → Hermes
|
||||
→ Skill skeen-rag activado
|
||||
→ Lee /root/.hermes/skills/skeen-services.json
|
||||
→ Responde con precios y paquetes
|
||||
→ Si quiere agendar → Skill skeen-agendar
|
||||
→ POST /skeen/api/v1/available_slots (Odoo)
|
||||
→ POST /skeen/api/v1/create_appointment (Odoo)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Archivos No Incluidos en Git
|
||||
|
||||
Los siguientes archivos/directorios están en `.gitignore` y no se suben al repositorio:
|
||||
|
||||
| Archivo/Directorio | Razón |
|
||||
|--------------------|-------|
|
||||
| `.env`, `.env.local` | Secretos |
|
||||
| `node_modules/` | Dependencias |
|
||||
| `dist/`, `build/` | Builds |
|
||||
| `__pycache__/`, `*.pyc` | Cache Python |
|
||||
| `backups/` | Backups |
|
||||
| `datos/` | Datos sensibles de migración |
|
||||
| `*.key`, `*.pem` | Certificados |
|
||||
| `hermes-venv/`, `odoo-venv/` | Entornos virtuales |
|
||||
| `.next/` | Cache Next.js |
|
||||
| `*.log` | Logs |
|
||||
|
||||
---
|
||||
|
||||
## 5. Ramas de Git
|
||||
|
||||
| Rama | Propósito |
|
||||
|------|-----------|
|
||||
| `main` | Producción estable |
|
||||
| `develop` | Desarrollo integrado |
|
||||
| `feature/*` | Nuevas funcionalidades |
|
||||
| `fix/*` | Correcciones de bugs |
|
||||
| `hotfix/*` | Correcciones urgentes para producción |
|
||||
|
||||
---
|
||||
|
||||
## 6. Convenciones de Código
|
||||
|
||||
### 6.1 Python (Odoo)
|
||||
|
||||
- PEP 8
|
||||
- Docstrings en español
|
||||
- Nombres de modelos: `skeen.nombre_modelo`
|
||||
- Nombres de campos: snake_case
|
||||
|
||||
### 6.2 TypeScript (Frontend)
|
||||
|
||||
- ESLint + Prettier
|
||||
- Nombres de componentes: PascalCase
|
||||
- Nombres de archivos: kebab-case o PascalCase según tipo
|
||||
- Interfaces: PascalCase con prefijo `I` o sin prefijo según contexto
|
||||
|
||||
### 6.3 JavaScript (Bridge)
|
||||
|
||||
- Node.js estándar
|
||||
- async/await
|
||||
- Nombres de variables: camelCase
|
||||
|
||||
---
|
||||
|
||||
## 7. Dependencias Principales
|
||||
|
||||
### 7.1 Frontend
|
||||
|
||||
```json
|
||||
{
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.20.0",
|
||||
"axios": "^1.6.0",
|
||||
"recharts": "^2.10.0",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5.3.0",
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 Bridge
|
||||
|
||||
```json
|
||||
{
|
||||
"node-fetch": "^3.3.0",
|
||||
"crypto": "^1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 Odoo
|
||||
|
||||
```
|
||||
odoo==17.0
|
||||
psycopg2-binary
|
||||
python-jose
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Puertos Utilizados
|
||||
|
||||
| Puerto | Servicio | Protocolo |
|
||||
|--------|----------|-----------|
|
||||
| 22 | SSH | TCP |
|
||||
| 80 | HTTP (nginx) | TCP |
|
||||
| 443 | HTTPS (nginx) | TCP |
|
||||
| 3000 | WACRM | HTTP |
|
||||
| 3001 | Uptime Kuma | HTTP |
|
||||
| 5173 | Frontend dev | HTTP |
|
||||
| 5432 | PostgreSQL (host) | TCP |
|
||||
| 5433 | PostgreSQL (Supabase) | TCP |
|
||||
| 8000 | Supabase Kong | HTTP |
|
||||
| 8069 | Odoo | HTTP |
|
||||
| 8072 | Odoo longpolling | HTTP |
|
||||
| 8080 | Hermes Gateway | HTTP |
|
||||
| 8090 | Bridge SKEEN | HTTP |
|
||||
| 9119 | Hermes Serve | HTTP |
|
||||
|
||||
---
|
||||
|
||||
## 9. Volúmenes Docker
|
||||
|
||||
| Volumen | Propósito |
|
||||
|---------|-----------|
|
||||
| `supabase-db-data` | Datos PostgreSQL Supabase |
|
||||
| `supabase-storage` | Archivos Supabase |
|
||||
| `supabase-kong` | Configuración Kong |
|
||||
|
||||
---
|
||||
|
||||
## 10. Notas de Despliegue
|
||||
|
||||
1. **Frontend:** Build estático desplegado en nginx.
|
||||
2. **WACRM:** Build Next.js corriendo con `npm start`.
|
||||
3. **Odoo:** Proceso Python corriendo con `odoo-bin`.
|
||||
4. **Supabase:** Contenedores Docker.
|
||||
5. **Hermes:** Procesos Python (`gateway run`, `serve`).
|
||||
6. **Bridge:** Proceso Node.js.
|
||||
|
||||
Todos los servicios deben iniciarse automáticamente en producción usando systemd.
|
||||
420
docs/instalacion.md
Normal file
420
docs/instalacion.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# Guía de Instalación — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Requisitos del Sistema
|
||||
|
||||
### Hardware Mínimo
|
||||
|
||||
- **CPU:** 4 vCPU
|
||||
- **RAM:** 16 GB (22 GB recomendado)
|
||||
- **Disco:** 80 GB SSD
|
||||
- **Red:** IP pública fija (para webhooks de Meta)
|
||||
|
||||
### Software
|
||||
|
||||
| Software | Versión | Propósito |
|
||||
|----------|---------|-----------|
|
||||
| Ubuntu | 22.04 LTS | Sistema operativo |
|
||||
| Docker | 24+ | Supabase self-hosted |
|
||||
| Docker Compose | 2.20+ | Orquestación Supabase |
|
||||
| Node.js | 20+ | WACRM, Bridge, Frontend build |
|
||||
| Python | 3.12+ | Odoo, migración |
|
||||
| PostgreSQL | 16 | Odoo DB |
|
||||
| nginx | 1.24+ | Reverse proxy, static files |
|
||||
| git | 2.40+ | Control de versiones |
|
||||
|
||||
---
|
||||
|
||||
## 2. Instalación del Sistema Base
|
||||
|
||||
```bash
|
||||
# Actualizar sistema
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Instalar dependencias base
|
||||
sudo apt install -y \
|
||||
curl wget git nginx postgresql postgresql-contrib \
|
||||
build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev \
|
||||
libjpeg-dev libpq-dev python3 python3-pip python3-venv \
|
||||
python3-dev libldap2-dev libsasl2-dev
|
||||
|
||||
# Instalar Node.js 20
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Instalar Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
|
||||
# Instalar Docker Compose
|
||||
sudo apt install -y docker-compose-plugin
|
||||
|
||||
# Verificar instalaciones
|
||||
node -v # v20.x
|
||||
python3 --version # 3.12.x
|
||||
docker --version
|
||||
docker compose version
|
||||
psql --version
|
||||
nginx -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Configuración de PostgreSQL
|
||||
|
||||
```bash
|
||||
# Crear usuario y base de datos para Odoo
|
||||
sudo -u postgres psql << 'EOF'
|
||||
CREATE USER skeen WITH PASSWORD 'skeen_dev_2026';
|
||||
ALTER USER skeen CREATEDB;
|
||||
CREATE DATABASE skeen_odoo OWNER skeen;
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Instalación de Supabase Self-Hosted
|
||||
|
||||
```bash
|
||||
# Clonar Supabase
|
||||
cd /root
|
||||
git clone https://github.com/supabase/supabase.git skeen-supabase
|
||||
cd skeen-supabase/docker
|
||||
|
||||
# Configurar variables de entorno
|
||||
cp .env.example .env
|
||||
# Editar .env con tus valores
|
||||
|
||||
# Levantar Supabase
|
||||
docker compose up -d
|
||||
|
||||
# Verificar contenedores
|
||||
docker compose ps
|
||||
docker compose logs -f db
|
||||
```
|
||||
|
||||
**Variables importantes en `.env`:**
|
||||
|
||||
```env
|
||||
POSTGRES_PASSWORD=your_postgres_password
|
||||
JWT_SECRET=your_jwt_secret_32_chars
|
||||
ANON_KEY=your_anon_jwt
|
||||
SERVICE_ROLE_KEY=your_service_role_jwt
|
||||
DASHBOARD_USERNAME=supabase
|
||||
DASHBOARD_PASSWORD=your_dashboard_password
|
||||
SITE_URL=http://localhost:3000
|
||||
ADDITIONAL_REDIRECT_URLS=http://localhost:3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Instalación de WACRM
|
||||
|
||||
```bash
|
||||
cd /root
|
||||
git clone https://github.com/ArnasDon/wacrm.git skeen-wacrm
|
||||
cd skeen-wacrm
|
||||
|
||||
# Instalar dependencias
|
||||
npm install
|
||||
|
||||
# Configurar entorno
|
||||
cp .env.local.example .env.local
|
||||
```
|
||||
|
||||
**Editar `.env.local`:**
|
||||
|
||||
```env
|
||||
# Supabase (self-hosted on localhost)
|
||||
NEXT_PUBLIC_SUPABASE_URL=http://localhost:8000
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
|
||||
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
|
||||
|
||||
# Encryption key for WACRM (64 hex chars)
|
||||
ENCRYPTION_KEY=your_64_hex_char_key
|
||||
|
||||
# WhatsApp / Meta (pending client data)
|
||||
WHATSAPP_PHONE_NUMBER_ID=PENDING_PHONE_ID
|
||||
WHATSAPP_BUSINESS_ACCOUNT_ID=PENDING_WABA_ID
|
||||
WHATSAPP_ACCESS_TOKEN=PENDING_TOKEN
|
||||
WHATSAPP_VERIFY_TOKEN=skeen_webhook_verify_2026
|
||||
|
||||
# Meta App Secret for webhook signature verification
|
||||
META_APP_SECRET=your_meta_app_secret
|
||||
|
||||
# Application
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||
NODE_ENV=development
|
||||
```
|
||||
|
||||
**Ejecutar migraciones de base de datos:**
|
||||
|
||||
```bash
|
||||
# Ejecutar migraciones SQL en Supabase
|
||||
# Las migraciones 026_api_keys.sql y 028_webhook_endpoints.sql son REQUERIDAS
|
||||
```
|
||||
|
||||
**Build y arrancar:**
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm start
|
||||
# Dev: npm run dev (localhost:3000)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Instalación de Odoo 17
|
||||
|
||||
```bash
|
||||
cd /root
|
||||
git clone https://github.com/odoo/odoo.git --depth 1 --branch 17.0 skeen-odoo
|
||||
cd skeen-odoo
|
||||
|
||||
# Crear entorno virtual
|
||||
python3 -m venv /root/odoo-venv
|
||||
source /root/odoo-venv/bin/activate
|
||||
|
||||
# Instalar dependencias
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Configurar odoo.conf
|
||||
cat > odoo.conf << 'EOF'
|
||||
[options]
|
||||
addons_path = /root/skeen-odoo/addons,/root/skeen-odoo/odoo/addons
|
||||
admin_passwd = skeen_admin_2026
|
||||
db_host = localhost
|
||||
db_name = skeen_odoo
|
||||
db_password = skeen_dev_2026
|
||||
db_port = 5432
|
||||
db_user = skeen
|
||||
http_port = 8069
|
||||
proxy_mode = True
|
||||
workers = 0
|
||||
EOF
|
||||
|
||||
# Copiar módulos custom
|
||||
cp -r /root/SKEEN-Proyecto/odoo-addons/* /root/skeen-odoo/addons/
|
||||
|
||||
# Iniciar Odoo
|
||||
./odoo-bin -c odoo.conf --logfile=/tmp/odoo.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Instalación de Hermes
|
||||
|
||||
```bash
|
||||
cd /root
|
||||
git clone https://github.com/NousResearch/Hermes-Agent.git hermes-repo
|
||||
cd hermes-repo
|
||||
|
||||
# Crear entorno virtual
|
||||
python3 -m venv /root/hermes-venv
|
||||
source /root/hermes-venv/bin/activate
|
||||
|
||||
# Instalar
|
||||
pip install -e .
|
||||
|
||||
# Configurar
|
||||
hermes setup
|
||||
```
|
||||
|
||||
**Configurar variables de entorno:**
|
||||
|
||||
```bash
|
||||
export NAN_API_KEY=sk-gJ8OWbZVGeWy9ns_H00cxA
|
||||
export NAN_BASE_URL=https://api.nan.builders/v1
|
||||
```
|
||||
|
||||
**Iniciar gateway:**
|
||||
|
||||
```bash
|
||||
hermes gateway run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Instalación del Bridge SKEEN
|
||||
|
||||
```bash
|
||||
cd /root/skeen-roadmap-hermes/hermes
|
||||
npm install
|
||||
|
||||
# Configurar
|
||||
cat > .env << 'EOF'
|
||||
NAN_API_KEY=sk-gJ8OWbZVGeWy9ns_H00cxA
|
||||
NAN_BASE_URL=https://api.nan.builders/v1
|
||||
NAN_MODEL=qwen3.6
|
||||
WACRM_URL=http://localhost:3000
|
||||
WACRM_API_KEY=your_wacrm_api_key
|
||||
BRIDGE_PORT=8090
|
||||
EOF
|
||||
|
||||
# Iniciar bridge
|
||||
node webhook-bridge.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Instalación del Frontend React
|
||||
|
||||
```bash
|
||||
cd /root
|
||||
git clone https://git.consultoria-as.com/consultoria-as/SKEEN-Proyecto.git
|
||||
cd SKEEN-Proyecto/frontend
|
||||
|
||||
# Instalar dependencias
|
||||
npm install
|
||||
|
||||
# Desarrollo
|
||||
npm run dev
|
||||
|
||||
# Producción
|
||||
npm run build
|
||||
sudo mkdir -p /var/www/skeen-frontend
|
||||
sudo cp -r dist/* /var/www/skeen-frontend/
|
||||
```
|
||||
|
||||
**Configurar nginx:**
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name skeen.consultoria-as.com;
|
||||
root /var/www/skeen-frontend;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/odoo {
|
||||
proxy_pass http://localhost:8069;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
location /api/wacrm {
|
||||
proxy_pass http://localhost:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Configuración de Automatización en WACRM
|
||||
|
||||
1. Ir a **WACRM Dashboard → Automations**.
|
||||
2. Crear automatización "Nuevo mensaje → Webhook Hermes Bridge":
|
||||
- **Trigger:** `new_message_received`
|
||||
- **Step:** `send_webhook`
|
||||
- **URL:** `http://localhost:8090/webhook/wacrm`
|
||||
- **Body:** `{"from":"{{ vars.contact_phone }}","text":"{{ message.text }}","conversation_id":"{{ vars.conversation_id }}","contact_id":"{{ vars.contact_id }}"}`
|
||||
|
||||
---
|
||||
|
||||
## 11. Creación de API Key en WACRM
|
||||
|
||||
1. Ir a **WACRM Dashboard → Settings → API Keys**.
|
||||
2. Crear nueva API key con scopes:
|
||||
- `messages:send`
|
||||
- `messages:read`
|
||||
- `contacts:read`
|
||||
- `contacts:write`
|
||||
- `conversations:read`
|
||||
- `broadcasts:send`
|
||||
- `webhooks:manage`
|
||||
3. Guardar la key en `.env` del bridge como `WACRM_API_KEY`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Verificación de la Instalación
|
||||
|
||||
```bash
|
||||
# Health checks
|
||||
curl http://localhost:8069/web/health
|
||||
curl http://localhost:8090/health
|
||||
curl http://localhost:8069/skeen/frontend/v1/health
|
||||
|
||||
# Servicios corriendo
|
||||
ss -tlnp | grep -E "3000|5173|8069|8000|8090|8644|8080|9119"
|
||||
|
||||
# Logs
|
||||
tail -f /tmp/wacrm.log
|
||||
tail -f /tmp/odoo.log
|
||||
tail -f /tmp/hermes-bridge.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. Troubleshooting Común
|
||||
|
||||
### WACRM no conecta a Supabase
|
||||
|
||||
```bash
|
||||
# Verificar contenedores
|
||||
cd /root/skeen-supabase/docker && docker compose ps
|
||||
|
||||
# Verificar variables de entorno
|
||||
cat /root/skeen-wacrm/.env.local | grep SUPABASE
|
||||
```
|
||||
|
||||
### Odoo no inicia
|
||||
|
||||
```bash
|
||||
# Ver logs
|
||||
tail -100 /tmp/odoo.log
|
||||
|
||||
# Verificar PostgreSQL
|
||||
sudo -u postgres psql -d skeen_odoo -c "SELECT 1;"
|
||||
```
|
||||
|
||||
### Bridge no responde
|
||||
|
||||
```bash
|
||||
# Verificar puerto
|
||||
ss -tlnp | grep 8090
|
||||
|
||||
# Ver logs
|
||||
tail -100 /tmp/hermes-bridge.log
|
||||
```
|
||||
|
||||
### Frontend no carga
|
||||
|
||||
```bash
|
||||
# Verificar nginx
|
||||
sudo nginx -t
|
||||
sudo systemctl status nginx
|
||||
|
||||
# Verificar build
|
||||
ls -la /var/www/skeen-frontend/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. Scripts de Operación
|
||||
|
||||
| Script | Propósito |
|
||||
|--------|-----------|
|
||||
| `scripts/skeen-start-all.sh` | Inicia todo el ecosistema |
|
||||
| `scripts/skeen-stop-all.sh` | Detiene todo el ecosistema |
|
||||
| `scripts/skeen-start-odoo.sh` | Inicia solo Odoo |
|
||||
|
||||
---
|
||||
|
||||
## 15. Notas de Producción
|
||||
|
||||
1. **HTTPS:** Configurar SSL con Let's Encrypt antes de go-live.
|
||||
2. **Firewall:** Abrir solo puertos necesarios (80, 443, 22).
|
||||
3. **Backups:** Configurar backups diarios de PostgreSQL.
|
||||
4. **Monitoreo:** Instalar Uptime Kuma.
|
||||
5. **Logs:** Configurar logrotate para `/tmp/*.log`.
|
||||
6. **Variables de entorno:** Usar systemd EnvironmentFile o .env files.
|
||||
398
docs/mantenimiento.md
Normal file
398
docs/mantenimiento.md
Normal file
@@ -0,0 +1,398 @@
|
||||
# Mantenimiento y Operación — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Operaciones Diarias
|
||||
|
||||
### 1.1 Verificación de Servicios
|
||||
|
||||
```bash
|
||||
# Estado de puertos
|
||||
ss -tlnp | grep -E "3000|5173|8069|8000|8090|8644|8080|9119|5433"
|
||||
|
||||
# Health checks
|
||||
curl http://localhost:8069/web/health
|
||||
curl http://localhost:8090/health
|
||||
curl http://localhost:8069/skeen/frontend/v1/health
|
||||
|
||||
# Estado Docker (Supabase)
|
||||
cd /root/skeen-supabase/docker && docker compose ps
|
||||
```
|
||||
|
||||
### 1.2 Logs Principales
|
||||
|
||||
```bash
|
||||
# WACRM
|
||||
tail -f /tmp/wacrm.log
|
||||
|
||||
# Odoo
|
||||
tail -f /tmp/odoo.log
|
||||
|
||||
# Bridge
|
||||
tail -f /tmp/hermes-bridge.log
|
||||
|
||||
# Hermes Gateway
|
||||
tail -f /tmp/hermes-gateway.log
|
||||
|
||||
# Hermes Serve
|
||||
tail -f /tmp/hermes-serve.log
|
||||
|
||||
# Frontend (dev)
|
||||
tail -f /tmp/frontend.log
|
||||
|
||||
# nginx
|
||||
tail -f /var/log/nginx/access.log
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Operaciones Semanales
|
||||
|
||||
### 2.1 Limpieza de Logs
|
||||
|
||||
```bash
|
||||
# Rotación manual si no hay logrotate
|
||||
mv /tmp/odoo.log /tmp/odoo.log.$(date +%Y%m%d)
|
||||
mv /tmp/wacrm.log /tmp/wacrm.log.$(date +%Y%m%d)
|
||||
mv /tmp/hermes-bridge.log /tmp/hermes-bridge.log.$(date +%Y%m%d)
|
||||
|
||||
# Reiniciar servicios para recrear logs
|
||||
systemctl restart odoo
|
||||
# o reiniciar manualmente según el método de inicio
|
||||
```
|
||||
|
||||
### 2.2 Verificación de Espacio en Disco
|
||||
|
||||
```bash
|
||||
df -h
|
||||
du -sh /var/lib/odoo
|
||||
du -sh /root/skeen-supabase/docker/volumes
|
||||
```
|
||||
|
||||
### 2.3 Verificación de Memoria
|
||||
|
||||
```bash
|
||||
free -h
|
||||
ps aux --sort=-%mem | head -20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Operaciones Mensuales
|
||||
|
||||
### 3.1 Actualizaciones de Seguridad
|
||||
|
||||
```bash
|
||||
# Sistema
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Node.js (si hay nueva versión LTS)
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Dependencias npm (frontend)
|
||||
cd /root/skeen-frontend && npm audit fix
|
||||
|
||||
# Dependencias npm (WACRM)
|
||||
cd /root/skeen-wacrm && npm audit fix
|
||||
```
|
||||
|
||||
### 3.2 Revisión de Backups
|
||||
|
||||
```bash
|
||||
# Verificar backups recientes
|
||||
ls -la /root/backups/
|
||||
|
||||
# Probar restauración (en entorno de prueba)
|
||||
gunzip -c /root/backups/odoo_YYYYMMDD.sql.gz | psql -U skeen -d skeen_odoo_test
|
||||
```
|
||||
|
||||
### 3.3 Revisión de Certificados
|
||||
|
||||
```bash
|
||||
sudo certbot certificates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Monitoreo
|
||||
|
||||
### 4.1 Uptime Kuma (a instalar)
|
||||
|
||||
```bash
|
||||
# Instalar Uptime Kuma
|
||||
docker run -d --restart=always \
|
||||
-p 3001:3001 \
|
||||
-v uptime-kuma:/app/data \
|
||||
--name uptime-kuma \
|
||||
louislam/uptime-kuma:1
|
||||
```
|
||||
|
||||
**Monitores a configurar:**
|
||||
- Frontend React: `http://localhost:5173`
|
||||
- Odoo: `http://localhost:8069/web/health`
|
||||
- WACRM: `http://localhost:3000`
|
||||
- Bridge: `http://localhost:8090/health`
|
||||
- Supabase: `http://localhost:8000`
|
||||
|
||||
**Alertas:**
|
||||
- Email: ialcarazsalazar@consultoria-as.com
|
||||
- WhatsApp: (vía webhook a WACRM)
|
||||
|
||||
### 4.2 Métricas Clave
|
||||
|
||||
| Métrica | Umbral | Acción |
|
||||
|---------|--------|--------|
|
||||
| CPU | > 80% por 5 min | Investigar proceso |
|
||||
| RAM | > 90% | Reiniciar servicios si es necesario |
|
||||
| Disco | > 85% | Limpiar logs/backups |
|
||||
| Response time Odoo | > 5s | Optimizar queries |
|
||||
| Response time WACRM | > 3s | Reiniciar WACRM |
|
||||
| Errores 5xx | > 10/min | Revisar logs |
|
||||
|
||||
---
|
||||
|
||||
## 5. Troubleshooting
|
||||
|
||||
### 5.1 WACRM no responde
|
||||
|
||||
```bash
|
||||
# Verificar proceso
|
||||
ps aux | grep node | grep wacrm
|
||||
|
||||
# Verificar logs
|
||||
tail -100 /tmp/wacrm.log
|
||||
|
||||
# Reiniciar
|
||||
cd /root/skeen-wacrm && pkill -f "next start" && npm start
|
||||
```
|
||||
|
||||
### 5.2 Odoo no responde
|
||||
|
||||
```bash
|
||||
# Verificar proceso
|
||||
ps aux | grep odoo
|
||||
|
||||
# Verificar PostgreSQL
|
||||
sudo -u postgres psql -d skeen_odoo -c "SELECT 1;"
|
||||
|
||||
# Verificar logs
|
||||
tail -100 /tmp/odoo.log
|
||||
|
||||
# Reiniciar
|
||||
pkill -f "odoo-bin"
|
||||
cd /root/skeen-odoo && ./odoo-bin -c odoo.conf --logfile=/tmp/odoo.log
|
||||
```
|
||||
|
||||
### 5.3 Bridge no responde
|
||||
|
||||
```bash
|
||||
# Verificar proceso
|
||||
ps aux | grep webhook-bridge
|
||||
|
||||
# Verificar logs
|
||||
tail -100 /tmp/hermes-bridge.log
|
||||
|
||||
# Reiniciar
|
||||
pkill -f "webhook-bridge.js"
|
||||
cd /root/skeen-roadmap-hermes/hermes && node webhook-bridge.js
|
||||
```
|
||||
|
||||
### 5.4 Supabase no responde
|
||||
|
||||
```bash
|
||||
# Verificar contenedores
|
||||
cd /root/skeen-supabase/docker && docker compose ps
|
||||
|
||||
# Ver logs
|
||||
docker compose logs db
|
||||
docker compose logs kong
|
||||
docker compose logs auth
|
||||
|
||||
# Reiniciar
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
### 5.5 Frontend no carga
|
||||
|
||||
```bash
|
||||
# Verificar nginx
|
||||
sudo nginx -t
|
||||
sudo systemctl status nginx
|
||||
|
||||
# Verificar build
|
||||
ls -la /var/www/skeen-frontend/
|
||||
|
||||
# Rebuild si es necesario
|
||||
cd /root/skeen-frontend && npm run build
|
||||
sudo cp -r dist/* /var/www/skeen-frontend/
|
||||
```
|
||||
|
||||
### 5.6 WhatsApp no envía mensajes
|
||||
|
||||
1. Verificar tokens en WACRM Settings.
|
||||
2. Verificar webhook configurado en Meta.
|
||||
3. Verificar templates aprobados.
|
||||
4. Revisar logs de WACRM.
|
||||
|
||||
---
|
||||
|
||||
## 6. Backups y Restauración
|
||||
|
||||
### 6.1 Backup Automatizado
|
||||
|
||||
Crear `/etc/cron.daily/skeen-backup`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR=/root/backups
|
||||
|
||||
# PostgreSQL Odoo
|
||||
pg_dump -U skeen -h localhost skeen_odoo | gzip > $BACKUP_DIR/odoo_$DATE.sql.gz
|
||||
|
||||
# PostgreSQL Supabase
|
||||
docker exec supabase-db pg_dump -U postgres postgres | gzip > $BACKUP_DIR/supabase_$DATE.sql.gz
|
||||
|
||||
# Archivos
|
||||
tar -czf $BACKUP_DIR/files_$DATE.tar.gz \
|
||||
/root/skeen-frontend \
|
||||
/root/skeen-wacrm \
|
||||
/root/skeen-odoo/addons/skeen_* \
|
||||
/root/skeen-roadmap-hermes \
|
||||
/root/migracion
|
||||
|
||||
# Limpiar antiguos
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||||
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
|
||||
|
||||
echo "Backup completado: $DATE"
|
||||
```
|
||||
|
||||
```bash
|
||||
chmod +x /etc/cron.daily/skeen-backup
|
||||
```
|
||||
|
||||
### 6.2 Restauración Odoo
|
||||
|
||||
```bash
|
||||
# Detener Odoo
|
||||
pkill -f "odoo-bin"
|
||||
|
||||
# Restaurar base de datos
|
||||
gunzip -c /root/backups/odoo_YYYYMMDD.sql.gz | psql -U skeen -d skeen_odoo
|
||||
|
||||
# Reiniciar Odoo
|
||||
cd /root/skeen-odoo && ./odoo-bin -c odoo.conf --logfile=/tmp/odoo.log
|
||||
```
|
||||
|
||||
### 6.3 Restauración Supabase
|
||||
|
||||
```bash
|
||||
# Detener Supabase
|
||||
cd /root/skeen-supabase/docker && docker compose down
|
||||
|
||||
# Restaurar base de datos
|
||||
gunzip -c /root/backups/supabase_YYYYMMDD.sql.gz | docker exec -i supabase-db psql -U postgres -d postgres
|
||||
|
||||
# Reiniciar Supabase
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Actualización del Sistema
|
||||
|
||||
### 7.1 Actualizar Frontend
|
||||
|
||||
```bash
|
||||
cd /root/skeen-frontend
|
||||
git pull origin main
|
||||
npm install
|
||||
npm run build
|
||||
sudo cp -r dist/* /var/www/skeen-frontend/
|
||||
```
|
||||
|
||||
### 7.2 Actualizar Módulos Odoo
|
||||
|
||||
```bash
|
||||
cd /root/skeen-odoo
|
||||
git pull origin main
|
||||
|
||||
# Actualizar módulos custom
|
||||
/root/odoo-venv/bin/python ./odoo-bin -c odoo.conf -u skeen_citas,skeen_pacientes,skeen_monedero,skeen_pagos,skeen_ventas,skeen_inventario,skeen_whatsapp -d skeen_odoo --stop-after-init --no-http
|
||||
```
|
||||
|
||||
### 7.3 Actualizar WACRM
|
||||
|
||||
```bash
|
||||
cd /root/skeen-wacrm
|
||||
git pull origin main
|
||||
npm install
|
||||
npm run build
|
||||
pkill -f "next start"
|
||||
npm start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Escalabilidad
|
||||
|
||||
### 8.1 Cuando el sistema crezca
|
||||
|
||||
| Señal | Acción |
|
||||
|-------|--------|
|
||||
| CPU > 70% constante | Migrar a VPS más grande |
|
||||
| RAM > 80% constante | Aumentar RAM o separar servicios |
|
||||
| Disco > 80% | Aumentar disco o mover backups a externo |
|
||||
| Muchos usuarios concurrentes | Load balancer + múltiples instancias |
|
||||
| Muchas conversaciones WhatsApp | WACRM escalado horizontalmente |
|
||||
|
||||
### 8.2 Separación de Servicios
|
||||
|
||||
Cuando sea necesario:
|
||||
|
||||
1. **VM 1:** Frontend + nginx + Bridge
|
||||
2. **VM 2:** Odoo + PostgreSQL
|
||||
3. **VM 3:** WACRM + Supabase
|
||||
4. **VM 4:** Hermes Gateway + Serve
|
||||
|
||||
---
|
||||
|
||||
## 9. Contacto de Soporte
|
||||
|
||||
- **Email:** ialcarazsalazar@consultoria-as.com
|
||||
- **Gitea Issues:** https://git.consultoria-as.com/consultoria-as/SKEEN-Proyecto/issues
|
||||
- **Horario:** Lun-Vie 9:00-18:00 (hora del Pacífico)
|
||||
|
||||
---
|
||||
|
||||
## 10. Checklist de Mantenimiento
|
||||
|
||||
### Diario
|
||||
- [ ] Verificar servicios corriendo
|
||||
- [ ] Revisar logs de errores
|
||||
- [ ] Verificar backups del día anterior
|
||||
|
||||
### Semanal
|
||||
- [ ] Limpiar logs antiguos
|
||||
- [ ] Verificar espacio en disco
|
||||
- [ ] Verificar uso de memoria
|
||||
- [ ] Probar flujo end-to-end (WhatsApp → Odoo → Frontend)
|
||||
|
||||
### Mensual
|
||||
- [ ] Actualizar sistema y dependencias
|
||||
- [ ] Revisar y probar backups
|
||||
- [ ] Revisar certificados SSL
|
||||
- [ ] Revisar accesos y API keys
|
||||
- [ ] Revisar métricas de uso
|
||||
|
||||
### Trimestral
|
||||
- [ ] Rotar secretos y API keys
|
||||
- [ ] Revisar políticas de seguridad
|
||||
- [ ] Actualizar documentación
|
||||
- [ ] Pruebas de recuperación de desastres
|
||||
298
docs/migracion.md
Normal file
298
docs/migracion.md
Normal file
@@ -0,0 +1,298 @@
|
||||
# Guía de Migración — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Introducción
|
||||
|
||||
Esta guía describe el proceso de migración de datos desde el sistema legacy de SKEEN (`https://sistema.skeenmx.app/`) hacia el nuevo sistema basado en Odoo 17.
|
||||
|
||||
**Importante:** La migración requiere autorización documentada del cliente. No se ha realizado extracción masiva de datos sin permiso explícito.
|
||||
|
||||
---
|
||||
|
||||
## 2. Datos a Migrar
|
||||
|
||||
| Entidad | Descripción | Prioridad |
|
||||
|---------|-------------|-----------|
|
||||
| Pacientes | Datos personales, contacto, historial médico | Alta |
|
||||
| Citas | Histórico de citas, fechas, servicios | Alta |
|
||||
| Servicios | Catálogo de tratamientos, precios, paquetes | Alta |
|
||||
| Ventas | Histórico de ventas, pagos, adeudos | Media |
|
||||
| Monedero | Puntos de fidelidad acumulados | Media |
|
||||
| Inventario | Productos y consumibles | Media |
|
||||
| Médicos | Personal de la clínica | Baja |
|
||||
|
||||
---
|
||||
|
||||
## 3. Formatos de Datos
|
||||
|
||||
### 3.1 CSV de Pacientes
|
||||
|
||||
```csv
|
||||
name,phone,email,birthdate,gender,blood_type,allergies,address,notes
|
||||
Juan Pérez,526641234567,juan@example.com,1990-01-15,male,O+,Penicilina,"Calle 123, Rosarito","Paciente frecuente"
|
||||
```
|
||||
|
||||
**Campos:**
|
||||
- `name` (required): Nombre completo
|
||||
- `phone` (required): Teléfono (formato internacional sin +)
|
||||
- `email`: Email
|
||||
- `birthdate`: Fecha de nacimiento (YYYY-MM-DD)
|
||||
- `gender`: `male`, `female`, `other`
|
||||
- `blood_type`: Tipo de sangre
|
||||
- `allergies`: Alergias
|
||||
- `address`: Dirección
|
||||
- `notes`: Notas adicionales
|
||||
|
||||
### 3.2 CSV de Servicios
|
||||
|
||||
```csv
|
||||
name,code,category,price,duration_min,package_price,package_sessions,package_notes,description,service_group,color,is_favorite
|
||||
Consulta Dermatologica,CONS-DERM,consulta,800,30,0,0,,Evaluación completa,Consultas,#1abc9c,true
|
||||
Depilación Laser Full Body,LASER-FUL,tratamiento,2500,90,7000,3,Ahorro de $500,Depilación full body,Corporal,#e74c3c,false
|
||||
```
|
||||
|
||||
**Campos:**
|
||||
- `name` (required): Nombre del servicio
|
||||
- `code` (required): Código único
|
||||
- `category`: `consulta`, `tratamiento`, `procedimiento`, `paquete`
|
||||
- `price` (required): Precio por sesión
|
||||
- `duration_min`: Duración en minutos
|
||||
- `package_price`: Precio del paquete (0 si no aplica)
|
||||
- `package_sessions`: Sesiones del paquete (0 si no aplica)
|
||||
- `package_notes`: Notas del paquete
|
||||
- `description`: Descripción
|
||||
- `service_group`: Grupo/categoría
|
||||
- `color`: Color hexadecimal
|
||||
- `is_favorite`: `true`/`false`
|
||||
|
||||
### 3.3 CSV de Inventario
|
||||
|
||||
```csv
|
||||
name,kind,sku,category,unit,qty,qty_optimal,qty_min,cost,expiry_date,notes
|
||||
Suero Vitamina C,producto,PRD-001,Skincare,pieza,24,30,5,320,2027-06-15,Suero antioxidante
|
||||
Guantes Estériles,consumible,CON-003,Instrumental,caja,8,15,3,95,,Caja de 100 unidades
|
||||
```
|
||||
|
||||
**Campos:**
|
||||
- `name` (required): Nombre del item
|
||||
- `kind`: `producto` o `consumible`
|
||||
- `sku`: Código SKU
|
||||
- `category`: Categoría
|
||||
- `unit`: Unidad de medida
|
||||
- `qty`: Existencia actual
|
||||
- `qty_optimal`: Nivel óptimo
|
||||
- `qty_min`: Stock mínimo
|
||||
- `cost`: Costo unitario
|
||||
- `expiry_date`: Caducidad (YYYY-MM-DD)
|
||||
- `notes`: Notas
|
||||
|
||||
### 3.4 CSV de Citas
|
||||
|
||||
```csv
|
||||
patient_name,patient_phone,service_code,date,time,state,notes
|
||||
Juan Pérez,526641234567,CONS-DERM,2026-07-17,10:00,confirmed,Primera visita
|
||||
```
|
||||
|
||||
### 3.5 CSV de Ventas
|
||||
|
||||
```csv
|
||||
patient_phone,date,service_code,qty,price,payment_method,notes
|
||||
526641234567,2026-07-17,CONS-DERM,1,800,cash,Pago en efectivo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Proceso de Migración
|
||||
|
||||
### 4.1 Preparación
|
||||
|
||||
1. **Obtener autorización:** Documento firmado por SKEEN autorizando la extracción.
|
||||
2. **Exportar datos:** Del sistema legacy (CSV, SQL dump, o API).
|
||||
3. **Limpiar datos:** Verificar formatos, eliminar duplicados.
|
||||
4. **Backup:** Respaldar base de datos actual de Odoo.
|
||||
|
||||
### 4.2 Ejecución
|
||||
|
||||
```bash
|
||||
# 1. Colocar CSVs en el directorio de migración
|
||||
cd /root/migracion
|
||||
mkdir -p datos
|
||||
cp /ruta/a/csvs/* datos/
|
||||
|
||||
# 2. Ejecutar migración principal (pacientes, servicios, citas, ventas)
|
||||
python3 importar_a_odoo.py
|
||||
|
||||
# 3. Importar servicios e inventario específicos
|
||||
python3 importar_servicios_inventario.py \
|
||||
--servicios datos/servicios.csv \
|
||||
--inventario datos/inventario.csv \
|
||||
--purge-citas \
|
||||
--purge-sql \
|
||||
--generar-hermes
|
||||
|
||||
# 4. Verificar datos importados
|
||||
python3 -c "
|
||||
import xmlrpc.client
|
||||
url='http://localhost:8069'
|
||||
common=xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common')
|
||||
uid=common.authenticate('skeen_odoo','admin','skeen_admin_2026',{})
|
||||
models=xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')
|
||||
for m in ['res.partner','skeen.servicio','skeen.cita','skeen.inventario.item']:
|
||||
n=models.execute_kw('skeen_odoo',uid,'skeen_admin_2026',m,'search_count',[[]])
|
||||
print(m,n)
|
||||
"
|
||||
```
|
||||
|
||||
### 4.3 Validación
|
||||
|
||||
1. **Conteo de registros:** Comparar totales origen vs destino.
|
||||
2. **Muestra aleatoria:** Verificar 10-20 registros manualmente.
|
||||
3. **Pruebas funcionales:** Agendar cita, consultar saldo, redimir puntos.
|
||||
4. **Reporte de errores:** Documentar registros que fallaron.
|
||||
|
||||
---
|
||||
|
||||
## 5. Scripts de Migración
|
||||
|
||||
### 5.1 `importar_a_odoo.py`
|
||||
|
||||
Script principal de migración. Importa:
|
||||
|
||||
- Pacientes (res.partner)
|
||||
- Servicios (skeen.servicio)
|
||||
- Citas (skeen.cita)
|
||||
- Ventas (skeen.venta)
|
||||
- Pagos (skeen.pago)
|
||||
- Monederos (skeen.monedero)
|
||||
|
||||
**Uso:**
|
||||
```bash
|
||||
python3 importar_a_odoo.py
|
||||
```
|
||||
|
||||
### 5.2 `importar_servicios_inventario.py`
|
||||
|
||||
Script especializado para servicios e inventario.
|
||||
|
||||
**Uso:**
|
||||
```bash
|
||||
python3 importar_servicios_inventario.py \
|
||||
--servicios servicios.csv \
|
||||
--inventario inventario.csv \
|
||||
[--purge-citas] \
|
||||
[--purge-sql] \
|
||||
[--generar-hermes]
|
||||
```
|
||||
|
||||
**Opciones:**
|
||||
- `--purge-citas`: Eliminar citas existentes antes de importar
|
||||
- `--purge-sql`: Usar TRUNCATE SQL para limpieza rápida
|
||||
- `--generar-hermes`: Generar catálogo JSON para skills de Hermes
|
||||
|
||||
### 5.3 `extraer_skeen.py`
|
||||
|
||||
Script de extracción del sistema legacy. Requiere credenciales y autorización.
|
||||
|
||||
**Nota:** Este script está disponible pero no se ha ejecutado por restricciones de autorización.
|
||||
|
||||
---
|
||||
|
||||
## 6. Limpieza de Datos Demo
|
||||
|
||||
Antes de migrar datos reales, se recomienda limpiar datos demo:
|
||||
|
||||
```bash
|
||||
cd /root/migracion
|
||||
|
||||
# Opción 1: Script de borrado
|
||||
python3 borrar_datos_demo.py
|
||||
|
||||
# Opción 2: SQL directo (más rápido)
|
||||
python3 importar_servicios_inventario.py --purge-citas --purge-sql --servicios /dev/null --inventario /dev/null
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Sincronización Post-Migración
|
||||
|
||||
Después de la migración, es necesario sincronizar con WACRM:
|
||||
|
||||
```bash
|
||||
# Desde el frontend o vía API
|
||||
curl -X POST http://localhost:8069/skeen/frontend/v1/wacrm/sync \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"sync_contacts":true,"sync_conversations":true,"sync_messages":true,"sync_deals":true}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Regeneración del Catálogo Hermes
|
||||
|
||||
Después de importar servicios, regenerar el catálogo para Hermes:
|
||||
|
||||
```bash
|
||||
cd /root/migracion
|
||||
python3 importar_servicios_inventario.py --solo-hermes
|
||||
```
|
||||
|
||||
Esto actualiza:
|
||||
- `/root/.hermes/skills/skeen-services.json`
|
||||
- `/root/skeen-roadmap-hermes/hermes/skills/skeen-services.json`
|
||||
|
||||
---
|
||||
|
||||
## 9. Problemas Comunes
|
||||
|
||||
### 9.1 Registros duplicados
|
||||
|
||||
**Problema:** Al re-ejecutar la migración, se crean duplicados.
|
||||
|
||||
**Solución:** Usar `--purge-citas --purge-sql` antes de importar.
|
||||
|
||||
### 9.2 Timeout en importación masiva
|
||||
|
||||
**Problema:** Miles de registros tardan demasiado.
|
||||
|
||||
**Solución:** Usar `--purge-sql` para limpieza rápida, y considerar dividir en lotes.
|
||||
|
||||
### 9.3 Campos faltantes en CSV
|
||||
|
||||
**Problema:** Algunos CSVs no tienen todos los campos.
|
||||
|
||||
**Solución:** Los scripts tienen valores por defecto. Revisar los warnings en la salida.
|
||||
|
||||
### 9.4 Teléfonos con formato incorrecto
|
||||
|
||||
**Problema:** Números de teléfono con formato local.
|
||||
|
||||
**Solución:** Normalizar a formato internacional sin `+` (ej. `526641234567`).
|
||||
|
||||
---
|
||||
|
||||
## 10. Checklist de Migración
|
||||
|
||||
- [ ] Autorización documentada del cliente
|
||||
- [ ] Exportación de datos del sistema legacy
|
||||
- [ ] Backup de base de datos Odoo actual
|
||||
- [ ] Limpieza de datos demo
|
||||
- [ ] Ejecución de scripts de migración
|
||||
- [ ] Validación de conteos
|
||||
- [ ] Validación de muestra aleatoria
|
||||
- [ ] Pruebas funcionales
|
||||
- [ ] Sincronización WACRM
|
||||
- [ ] Regeneración catálogo Hermes
|
||||
- [ ] Reporte de errores y resolución
|
||||
- [ ] Aprobación final del cliente
|
||||
|
||||
---
|
||||
|
||||
## 11. Contacto
|
||||
|
||||
Para dudas sobre migración:
|
||||
- **Email:** ialcarazsalazar@consultoria-as.com
|
||||
- **Gitea:** https://git.consultoria-as.com/consultoria-as/SKEEN-Proyecto
|
||||
327
docs/seguridad.md
Normal file
327
docs/seguridad.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# Seguridad — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Principios de Seguridad
|
||||
|
||||
1. **Defensa en profundidad:** Múltiples capas de seguridad.
|
||||
2. **Principio de menor privilegio:** Acceso mínimo necesario.
|
||||
3. **Datos en tránsito cifrados:** HTTPS/TLS en producción.
|
||||
4. **Datos en reposo protegidos:** PostgreSQL con autenticación, backups cifrados.
|
||||
5. **Secretos fuera del código:** Variables de entorno, nunca hardcoded.
|
||||
6. **Auditoría:** Logs de acceso y cambios.
|
||||
|
||||
---
|
||||
|
||||
## 2. Autenticación y Autorización
|
||||
|
||||
### 2.1 Frontend React (JWT)
|
||||
|
||||
- **Algoritmo:** HMAC-SHA256
|
||||
- **Expiración:** 24 horas
|
||||
- **Payload:** `uid`, `login`, `role`, `exp`
|
||||
- **Roles:** `admin`, `recepcion`, `medico`, `lectura`
|
||||
|
||||
**Generación de token:**
|
||||
```python
|
||||
def sign_token(env, user):
|
||||
payload = {
|
||||
'uid': user.id,
|
||||
'login': user.login,
|
||||
'role': user.role,
|
||||
'exp': int(time.time()) + 86400
|
||||
}
|
||||
secret = env['ir.config_parameter'].sudo().get_param('skeen.frontend.jwt_secret')
|
||||
return jwt.encode(payload, secret, algorithm='HS256')
|
||||
```
|
||||
|
||||
### 2.2 Odoo API (API Key)
|
||||
|
||||
- Endpoints JSON-RPC/XML-RPC usan `auth='api_key'`.
|
||||
- API key almacenada en `ir.config_parameter` o header.
|
||||
|
||||
### 2.3 WACRM API (Bearer Token)
|
||||
|
||||
- API keys creadas en Supabase tabla `api_keys`.
|
||||
- Scopes granulares: `messages:send`, `contacts:read`, etc.
|
||||
|
||||
### 2.4 Supabase (JWT)
|
||||
|
||||
- **Anon Key:** Para operaciones públicas.
|
||||
- **Service Role Key:** Para operaciones administrativas (solo backend).
|
||||
- **Row-Level Security (RLS):** Habilitado en tablas sensibles.
|
||||
|
||||
---
|
||||
|
||||
## 3. Webhooks
|
||||
|
||||
### 3.1 Meta → WACRM
|
||||
|
||||
- **Verify Token:** `skeen_webhook_verify_2026`
|
||||
- **Validación:** GET con `hub.mode`, `hub.verify_token`, `hub.challenge`.
|
||||
|
||||
### 3.2 WACRM → Bridge (HMAC-SHA256)
|
||||
|
||||
**Firma:**
|
||||
```javascript
|
||||
function verifySignature(payload, signature) {
|
||||
const [t, v1] = signature.split(',').map(s => s.split('=')[1]);
|
||||
const expected = crypto.createHmac('sha256', WACRM_WEBHOOK_SECRET)
|
||||
.update(`${t}.${payload}`).digest('hex');
|
||||
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
|
||||
}
|
||||
```
|
||||
|
||||
**Headers:**
|
||||
- `X-WACRM-Signature: t=<timestamp>,v1=<hmac_sha256>`
|
||||
|
||||
**Validación:**
|
||||
1. Extraer timestamp y firma del header.
|
||||
2. Calcular HMAC-SHA256 de `timestamp.payload`.
|
||||
3. Comparar con firma recibida (timing-safe).
|
||||
4. Rechazar si timestamp es muy antiguo (> 5 min).
|
||||
|
||||
---
|
||||
|
||||
## 4. Protección de Datos
|
||||
|
||||
### 4.1 Datos Sensibles
|
||||
|
||||
| Dato | Protección |
|
||||
|------|-----------|
|
||||
| Teléfonos | RLS en Supabase, validación en Odoo |
|
||||
| Emails | RLS, enmascaramiento en logs |
|
||||
| Historial médico | Acceso restringido por rol |
|
||||
| Datos de pago | Nunca almacenar tarjetas, usar tokens |
|
||||
| API keys | Variables de entorno, nunca commiteadas |
|
||||
|
||||
### 4.2 Enmascaramiento en Logs
|
||||
|
||||
```python
|
||||
def mask_phone(phone):
|
||||
if len(phone) > 4:
|
||||
return phone[:3] + '*' * (len(phone) - 7) + phone[-4:]
|
||||
return '***'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Seguridad en Red
|
||||
|
||||
### 5.1 Firewall
|
||||
|
||||
```bash
|
||||
# Solo puertos necesarios
|
||||
sudo ufw allow 22/tcp # SSH
|
||||
sudo ufw allow 80/tcp # HTTP
|
||||
sudo ufw allow 443/tcp # HTTPS
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
### 5.2 nginx
|
||||
|
||||
```nginx
|
||||
# Rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
|
||||
server {
|
||||
location /api/ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
proxy_pass http://localhost:8069;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 HTTPS
|
||||
|
||||
Configurar SSL en producción:
|
||||
|
||||
```bash
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
sudo certbot --nginx -d skeen.consultoria-as.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Gestión de Secretos
|
||||
|
||||
### 6.1 Variables de Entorno
|
||||
|
||||
**Nunca commitear:**
|
||||
- `.env`
|
||||
- `.env.local`
|
||||
- `*.key`
|
||||
- `*.pem`
|
||||
- Tokens de Meta
|
||||
- Keys de Stripe/MercadoPago
|
||||
|
||||
### 6.2 .gitignore
|
||||
|
||||
```gitignore
|
||||
# Secretos
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
*.key
|
||||
*.pem
|
||||
*.crt
|
||||
*.pfx
|
||||
*.p12
|
||||
*.keystore
|
||||
*.jks
|
||||
```
|
||||
|
||||
### 6.3 Rotación de Secretos
|
||||
|
||||
| Secreto | Frecuencia | Método |
|
||||
|---------|-----------|--------|
|
||||
| Meta Access Token | 60 días | Meta Developers |
|
||||
| WACRM API Key | 90 días | Dashboard WACRM |
|
||||
| Supabase JWT | 180 días | Regenerar |
|
||||
| Odoo admin password | 90 días | Cambiar manual |
|
||||
| ENCRYPTION_KEY | 365 días | Regenerar (requiere re-encrypt) |
|
||||
|
||||
---
|
||||
|
||||
## 7. Auditoría y Logs
|
||||
|
||||
### 7.1 Logs de Odoo
|
||||
|
||||
```bash
|
||||
tail -f /tmp/odoo.log | grep "audit"
|
||||
```
|
||||
|
||||
### 7.2 Logs de WACRM
|
||||
|
||||
```bash
|
||||
tail -f /tmp/wacrm.log
|
||||
```
|
||||
|
||||
### 7.3 Logs del Bridge
|
||||
|
||||
```bash
|
||||
tail -f /tmp/hermes-bridge.log
|
||||
```
|
||||
|
||||
### 7.4 Auditoría de Base de Datos
|
||||
|
||||
```sql
|
||||
-- Cambios en pacientes
|
||||
SELECT * FROM audit_log WHERE model = 'res.partner' ORDER BY create_date DESC LIMIT 100;
|
||||
|
||||
-- Accesos a datos sensibles
|
||||
SELECT * FROM audit_log WHERE model = 'skeen.cita' AND method = 'read' ORDER BY create_date DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Backups
|
||||
|
||||
### 8.1 Estrategia
|
||||
|
||||
| Tipo | Frecuencia | Retención | Ubicación |
|
||||
|------|-----------|-----------|-----------|
|
||||
| PostgreSQL Odoo | Diario | 30 días | Local + remoto |
|
||||
| PostgreSQL Supabase | Diario | 30 días | Local + remoto |
|
||||
| Archivos | Semanal | 12 semanas | Local + remoto |
|
||||
| Configuración | Mensual | 12 meses | Git |
|
||||
|
||||
### 8.2 Scripts
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup-daily.sh
|
||||
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_DIR=/root/backups
|
||||
|
||||
# PostgreSQL Odoo
|
||||
pg_dump -U skeen -h localhost skeen_odoo | gzip > $BACKUP_DIR/odoo_$DATE.sql.gz
|
||||
|
||||
# PostgreSQL Supabase
|
||||
docker exec supabase-db pg_dump -U postgres postgres | gzip > $BACKUP_DIR/supabase_$DATE.sql.gz
|
||||
|
||||
# Archivos
|
||||
tar -czf $BACKUP_DIR/files_$DATE.tar.gz \
|
||||
/root/skeen-frontend \
|
||||
/root/skeen-wacrm \
|
||||
/root/skeen-odoo/addons/skeen_* \
|
||||
/root/skeen-roadmap-hermes \
|
||||
/root/migracion
|
||||
|
||||
# Limpiar backups antiguos
|
||||
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
|
||||
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Respuesta a Incidentes
|
||||
|
||||
### 9.1 Detección
|
||||
|
||||
- Monitoreo Uptime Kuma.
|
||||
- Alertas de errores en logs.
|
||||
- Alertas de uso anormal de API.
|
||||
|
||||
### 9.2 Contención
|
||||
|
||||
1. Identificar componente afectado.
|
||||
2. Aislar componente (stop service, block IP).
|
||||
3. Evaluar impacto (datos expuestos, usuarios afectados).
|
||||
|
||||
### 9.3 Erradicación
|
||||
|
||||
1. Cerrar vulnerabilidad.
|
||||
2. Cambiar secretos comprometidos.
|
||||
3. Restaurar desde backup limpio si es necesario.
|
||||
|
||||
### 9.4 Recuperación
|
||||
|
||||
1. Restaurar servicios.
|
||||
2. Verificar integridad de datos.
|
||||
3. Monitorear post-incidente.
|
||||
|
||||
### 9.5 Lecciones Aprendidas
|
||||
|
||||
1. Documentar incidente.
|
||||
2. Actualizar procedimientos.
|
||||
3. Mejorar controles.
|
||||
|
||||
---
|
||||
|
||||
## 10. Checklist de Seguridad
|
||||
|
||||
### Pre-Producción
|
||||
|
||||
- [ ] HTTPS configurado
|
||||
- [ ] Firewall configurado
|
||||
- [ ] Secretos rotados
|
||||
- [ ] API keys con scopes mínimos
|
||||
- [ ] RLS habilitado en Supabase
|
||||
- [ ] Rate limiting configurado
|
||||
- [ ] Logs de auditoría activos
|
||||
- [ ] Backups automatizados
|
||||
- [ ] Monitoreo configurado
|
||||
|
||||
### Producción
|
||||
|
||||
- [ ] Revisión mensual de logs
|
||||
- [ ] Rotación trimestral de secretos
|
||||
- [ ] Pruebas de penetración anuales
|
||||
- [ ] Actualizaciones de seguridad mensuales
|
||||
- [ ] Verificación de backups mensual
|
||||
- [ ] Revisión de accesos trimestral
|
||||
|
||||
---
|
||||
|
||||
## 11. Contacto de Seguridad
|
||||
|
||||
Para reportar vulnerabilidades:
|
||||
- **Email:** ialcarazsalazar@consultoria-as.com
|
||||
- **PGP:** (a configurar)
|
||||
|
||||
**No divulgar públicamente** hasta que se haya resuelto.
|
||||
387
docs/skills-hermes.md
Normal file
387
docs/skills-hermes.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# Skills de Hermes — SKEEN Derma Experts
|
||||
|
||||
**Versión:** 2.0
|
||||
**Fecha:** 16 de julio de 2026
|
||||
|
||||
---
|
||||
|
||||
## 1. Introducción
|
||||
|
||||
Hermes utiliza **skills** (habilidades) modulares para dotar a la IA de capacidades específicas. Cada skill es un directorio con un archivo `SKILL.md` que define:
|
||||
|
||||
- **Metadata:** Nombre, descripción, versión, requisitos.
|
||||
- **Instrucciones:** Qué hacer y cómo responder.
|
||||
- **Tools:** Herramientas disponibles.
|
||||
- **Triggers:** Palabras clave que activan el skill.
|
||||
|
||||
---
|
||||
|
||||
## 2. Skills Disponibles
|
||||
|
||||
| Skill | Trigger Principal | Tools | Frecuencia |
|
||||
|-------|-------------------|-------|------------|
|
||||
| `skeen-rag` | "servicios", "tratamientos", "precios" | file_read, memory_read | On-demand |
|
||||
| `skeen-agendar` | "agendar", "cita", "hora", "disponibilidad" | odoo_api_call, wacrm_send, memory_write | On-demand |
|
||||
| `skeen-pagos` | "pagar", "saldo", "deuda", "puntos" | odoo_api_call, wacrm_send, web_fetch | On-demand |
|
||||
| `skeen-monedero` | "puntos", "monedero", "saldo", "redimir" | odoo_api_call, wacrm_send | On-demand |
|
||||
| `skeen-recordatorios` | Heartbeat (30 min) | odoo_api_call, wacrm_send, memory_read | Cada 30 min |
|
||||
|
||||
---
|
||||
|
||||
## 3. Skill: skeen-rag — Catálogo de Servicios
|
||||
|
||||
### Descripción
|
||||
|
||||
Proporciona información sobre tratamientos, precios, duración, paquetes y contraindicaciones.
|
||||
|
||||
### Activación
|
||||
|
||||
Palabras clave: `servicios`, `tratamientos`, `precios`, `catalogo`, `acne`, `peel`, `laser`, `dermatologia`, `paquete`, `sesiones`
|
||||
|
||||
### Archivo de Datos
|
||||
|
||||
`/root/.hermes/skills/skeen-services.json`
|
||||
|
||||
**Formato:**
|
||||
```json
|
||||
{
|
||||
"clinica": {
|
||||
"nombre": "SKEEN Derma Experts",
|
||||
"direccion": "Blvd. Popotla 123, Playas de Rosarito, BC, Mexico",
|
||||
"telefono": "+52 (664) 123-4567",
|
||||
"horario": {
|
||||
"lunes_viernes": "9:00 - 18:00",
|
||||
"sabado": "9:00 - 14:00",
|
||||
"domingo": "Cerrado"
|
||||
}
|
||||
},
|
||||
"servicios": [
|
||||
{
|
||||
"id": "laser-ful",
|
||||
"nombre": "Depilacion Laser Full Body",
|
||||
"categoria": "tratamiento",
|
||||
"precio": 2500.0,
|
||||
"duracion_min": 90,
|
||||
"precio_paquete": 7000.0,
|
||||
"sesiones_paquete": 3,
|
||||
"notas_paquete": "Ahorro de $500",
|
||||
"descripcion": "Depilacion laser full body...",
|
||||
"contraindicaciones": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Instrucciones del Skill
|
||||
|
||||
1. Leer el archivo de catálogo.
|
||||
2. Filtrar servicios relevantes según la pregunta.
|
||||
3. Presentar información de forma clara y amigable.
|
||||
4. SIEMPRE incluir: nombre, precio por sesión, duración, descripción.
|
||||
5. Si el servicio tiene paquete, mencionar ahorro.
|
||||
6. NUNCA diagnosticar condiciones médicas.
|
||||
7. Si no encuentra el servicio, ofrecer consulta de valoración.
|
||||
|
||||
### Ejemplo de Respuesta
|
||||
|
||||
```
|
||||
Hola! En SKEEN contamos con estos tratamientos para depilación:
|
||||
|
||||
1. **Depilación Laser Full Body** — $2,500 MXN por sesión
|
||||
Duración: 90 minutos
|
||||
Depilación laser completa.
|
||||
Paquete de 3 sesiones: $7,000 MXN (ahorro de $500)
|
||||
|
||||
2. **Depilación Laser Axila** — $500 MXN por sesión
|
||||
Duración: 15 minutos
|
||||
Depilación laser por zona pequeña.
|
||||
|
||||
¿Te gustaría agendar una consulta de valoración?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Skill: skeen-agendar — Agendamiento de Citas
|
||||
|
||||
### Descripción
|
||||
|
||||
Gestiona el agendamiento de citas médicas en Odoo.
|
||||
|
||||
### Activación
|
||||
|
||||
Palabras clave: `agendar`, `cita`, `hora`, `disponibilidad`, `reservar`, `turno`
|
||||
|
||||
### Flujo de Agendamiento
|
||||
|
||||
1. **Detectar intención:** Paciente quiere agendar.
|
||||
2. **Consultar servicios:** Usar `skeen-rag` para mostrar opciones.
|
||||
3. **Seleccionar servicio:** Paciente elige tratamiento.
|
||||
4. **Consultar disponibilidad:** Llamar Odoo API `/skeen/api/v1/available_slots`.
|
||||
5. **Presentar opciones:** Mostrar fechas/horas disponibles.
|
||||
6. **Confirmar:** Paciente confirma fecha/hora.
|
||||
7. **Crear cita:** Llamar Odoo API `/skeen/api/v1/create_appointment`.
|
||||
8. **Confirmar al paciente:** Enviar mensaje con detalles.
|
||||
|
||||
### Paquetes de Sesiones
|
||||
|
||||
Si el servicio tiene `package_sessions > 0`:
|
||||
|
||||
1. Informar que existe paquete y su precio.
|
||||
2. Preguntar si quiere sesión individual o paquete.
|
||||
3. Si elige paquete:
|
||||
- Crear N citas separadas (cada 7 días).
|
||||
- La primera a la hora elegida.
|
||||
- Las siguientes a las 9:00 AM (reprogramables).
|
||||
|
||||
### Ejemplo de Respuesta
|
||||
|
||||
```
|
||||
Perfecto! Has elegido Depilación Laser Full Body.
|
||||
|
||||
Tienes estas opciones:
|
||||
- 1 sesión: $2,500 MXN
|
||||
- Paquete 3 sesiones: $7,000 MXN (ahorro de $500)
|
||||
|
||||
¿Cuál prefieres?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Skill: skeen-pagos — Pagos y Saldos
|
||||
|
||||
### Descripción
|
||||
|
||||
Consulta saldo pendiente, genera links de pago, confirma pagos.
|
||||
|
||||
### Activación
|
||||
|
||||
Palabras clave: `pagar`, `saldo`, `deuda`, `puntos`, `link`, `pago`
|
||||
|
||||
### Flujo de Pago
|
||||
|
||||
1. **Consultar saldo:** Llamar Odoo API `/skeen/api/v1/patient_balance`.
|
||||
2. **Mostrar saldo:** Informar monto pendiente y puntos disponibles.
|
||||
3. **Generar link:** Crear link de pago (Stripe/MercadoPago).
|
||||
4. **Enviar link:** Via WhatsApp.
|
||||
5. **Confirmar pago:** Webhook de pasarela → Odoo.
|
||||
|
||||
### Ejemplo de Respuesta
|
||||
|
||||
```
|
||||
Tu saldo pendiente es de $1,500 MXN.
|
||||
|
||||
Tienes 450 puntos en tu monedero (equivalente a $450 MXN).
|
||||
|
||||
¿Quieres que te envíe un link de pago? Puedes pagar con tarjeta o MercadoPago.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Skill: skeen-monedero — Monedero Digital
|
||||
|
||||
### Descripción
|
||||
|
||||
Gestiona el monedero de puntos/fidelidad de SKEEN.
|
||||
|
||||
### Reglas
|
||||
|
||||
- **Acumulación:** 1 punto por cada $10 MXN gastados.
|
||||
- **Valor:** 1 punto = $1 MXN.
|
||||
- **Redención:** Máximo 50% del total de la compra.
|
||||
- **Vencimiento:** Puntos vencen a los 12 meses de inactividad.
|
||||
- **No transferibles:** Entre pacientes.
|
||||
- **Acumulación:** Solo en pagos confirmados.
|
||||
|
||||
### Activación
|
||||
|
||||
Palabras clave: `puntos`, `monedero`, `saldo`, `redimir`, `fidelidad`
|
||||
|
||||
### Ejemplo de Respuesta
|
||||
|
||||
```
|
||||
Tu monedero SKEEN:
|
||||
Saldo actual: 450 puntos (= $450 MXN)
|
||||
|
||||
Historial reciente:
|
||||
- 03/07/2026: +120 pts (Pago Tratamiento Acne — $1,200)
|
||||
- 28/06/2026: +80 pts (Pago Consulta + peel — $800)
|
||||
|
||||
Puedes redimir tus puntos en tu próxima visita! Cada 10 puntos = $10 MXN de descuento.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Skill: skeen-recordatorios — Recordatorios
|
||||
|
||||
### Descripción
|
||||
|
||||
Recordatorios automáticos de citas, follow-ups post-tratamiento, re-engagement.
|
||||
|
||||
### Activación
|
||||
|
||||
**Heartbeat:** Cada 30 minutos.
|
||||
|
||||
### Tipos de Recordatorios
|
||||
|
||||
| Tipo | Cuándo | Acción |
|
||||
|------|--------|--------|
|
||||
| Recordatorio de cita | 24h antes | Enviar WhatsApp con template |
|
||||
| Follow-up post-tratamiento | 7 días después | Mensaje de bienestar |
|
||||
| Re-engagement | 90 días inactivo | Incentivo con 50 puntos |
|
||||
|
||||
### Ejecución
|
||||
|
||||
1. Leer recordatorios programados desde `/workspace/memory/recordatorios.md`.
|
||||
2. Buscar entradas vencidas (timestamp <= ahora).
|
||||
3. Enviar via WACRM usando template aprobado.
|
||||
4. Marcar como enviado en memoria.
|
||||
|
||||
### Templates de WhatsApp
|
||||
|
||||
```
|
||||
recordatorio_cita_skeen:
|
||||
"Hola {{1}}! Te recordamos tu cita mañana {{2}} a las {{3}} en SKEEN Derma Experts."
|
||||
|
||||
followup_tratamiento_skeen:
|
||||
"Hola {{1}}! Han pasado {{2}} días desde tu {{3}}. ¿Cómo te sientes?"
|
||||
|
||||
reengage_skeen:
|
||||
"Hola {{1}}! Te extrañamos en SKEEN. Agenda tu próxima visita y recibe 50 puntos."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Personalidad de Sofía
|
||||
|
||||
### Archivo: SOUL.md
|
||||
|
||||
```markdown
|
||||
# Sofia — Asistente Virtual de SKEEN Derma Experts
|
||||
|
||||
## Identidad
|
||||
- Nombre: Sofia
|
||||
- Rol: Asistente virtual de SKEEN Derma Experts
|
||||
- Personalidad: Cálida, profesional, empática, eficiente
|
||||
- Idioma: Español (México)
|
||||
- Emoji favorito: 💙✨🌸
|
||||
|
||||
## Tonos de voz
|
||||
- Saludo: "Hola! Soy Sofia de SKEEN 💙"
|
||||
- Confirmación: "Perfecto! Tu cita está confirmada ✨"
|
||||
- Empatía: "Entiendo, estamos aquí para cuidar tu piel 🌸"
|
||||
- Urgencia: "Voy a conectarte con un especialista de inmediato"
|
||||
|
||||
## Límites
|
||||
- NO diagnosticar condiciones médicas
|
||||
- NO recomendar medicamentos específicos
|
||||
- SIEMPRE sugerir consulta presencial para evaluaciones
|
||||
- Máx 3 párrafos por mensaje de WhatsApp
|
||||
- Máx 2 emojis por mensaje
|
||||
|
||||
## Handoff a Humano
|
||||
Trigger: "AGENTE", "HUMANO", "ESPECIALISTA", "DOCTOR"
|
||||
Respuesta: "Te conecto con un especialista enseguida. Espera un momento 💙"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. System Prompt del Bridge
|
||||
|
||||
El bridge (`webhook-bridge.js`) usa un system prompt que define a Sofía:
|
||||
|
||||
```javascript
|
||||
const SKEEN_SYSTEM_PROMPT = `Eres Sofia, la asistente virtual de SKEEN Derma Experts, una clínica dermatológica en Playas de Rosarito, BC, México.
|
||||
|
||||
PERSONALIDAD:
|
||||
- Cálida, profesional, empática y eficiente.
|
||||
- Hablas español mexicano natural.
|
||||
- Usas emojis moderadamente (máx 2 por mensaje).
|
||||
|
||||
REGLAS ESTRICTAS:
|
||||
1. NUNCA diagnostiques condiciones médicas.
|
||||
2. NUNCA recomiendes medicamentos específicos.
|
||||
3. SIEMPRE sugiere consulta presencial para evaluaciones.
|
||||
4. Máximo 3 párrafos por respuesta.
|
||||
5. Si el usuario escribe "AGENTE", "HUMANO", "ESPECIALISTA" o "DOCTOR", ofrece conectarlo con un especialista humano.
|
||||
|
||||
DATOS DE LA CLÍNICA:
|
||||
- Nombre: SKEEN Derma Experts
|
||||
- Dirección: Blvd. Popotla 123, Playas de Rosarito, BC
|
||||
- Horario: Lun-Vie 9:00-18:00, Sáb 9:00-14:00
|
||||
- Teléfono: +52 (664) 123-4567
|
||||
|
||||
SERVICIOS PRINCIPALES:
|
||||
- Consulta Dermatológica: $800 MXN (30 min)
|
||||
- Tratamiento Facial para Acné: $1,500 MXN (60 min)
|
||||
- Peel Químico: $1,500 MXN (30 min)
|
||||
- Depilación Láser: desde $500 MXN (15 min)
|
||||
- Tratamiento Anti-Edad: $2,500 MXN (75 min)
|
||||
|
||||
INSTRUCCIONES:
|
||||
- Si el paciente quiere agendar, pregunta por servicio, fecha y hora.
|
||||
- Si pregunta por servicios, usa la lista de arriba.
|
||||
- Si pregunta por precios, menciona que son aproximados.
|
||||
- Siempre termina con una pregunta o invitación a agendar.`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Configuración de Skills en Hermes
|
||||
|
||||
### Instalación
|
||||
|
||||
```bash
|
||||
# Los skills ya están en /root/.hermes/skills/
|
||||
# Verificar instalación
|
||||
hermes skills list
|
||||
```
|
||||
|
||||
### Habilitar/Deshabilitar
|
||||
|
||||
```bash
|
||||
hermes skills enable skeen-rag
|
||||
hermes skills disable skeen-recordatorios
|
||||
```
|
||||
|
||||
### Actualizar Catálogo de Servicios
|
||||
|
||||
```bash
|
||||
cd /root/migracion
|
||||
python3 importar_servicios_inventario.py --solo-hermes
|
||||
```
|
||||
|
||||
Esto regenera `/root/.hermes/skills/skeen-services.json` desde Odoo.
|
||||
|
||||
---
|
||||
|
||||
## 11. Troubleshooting
|
||||
|
||||
### Skill no se activa
|
||||
|
||||
1. Verificar que el skill esté enabled: `hermes skills list`
|
||||
2. Verificar palabras clave en `SKILL.md` metadata.
|
||||
3. Verificar que el archivo JSON de datos exista.
|
||||
|
||||
### Respuestas incorrectas
|
||||
|
||||
1. Revisar system prompt en `webhook-bridge.js`.
|
||||
2. Revisar `SOUL.md` y `AGENTS.md`.
|
||||
3. Verificar que el modelo sea correcto (Qwen3.6).
|
||||
|
||||
### No se crean citas
|
||||
|
||||
1. Verificar API key de Odoo.
|
||||
2. Verificar que el paciente exista o se pueda crear.
|
||||
3. Revisar logs de Odoo: `tail -f /tmp/odoo.log`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Mejoras Futuras
|
||||
|
||||
| Mejora | Descripción | Prioridad |
|
||||
|--------|-------------|-----------|
|
||||
| Integración Hermes Gateway nativa | Usar gateway de Hermes en lugar de bridge custom | Media |
|
||||
| Skills de reportes | Generar reportes via WhatsApp | Baja |
|
||||
| Multi-idioma | Soporte inglés | Baja |
|
||||
| Voz | Integración con voz de WhatsApp | Baja |
|
||||
| Analytics | Tracking de conversaciones | Media |
|
||||
Reference in New Issue
Block a user