Builder multi-proveedor de servicios (tour / A&B / transportacion). Python stdlib + SQLite + vanilla JS SPA. Hereda filosofia del Hub. Secretos y datos (catalogo.db, secret.key, uploads/) excluidos via .gitignore. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.6 KiB
Catálogo (borrador) — Contexto para Claude
Builder de catálogo multi-proveedor de servicios (no productos físicos). Hereda la filosofía del Art4Hotel Hub. Proyecto independiente, no toca el Hub.
Qué es
Sistema interno para armar la base de datos de un catálogo de servicios de varios touroperadores / proveedores. Tres tipos de servicio:
- tour · ayb (A&B / banquetes) · transportacion
Objetivo final (fases siguientes): usar esta DB para propuestas y una página web de catálogo online optimizado. Por ahora el foco es el builder (captura de datos + fotos).
⚠️ Principio clave (del Hub): el servicio = fuente única de verdad
Cada atributo de un servicio impacta hasta 3 funciones. Antes de agregar/cambiar uno, define su impacto en:
- Operación — disponibilidad, horarios, capacidad, precio neto
- Propuesta / cotizador — lo que ve el cliente, precio público, términos
- Página web — catálogo online
Neto vs público: precio_neto = lo que cobra el proveedor · precio_publico = lo que paga el cliente.
El margen vive en medio y nunca se mezcla con lo que ve el cliente.
Stack
- Backend: Python 3 stdlib (
http.server+sqlite3), zero deps. WAL + FK on. - Frontend: SPA vanilla JS (
index.html), sin frameworks. - CRUD genérico vía dict
TABLESenserver.py(un solo handler POST/PUT/DELETE para todas las tablas). - Auth: usuario/contraseña (PBKDF2) + cookie de sesión firmada (HMAC).
needs_setupen primer acceso.
Acceso al server
- Host:
claude@100.110.177.1(Tailscaleiclaude) / red local192.168.50.46 - Path:
/mnt/iclaude/catalogo-borrador/ - Puerto: 4403 (4401 = Hub, 4402 = airbnb-pricing)
- URL:
http://iclaude:4403/http://192.168.50.46:4403 - Servicio:
sudo systemctl restart catalogo-borrador - Deploy:
scp index.html server.py claude@100.110.177.1:/mnt/iclaude/catalogo-borrador/ && ssh claude@100.110.177.1 "sudo systemctl restart catalogo-borrador" - Logs:
sudo journalctl -u catalogo-borrador -n 50 --no-pager
Modelo de datos (SQLite)
proveedores— quién ofrece (nombre, tipo_principal, contacto, comision_default, …)servicios— fuente única de verdad (FK proveedor_id). Campos por sección de impacto:- 📋 Identidad: nombre, tipo, categoria, codigo, descripcion
- ⚙️ Operación: horarios, capacidad_min/max, restricciones +
atributos(JSON específico por tipo) - 💰 Comercial: precio_neto, precio_publico, moneda, unidad, tarifas_adicionales
- 📄 Condiciones: terminos
- 🌐 Publicación: mostrar_en_web
usuarios— auth
Atributos flexibles por tipo (servicios.atributos, JSON)
En vez de columnas rígidas, los extras específicos van en JSON. Sugeridos por tipo (en index.html → ATRIBUTOS):
- tour: duracion, punto_encuentro, incluye, no_incluye, idioma
- ayb: tipo_menu, min_personas, montaje, servicio_incluido, opciones_dieta
- transportacion: tipo_vehiculo, pasajeros, ruta_zona, chofer, tiempo_espera
Disponibilidad — modos (servicios.modo_disponibilidad + horarios JSON)
Eje independiente del tipo. modo_disponibilidad: salidas | rango | siempre (24/7) | por_evento.
Default sugerido por tipo (MODO_DEFAULT: tour→salidas, transportacion→siempre, ayb→por_evento), editable. El editor (renderDisp) cambia los controles según el modo:
- salidas: editor semanal de días + varias salidas por día →
horarios={"Lun":["08:00","14:00"],...}. (+ salidaagrega varias;parseHor/fmtHorGroups/compactDiaspara mostrar.) - rango: días + ventana →
horarios={"dias":[...],"desde":"06:00","hasta":"22:00"}. - siempre / por_evento:
horarios={} (sin horario; la reserva es por fecha).dispShort(s)arma el texto de disponibilidad según el modo (usado en vista cliente). Compat: servicios viejos sinmodo=salidascon suhorariosdía-keyed.
Alimentos / Menú (opcional, flexible)
servicios.incluye_alimentos (0/1) + menu_detalle (texto). Fotos del menú: se suben con tipo=menu (prefijo menu_) al mismo uploads/servicio_{id}/; se separan de las fotos del servicio por prefijo (loadPhotos excluye menu_, loadMenuFotos solo menu_). En file-counts el prefijo menu está excluido del first_image (no roba el thumbnail). En vista cliente se muestra el bloque "🍽️ Menú / Alimentos" (detalle + galería) solo si aplica. Pensado para tours que incluyen comida como plus; opcional porque depende del operador.
Campos "reserva-lista" (servicios)
ubicacion (lugar/punto de encuentro/dirección), mapa_url (link Google Maps), checkin (anti no-show, ej. "Llegar 15 min antes"), anticipacion (lead time, ej. "48 h"). Se ven en la vista cliente (bloques Disponibilidad / Dónde / Check-in). Cada modo + estos campos definen qué pedirá el futuro formulario de reserva (lead casi listo).
Vistas (toggle en tab Servicios)
- ✎ Builder — grid de edición (muestra precio público + margen).
- 👁 Vista cliente — catálogo limpio agrupado por tipo, como lo vería un cliente.
openCliente()abre detalle estilo público. Oculta: precio_neto, margen, comisión, notas internas, proveedor, código.
Diseño / UI
Formal y minimalista: tipografía Inter, paleta blanco/negro/gris (--ink,--muted,--line),
acentos sobrios mar (--sea #1f4b54, primario/activos) y arena (--sand, detalles puntuales como A&B).
Botón primario negro. Sin serif decorativo.
Archivos / fotos
- En
uploads/servicio_{id}/, prefijofoto_(fotos) odoc_(documentos). /api/file-countseligefirst_imagePREFIRIENDOfoto_y excluyendo docs (mismo patrón que el Hub).
Endpoints
GET/POST/PUT/DELETE /api/{proveedores|servicios}GET /api/servicios(join proveedor_nombre) ·GET /api/proveedores(con servicios_count)GET /api/dashboard·GET /api/file-counts·GET /api/files/{entidad}POST /api/upload/{entidad}?tipo=foto&label=...·DELETE /api/files/{entidad}/{name}
Convenciones de edición
- Editar LOCAL aquí (
/Users/claudeandrefg/Documents/catalogo-borrador/) y desplegar con scp. - No instalar dependencias — stdlib + vanilla JS. Si una feature lo requiere, discutir antes.
- Para agregar una tabla nueva:
CREATE TABLEeninit_db()+ entrada enTABLES(CRUD automático).
Pendientes / fases siguientes
- (Hecho) Builder: proveedores + servicios con fotos y todos los campos.
- Builder de propuestas/catálogos (selección de servicios → documento → PDF). Reusar patrón
catalogosdel Hub. - Página web pública de catálogo online optimizado (sync desde la DB).