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

92 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
```yaml
- 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`.