Files
art4hotel-hub/CONTEXTO.md
consultoria-as c2ae140078 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>
2026-06-09 00:10:07 -07:00

6.5 KiB

Art4Hotel Hub — Contexto del proyecto

Sistema interno de operaciones para Clod (bolsas/accesorios custom, Los Cabos). Última actualización mayor: 2026-05-31

Stack

  • Backend: Python 3 stdlib HTTP server + SQLite (WAL, FK on)
  • Frontend: SPA vanilla JS, sin frameworks (index.html ~9000 líneas)
  • Deploy: claude@192.168.50.46:/mnt/iclaude/art4hotel-hub/ puerto 4401
  • Acceso: red local 192.168.50.46:4401 · Tailscale 100.110.177.1:4401
  • Deploy cmd: 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"

Modelo de datos (SQLite)

ordenes (pedidos/líneas de producción), oc (orden de compra que agrupa pedidos), productos (catálogo), proyectos (recetas recurrentes), propuestas (cotizaciones), catalogos (presentaciones PDF), clientes, trabajos, modelos, materiales, inventario, tareas, bitacora.

CRUD genérico: dict TABLES en server.py define fields/int_fields/float_fields/nullable_fields por tabla; un solo handler maneja POST/PUT/DELETE de todas.

Conceptos clave

  • Pedido (ordenes) = línea de producción individual
  • Orden (OC) (oc) = agrupa pedidos, lleva factura/cobranza
  • Proyecto recurrente (proyectos) = receta autorizada (cliente+producto+trabajo+logo)
  • Propuesta → al aceptarse, botón "Convertir a Orden" crea OC + N pedidos (oc.propuesta_id)
  • tipo_orden: OC / Resurtido / Muestra / Defecto / Faltante
  • Bodega: Con orden (hoteles, facturable) vs Sin orden (resurtido/POS libre)
  • Stages: Nuevo → En 2 Mares / En Taller Sofía → En Almacén → En Vehículo → Entregado

Producto — modelo unificado (editor de 4 secciones)

El producto es la fuente única de verdad. Editor openProductoEdit organizado por impacto:

  • 📋 Identidad (catálogo·web·cotizador): nombre, categoría, talla, medidas, material, descripcion_web
  • 🎨 Personalización (cotizador·web): tipos_trabajo_disponibles (CSV multi-select) — al cotizar SOLO aparecen estos
  • ⚙️ Operación (producción·inventario): sku (no editable), costo_base, proveedor, stock_actual, punto_reorden
  • 🌐 Publicación: mostrar_en_web

Quickview openProductoView = visual read-only + botón Editar (ARRIBA de la galería) + galería de ejemplos.

⚠️ PRINCIPIO: cada atributo de producto impacta hasta 3 funciones

Al agregar/cambiar un atributo de producto, definir su impacto en las 3 antes de implementar:

  1. Operación / flujo de producción (kanban, inventario, costos)
  2. Catálogo / cotizador (propuestas, catálogo PDF)
  3. Página web (sync a art4hotel.com) Ejemplo: agregar "uso" (boda/empresa/hotel) → afecta filtros web + tal vez segmentación de cotización.

Campos legacy (en DB, retirados del editor)

color (datos sucios), logo_diseno (pertenece a proyecto/pedido), modelo (vacío), tipo_personalizacion (ya migrado → tipos_trabajo_disponibles). Pendiente: limpieza con script.

Galería de ejemplos (base + personalización)

  • Un producto base muestra "cómo se ha personalizado" = pedidos (ordenes) con foto cuyo producto coincide por nombre.
  • Curaduría por ejemplo: ordenes.web_ejemplo (1=va a web) + ordenes.web_etiqueta (etiqueta PÚBLICA: zona/"muestra", nunca el cliente real — protege la cartera).
  • getEjemplosDeProducto(nombre) calcula en cliente desde S.ordenes + fileIndex.

Archivos / fotos

  • Guardados en uploads/{entidad}/, prefijo del tipo en el nombre: factura_, foto_avance_produccion_, foto_producto_base_, recibo_entrega_, etc.
  • El prefijo es crítico: /api/file-counts lo usa para elegir first_image PREFIRIENDO fotos (foto_/mockup) y EXCLUYENDO documentos (factura,recibo,comprobante,soporte,contrato,propuesta).
  • Subida con etiqueta opcional: ?tipo=X&label=... → nombre {tipo}_{ts}_{label} (prefijo siempre se conserva). Sugerencia automática según tipo+contexto (suggestFileLabel).

Catálogos (Propuestas → 📚 Catálogos)

  • Tabla catalogos: nombre, segmento, cliente_nombre, fecha, items(JSON), show_prices/show_clientes/show_contacto, entrega, minimo_compra, terminos, status.
  • Builder: picker de Productos / Proyectos / Pedidos-con-foto. Items guardan snapshot + rehidratación (catRehydrateItem) al abrir → refresca datos vivos del producto, conserva precio_unit manual.
  • Precio unitario editable inline por item (vacío = no se muestra).
  • PDF: portada (logo oficial centrado) → grids 2 productos/página → pie con términos comerciales (entrega·mínimo) + contacto toggleable en cada página.
  • Imprimir: catPrintCatalog() agrega clase cat-printing al body → @media print A4 vertical.

Ventas (tab unificada)

Sub-vistas: 📊 Dashboard (KPIs, comparativo mes/mes-pasado/año-pasado, top clientes, tiempos de ciclo, pricing por producto) · 📋 Por OC (kanban cobranza) · 📦 Por Entregas (panel "En Vehículo" + histórico).

Marca / estilo UI

  • Fuentes: Outfit (cuerpo) + Playfair Display Italic (display) + DM Sans (labels)
  • Colores: olivo #5C6B4F, olivo-osc #3D4A33, café #6B4F3C, arena #D4C5A9, crema #FAF7F0
  • Constantes canónicas: TRABAJO_OPTS, CONDICIONES_PAGO_OPTS, PRODUCTO_CATEGORIAS
  • Nav: tabs en desktop, dropdown en móvil (≤700px)

Optimizaciones

  • /api/file-counts batched (1 request) con first_image inteligente
  • Imágenes loading="lazy" decoding="async", kanban/bodega sin thumbs por default
  • IDs con MAX(num)+1 (no count) — evita colisiones

Endpoints

  • GET/POST/PUT/DELETE /api/{table}
  • GET /api/file-counts{entity: {count, first_image}}
  • GET /api/ventas → dashboard analytics
  • POST /api/upload/{id}?tipo=X&label=Y · GET /api/files/{id} · DELETE /api/files/{id}/{name}

Backup

  • backup.py por cron: snapshot DB (online backup, safe c/ WAL) + uploads.tar.gz, 30 días en backups/
  • Backups manuales antes de migraciones: cp art4hotel.db art4hotel.db.bak_<motivo>_<fecha>

Pendientes (al 2026-05-31)

  • Web: filtros por uso (boda/empresa/tienda/hotel — requiere atributo "uso") + secciones por tipo · foto base del modal de producto web recorta en cuadrado · analytics
  • Limpieza DB: retirar columnas legacy (color, logo_diseno, modelo, tipo_personalizacion)
  • Operación: limpieza de campos de pedido poco usados · distinguir 3 paths visualmente

Sitio web público → ver WEB.md

art4hotel.com (GitHub Pages) se alimenta del Hub vía sync_catalogo.py. Detalle en WEB.md.