# 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`).