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

90
MODELO_DATOS.md Normal file
View File

@@ -0,0 +1,90 @@
# Modelo de Datos — Art4Hotel Hub
Base de datos **SQLite** (`art4hotel.db`), modo WAL + foreign keys ON. 14 tablas.
Todas las tablas tienen `id INTEGER PRIMARY KEY AUTOINCREMENT` y, la mayoría, `created_at` / `updated_at`.
> El esquema se crea/migra automáticamente al arrancar (`init_db()` en `server.py`), con migraciones idempotentes (`ALTER TABLE` solo si la columna no existe).
---
## Diagrama de relaciones (lógicas)
```
propuestas ──(propuesta_id)──> oc ──(oc_id)──> ordenes
└──(proyecto_id)──> proyectos ──> productos
clientes ───────(por nombre)───────> oc, ordenes, proyectos
productos <──(por nombre)── ordenes (los "ejemplos" del producto = pedidos con foto)
trabajos ──> tipos de personalización (CSV en productos.tipos_trabajo_disponibles)
```
Las relaciones son por **FK nullable** (`oc.propuesta_id`, `ordenes.oc_id`, `ordenes.proyecto_id`) o **por nombre** (cliente/producto como texto). El CRUD es genérico vía el dict `TABLES` en `server.py`.
---
## Tablas
### `ordenes` — Pedidos (líneas de producción) · 36 columnas
El corazón operativo. Cada fila = una pieza/lote en producción.
| Campo | Notas |
|---|---|
| `orden_id` | ID legible (ej. `ORD-2026-071`). Se genera con MAX+1 |
| `tipo_orden` | OC / Resurtido / Muestra / Defecto / Faltante |
| `cliente`, `producto`, `sku`, `cantidad` | datos del pedido |
| `tipo_trabajo` | personalización (Bordado, Serigrafía, DTF UV…) |
| `stage` | etapa del kanban |
| `fecha_oc/inicio/estimada/recepcion/entrega`, `recibio` | fechas y firma |
| `urgente`, `logo_instrucciones`, `notas` | |
| `costo_producto`, `costo_trabajo`, `costo_logistica`, `precio_factura` | economía |
| `check_facturada/empacada/etiquetas/vehiculo` | checklist |
| `grupo_oc`, `piezas_recibidas`, `piezas_danadas`, `nota_recepcion` | recepción/parciales |
| `oc_id` → oc, `proyecto_id` → proyectos | vínculos |
| `web_ejemplo`, `web_etiqueta` | curaduría web: si la foto de este pedido es ejemplo público + etiqueta pública (zona, NO el cliente real) |
### `oc` — Órdenes de Compra · 22 columnas
Agrupan pedidos de un cliente; llevan la facturación/cobranza.
`oc_id`, `cliente`, `fecha_oc`, `fecha_entrega`, `recibio`, `costo_logistica`, `precio_factura`, `factura_num`, `condiciones_pago`, `status`, `iva_pct`, `otros_gastos(+desc)`, `pagado`, `fecha_pago`, `metodo_pago`, `oc_origen_id` (entregas parciales), `propuesta_id` (de qué propuesta nació).
### `productos` — Catálogo (fuente única de verdad) · 18 columnas
`sku`, `nombre`, `categoria`, `talla`, `material`, `medidas`, `descripcion_web`, `tipos_trabajo_disponibles` (CSV de personalizaciones que aplican), `costo_base`, `proveedor`, `stock_actual`, `punto_reorden`, `activo`, `mostrar_en_web` (publicar en art4hotel.com).
### `proyectos` — Recetas recurrentes · 17 columnas
Receta autorizada reutilizable. `nombre`, `producto_id/_nombre`, `cliente`, `tipo_trabajo`, `costo_unitario`, `costo_trabajo`, `logo_descripcion`, `logo_archivo`, `foto_terminado`, `activo`, `veces_usado`, `ultimo_uso`.
### `propuestas` — Cotizaciones · 19 columnas
`numero`, `cliente_nombre`, `contacto`, `empresa`, `direccion`, `locacion`, `tipo_negocio`, `email`, `telefono`, `fecha`, `vigencia_dias`, `items` (JSON), `iva_pct`, `descuento_pct`, `status` (borrador/enviada/aceptada/rechazada).
### `catalogos` — Presentaciones PDF · 17 columnas
`nombre`, `segmento`, `cliente_nombre`, `fecha`, `items` (JSON con snapshot + precio manual), `show_prices/clientes/contacto`, `entrega`, `minimo_compra`, `terminos`, `status`.
### `clientes` — CRM · 10 columnas
`nombre`, `tipo` (hotel/restaurante/tienda…), `contacto`, `zona_entrega`, `costo_entrega`, `condiciones_pago`, `notas`, `activo`.
### `trabajos` — Tipos de personalización · 8 columnas
`clave`, `nombre`, `costo_base`, `variable_por`, `proveedor_default`, `activo`. Fuente de la lista de personalizaciones.
### `inventario` — SKUs legacy · 15 columnas
`sku`, `nombre`, `descripcion`, `tipo`, `talla`, `color_base`, `proveedor`, `stock_inicial`, `punto_reorden`, `costo_unitario`, `ultimo_conteo`.
### `compras` — Compras a proveedor · 13 columnas
`compra_id`, `proveedor`, `fecha_compra`, `fecha_llegada`, `sku`, `nombre_producto`, `cantidad`, `costo_unitario`, `status`.
### `modelos` · `materiales` — Catálogos auxiliares
`modelos`: clave, nombre, descripcion, activo. `materiales`: clave, nombre, tipo, costo_unitario, activo.
### `tareas` — Kanban interno del equipo · 11 columnas
`titulo`, `descripcion`, `prioridad`, `stage`, `categoria`, `fecha_limite`, `asignado`, `notas`.
### `bitacora` — Timeline de eventos · 6 columnas
`tipo`, `titulo`, `descripcion`, `referencia`, `fecha`. Registro de acciones del sistema.
### `usuarios` — Login del Hub · 6 columnas
`username`, `pass_hash` (PBKDF2-SHA256, 200k iteraciones, con salt), `nombre`, `activo`. La sesión usa cookie firmada con HMAC (clave en `secret.key`, NO versionada).
---
## Archivos (no en DB)
Guardados en `uploads/{entidad}/` con prefijo de tipo en el nombre:
`factura_`, `recibo_entrega_`, `foto_producto_base_`, `foto_avance_produccion_`, `comprobante_`, etc.
**El prefijo es crítico**: `/api/file-counts` lo usa para elegir la imagen representativa, **prefiriendo** fotos (`foto_`/`mockup`) y **excluyendo** documentos (`factura`, `recibo`, `comprobante`, `soporte`, `contrato`, `propuesta`).