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>
6.3 KiB
Art4Hotel Hub — Índice y Contexto para Claude
Punto de entrada. Aquí está el mapa de TODO: documentación, sitios/servicios y accesos. Última actualización: 2026-06-06
📚 ÍNDICE DE DOCUMENTACIÓN (qué hay y dónde)
| Documento | Cubre | Léelo cuando… |
|---|---|---|
| NEGOCIO.md | Contexto del negocio: clientes, productos, flujo real, equipo, reglas | …antes de cualquier cambio (la app refleja el negocio) |
| CONTEXTO.md | Estado técnico del Hub: stack, modelo de datos, producto unificado, catálogos, galería de ejemplos, archivos, ventas | …vas a tocar código del Hub |
| WEB.md | Sitio público art4hotel.com + sync_catalogo.py (Hub → web) |
…trabajas en la página pública o el sync |
| ONBOARDING.md | Handover: acceso, arquitectura, tabs del SPA, fórmula de margen | …repaso general rápido |
| VALOR_SISTEMA.html | Valor/costo del sistema, hosting, esquema (para presentar a terceros) | …explicar el sistema o cotizarlo a alguien |
| ACCESOS.html | Tarjeta de accesos de usuario final (links de servicios) | …recordar cómo entrar a cada servicio |
🌐 MAPA DE SITIOS / SERVICIOS (servidor "iclaude")
Todo corre en el servidor iclaude (192.168.50.46, una Surface vieja). Acceso por Tailscale (red privada) salvo lo marcado público.
Proyectos web (cada uno su propio puerto, todos del usuario)
Cada sitio tiene acceso directo por Tailscale (iclaude:PUERTO, requiere Tailscale activo) y, si está en Funnel, también una URL pública (desde cualquier lado, sin Tailscale).
| Puerto | Sitio | Acceso privado (Tailscale) | Acceso público (Funnel) | Notas |
|---|---|---|---|---|
| 4401 | Art4Hotel Hub (este proyecto) | http://iclaude:4401 |
— (privado) | Login (usuario claude). Operaciones/ventas/catálogo |
| 4402 | Airbnb Pricing | http://iclaude:4402 |
— (privado) | Panel pricing Airbnb (Hacienda Cabo Bello / Casa Montoya) |
| 4403 | Catálogo | http://iclaude:4403 |
https://iclaude.tail69ab9b.ts.net:8443/ 🌍 |
Login. Público vía Funnel |
| 4404 | Portafolio | http://iclaude:4404 |
https://iclaude.tail69ab9b.ts.net/ 🌍 |
Público vía Funnel (raíz) |
Cada proyecto tiene su carpeta y su propia documentación en el servidor:
| Proyecto | Carpeta | Servicio systemd | Su doc |
|---|---|---|---|
| Hub | /mnt/iclaude/art4hotel-hub/ |
art4hotel-hub.service |
este CLAUDE.md + los .md de abajo |
| Airbnb Pricing | /mnt/iclaude/airbnb-pricing/ |
airbnb-pricing.service |
NEGOCIO.md |
| Catálogo | /mnt/iclaude/catalogo-borrador/ |
catalogo-borrador.service |
CLAUDE.md |
| Portafolio/Foto Studio | /mnt/iclaude/foto-studio/ |
foto-studio.service |
CLAUDE.md |
Todos comparten el mismo stack (Python stdlib + SQLite + vanilla JS) y se reinician con sudo systemctl restart <servicio>.
Servicios de nube personal (Docker)
| Servicio | Puerto | Acceso | Usuario |
|---|---|---|---|
| Immich (fotos) | 2283 | iclaude:2283 |
claudeandrefg@gmail.com |
| Filebrowser (archivos) | 8085 | iclaude:8085 |
admin (carpeta /mnt/iclaude/escritorio) |
Sitio público externo
| Sitio | Dónde | Notas |
|---|---|---|
| art4hotel.com | GitHub Pages (NO en el servidor) | Landing + catálogo + wizard de leads. Repo Claudeandrefg/art4hotel. Se alimenta del Hub vía sync_catalogo.py |
🔧 INFRAESTRUCTURA (claves del servidor)
- Acceso admin:
ssh claude@192.168.50.46(oclaude@iclaudepor Tailscale). Usuarioclaude, sudo sin password, llave SSH. - Tailscale: red privada. MagicDNS activo →
iclauderesuelve a100.110.177.1. Tailnet:tail69ab9b.ts.net. Dispositivos: iphone, macbook, pixel. - Tailscale Funnel: expone a internet
:443 → 4404 (Portafolio)y:8443 → 4403 (Catálogo). - ⏰ Reloj: la Surface tiene CMOS muerta (RTC=2009) y NTP bloqueado.
sync_clock.sh(cron @reboot + cada hora) lo corrige desde IPs fijas (1.1.1.1). Si los logins fallan con "logged out due to inactivity" → revisar el reloj (date); era el bug raíz. - DNS: Tailscale ya NO gestiona el DNS (
--accept-dns=false); usa 1.1.1.1/8.8.8.8. Resuelve nombres públicos OK. - RAM: solo 3.7GB (sin ampliar). Apagados Odoo/NocoDB/Jellyfin/qBittorrent/pihole para liberar. NO instalar plataformas pesadas (n8n, etc.) — usar scripts ligeros (Python stdlib/cron).
- Backups: cron diario medianoche →
backup.py(DB + uploads, 30 días enbackups/).
⚠️ Principio clave: producto = fuente única de verdad
Cada atributo de producto impacta hasta 3 funciones. Antes de agregar/cambiar uno, define su impacto en: (1) Operación/producción · (2) Catálogo/cotizador · (3) Página web.
Deploy del Hub
- Host:
claude@192.168.50.46· Path:/mnt/iclaude/art4hotel-hub/ - Restart:
sudo systemctl restart art4hotel-hub - Deploy:
scp index.html server.py claude@192.168.50.46:/mnt/iclaude/art4hotel-hub/ && ssh claude@192.168.50.46 "sudo systemctl restart art4hotel-hub"
Convenciones de edición
- Toda edición a
index.htmloserver.pyse hace LOCAL aquí y se despliega con scp. - Después de cualquier cambio en DB (ALTER TABLE, migración), verificar con SSH que se aplicó.
- No instalar dependencias nuevas — stack es Python stdlib + vanilla JS. Si una feature lo requiere, discutir antes.
- Cambios masivos (renombrar IDs, reorganizar tablas) → backup primero:
cp art4hotel.db art4hotel.db.bak_<fecha>. - Listas de personalización: editar la tabla
trabajosen DB, no hardcodear en index.html. HayTRABAJO_OPTScomo fallback +trabajoOpts()helper que prefiereS.trabajosdinámico.
Tareas frecuentes
- Ver duplicados:
python3 -c "import sqlite3; c=sqlite3.connect('art4hotel.db'); print(list(c.execute('SELECT orden_id,COUNT(*) FROM ordenes GROUP BY orden_id HAVING COUNT(*)>1')))" - Backup manual:
cp art4hotel.db art4hotel.db.bak_$(date +%Y%m%d_%H%M%S) - Logs del servicio:
sudo journalctl -u art4hotel-hub -n 50 --no-pager
Si Clod te pide algo
- Si es feature nueva → propón primero antes de implementar (usar AskUserQuestion).
- Si es fix → identifica la causa raíz, confírmala con el código y datos, después arregla.
- Si es cambio cosmético → directo, sin overthink.