Files
SKEEN-Proyecto/docs/segunda-instancia.md

4.6 KiB
Raw Blame History

Segunda instancia white-label (sin branding SKEEN)

Segunda clínica sobre el mismo código y la misma VPS. La marca no vive en el código: sale del parámetro skeen.clinic.brand (ver GET /skeen/frontend/v1/brand), así que esta y futuras instancias son solo infra + config.

Mapa de la instalación

Componente SKEEN (instancia 1) Clínica 2 (instancia white-label)
Odoo HTTP 8069 8070
Odoo longpolling 8072 8073
Base de datos skeen_odoo clinica2_odoo
Conf /root/skeen-odoo/odoo.conf /root/clinica2-odoo.conf
Systemd odoo-skeen.service odoo-clinica2.service
Frontend /var/www/skeen-frontend /var/www/clinica2-frontend
Nginx vhost skeen-crm (80) vhost clinica2 (80 + 8880)
Acceso LAN http://192.168.10.114 http://192.168.10.114:8880
Acceso público skeen.consultoria-as.com clinica.consultoria-as.com (pendiente: dashboard del túnel)
WhatsApp (WACRM) integrado oculto + bloqueado (escenario B)

addons_path se comparte (read-only): /root/skeen-odoo/addons. Un solo código, N bases de datos.

Cómo se levantó (orden de pasos)

Los archivos canónicos están en infra/clinica2/:

  1. odoo.conf — copia del de SKEEN con db_name=clinica2_odoo, http_port=8070, longpolling_port=8073, data_dir=/var/lib/odoo-clinica2.
  2. Crear la base (el rol skeen no tiene CREATEDB; se crea como postgres): CREATE DATABASE clinica2_odoo OWNER skeen ...
  3. Instalar módulos limpio (sin demo): odoo-bin -c /root/clinica2-odoo.conf -d clinica2_odoo --without-demo=all --init=skeen_whatsapp,skeen_chat,skeen_visitas --stop-after-init --no-http (skeen_whatsapp arrastra citas/pacientes/ventas/pagos/monedero; visitas arrastra inventario).
  4. postinstall.py — brand neutro (skeen.clinic.brand), menú WACRM vacío para todos (skeen.menu_roles), password de admin propio + must_change_password, empresa renombrada.
  5. systemctl enable --now odoo-clinica2.
  6. nginx-vhost → /etc/nginx/sites-enabled/clinica2 + nginx -t && reload.
  7. Frontend: mismo build de SKEEN (rsync -a dist/ /var/www/clinica2-frontend/) más public/brand/ (logos SVG neutros + favicon, versionados en el repo).

Pendiente para acceso público (único paso manual)

El túnel cloudflared corre con --token (remotamente administrado): el config.yml local NO aplica. En el dashboard de Cloudflare (Zero Trust → Networks → Tunnels → f2517233…) agregar el ingress:

- hostname: clinica.consultoria-as.com
  service: http://localhost:80

El vhost nginx ya escucha en el 80 con ese server_name; al agregar el hostname el túnel enruta solo. El 8880 queda como acceso LAN permanente.

Aislamiento de datos (escenario B: sin WhatsApp)

  • Sin SUPABASE_URL / WACRM_API_* / HERMES_BRIDGE_URL en la unit systemd (el backend respondería "Falta configuración").
  • Aun así, el backend tiene fallback a localhost:3000; por eso el vhost nginx corta /api/odoo/skeen/frontend/v1/wacrm/ con return 403; — doble candado, la instancia 2 no puede leer ni escribir las conversaciones de SKEEN aunque alguien llame la API a mano.
  • Menú WACRM oculto para todos los roles vía matriz (/wacrm/*: []).

Para activar WhatsApp en la instancia 2 (escenario A) se necesita: número propio de WhatsApp Business + decisión de WACRM multi-clínica (estimar aparte).

Fix de menús que esta fase destapó (aplica a TODAS las instancias)

Las vistas XML referenciaban skeen_citas.menu_skeen_root, pero skeen_citas depende de skeen_pacientes: en instalación limpia de una sola pasada el xmlid aún no existe y la carga falla (la base de SKEEN se construyó por fases y por eso nunca explotó). Se movió el menú raíz a skeen_pacientes (módulo raíz de la jerarquía) y todas las referencias apuntan a skeen_pacientes.menu_skeen_root. En bases existentes se transfirió el ownership del xmlid (UPDATE ir_model_data SET module='skeen_pacientes' …), así actualizar no duplica el menú. Mismo tratamiento para el menú padre de Citas (skeen_citas/views/menus.xml carga antes que bloqueos/lista de espera).

Operación habitual

  • Logs: tail -f /tmp/odoo2.log (instancia 2) vs /tmp/odoo.log (SKEEN).
  • Ambas instancias comparten código: un git pull + rebuild afecta el build de ambas solo si se vuelven a copiar los dist/ (cada uno tiene el suyo).
  • Para una tercera clínica: repetir pasos 1–7 con clinica3 (puertos 8074/8075, db clinica3_odoo, vhost propio) y setear su brand desde Configuración → Clínica o con PUT /brand.