Art4Hotel Hub: código + documentación extensiva

ERP a la medida (Python stdlib + SQLite + vanilla JS SPA).
Incluye server.py, index.html, utilidades y documentación:
README, MODELO_DATOS, API, INSTALACION, CONTEXTO, NEGOCIO,
WEB, ONBOARDING, VALOR_SISTEMA, CLAUDE.

Secretos y datos (art4hotel.db, secret.key, ACCESOS.html,
uploads/, backups/) excluidos vía .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
consultoria-as
2026-06-09 00:10:07 -07:00
commit c2ae140078
16 changed files with 12675 additions and 0 deletions

122
INSTALACION.md Normal file
View File

@@ -0,0 +1,122 @@
# Instalación y Despliegue — Art4Hotel Hub
Sin Docker, sin pip, sin CI/CD. Solo Python 3 y `systemd`.
---
## Requisitos
- **Python 3.8+** (stdlib únicamente — `http.server`, `sqlite3`, `hashlib`, `hmac`)
- Linux con `systemd` (para correr como servicio). En Windows/Mac corre igual con `python3 server.py`.
---
## 1. Desarrollo local
```bash
git clone https://git.consultoria-as.com/consultoria-as/art4hotel-hub.git
cd art4hotel-hub
python3 server.py
# → http://localhost:4401
```
Primera vez: la app pide **crear la cuenta admin** (pantalla de setup). Genera `art4hotel.db` y `secret.key` automáticamente.
---
## 2. Despliegue en servidor
### a) Copiar archivos
```bash
scp server.py index.html backup.py usuario@servidor:/ruta/art4hotel-hub/
```
> **No copiar** `secret.key` ni `art4hotel.db` desde tu máquina local — el servidor genera los suyos en el primer arranque (o migra los existentes en producción). Los datos del negocio viven solo en el servidor.
### b) Servicio systemd
`/etc/systemd/system/art4hotel-hub.service`:
```ini
[Unit]
Description=Art4Hotel Hub
After=network.target
[Service]
Type=simple
User=claude
WorkingDirectory=/ruta/art4hotel-hub
ExecStart=/usr/bin/python3 server.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now art4hotel-hub
sudo systemctl status art4hotel-hub
```
### c) Redespliegue (actualizar código)
```bash
scp server.py index.html usuario@servidor:/ruta/art4hotel-hub/
ssh usuario@servidor 'sudo systemctl restart art4hotel-hub'
```
Las migraciones de esquema corren solas al reiniciar (idempotentes).
---
## 3. Acceso remoto (Tailscale)
El Hub vive en una red privada **Tailscale** (MagicDNS `iclaude`):
- **Privado** (equipos en la tailnet): `http://iclaude:4401/`
- **Público** (si se requiere exponer): Tailscale **Funnel** en un puerto dedicado (443/8443/10000).
```bash
tailscale funnel --bg 4401 # expone el Hub públicamente
tailscale funnel status # ver qué está expuesto
```
> Nota de seguridad: el Hub ya tiene login propio, pero exponerlo públicamente amplía la superficie de ataque. Mantener el login activo y contraseñas fuertes.
---
## 4. Respaldos
`backup.py` por cron diario:
```cron
0 3 * * * cd /ruta/art4hotel-hub && /usr/bin/python3 backup.py
```
Hace: online backup de la DB (seguro con WAL) + `uploads.tar.gz`. Retiene 30 días en `backups/`.
También disponible bajo demanda desde la UI (`POST /api/backup-now`).
---
## 5. Reloj del servidor (importante)
El servidor de producción tiene CMOS muerto y NTP bloqueado; un reloj desfasado **rompe los logins basados en token** (Filebrowser/Immich) y firma de sesiones.
Mitigación: cron `sync_clock.sh` que toma el header `Date` de `1.1.1.1` y ajusta la hora. Verificar `date` tras reinicios.
---
## 6. Solución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
| "Sesión inválida" constante | reloj del servidor desfasado | corregir hora; revisar `sync_clock.sh` |
| `secret.key` regenerado → todos deslogueados | se borró/cambió la clave | restaurar `secret.key`; es la clave de firma |
| Imágenes equivocadas como ejemplo | prefijos de archivo | ver lógica `first_image` en `/api/file-counts` |
| No resuelve nombres públicos | DNS de Tailscale sin upstream | `tailscale set --accept-dns=false` |
---
*Stack deliberadamente mínimo: todo el sistema cabe en una USB y corre con un solo `python3 server.py`.*