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>
3.2 KiB
3.2 KiB
API REST — Art4Hotel Hub
Servidor: server.py (Python stdlib http.server), puerto 4401.
Respuestas en JSON. Autenticación por cookie de sesión (firmada HMAC).
Autenticación
Todas las rutas requieren sesión excepto las públicas de auth. Sin sesión: las páginas HTML muestran el login; las rutas /api/* devuelven 401.
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/needs-setup |
¿Primera vez? → {needs_setup: bool} (pública) |
| POST | /api/setup |
Crea la cuenta admin inicial (solo si no hay usuarios). Body: {username, password, nombre} |
| POST | /api/login |
Inicia sesión. Body: {username, password} → set-cookie de sesión |
| POST | /api/logout |
Cierra sesión (borra cookie) |
- Contraseñas: hash PBKDF2-SHA256 (200k iteraciones + salt).
- Sesión: cookie
a4h_sessionfirmada con HMAC (clave ensecret.key), válida 14 días.
CRUD genérico
Un solo handler maneja todas las tablas vía el dict TABLES en server.py:
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/{tabla} |
Lista todos los registros |
| POST | /api/{tabla} |
Crea un registro (body = campos) |
| PUT | /api/{tabla}/{id} |
Actualiza un registro |
| DELETE | /api/{tabla}/{id} |
Elimina un registro |
Tablas disponibles: ordenes, oc, productos, proyectos, propuestas, catalogos, clientes, trabajos, modelos, materiales, inventario, compras, tareas, bitacora.
El dict define por tabla: fields, int_fields, float_fields, nullable_fields (para casteo/validación automática).
Endpoints especiales
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/dashboard |
KPIs del dashboard (stages, clientes activos, alertas) |
| GET | /api/ventas |
Analítica de ventas: comparativo mensual, top clientes, tiempos de ciclo, pricing por producto |
| GET | /api/entregas |
Pedidos entregados (agrupables por fecha/cliente/OC) |
| GET | /api/oc |
OCs con sus líneas (lineas), totales y progress agregado |
| POST | /api/oc-split/{oc_id} |
Entrega parcial: crea OC hermana con pedidos seleccionados |
| GET | /api/file-counts |
{entidad: {count, first_image}} para TODAS las carpetas en 1 request. first_image prefiere fotos y excluye documentos |
| POST | /api/upload/{id}?tipo=X&label=Y |
Sube archivo(s). tipo define el prefijo; label opcional como parte descriptiva del nombre |
| GET | /api/files/{id} |
Lista archivos de una entidad |
| DELETE | /api/files/{id}/{nombre} |
Elimina un archivo |
| POST | /api/backup-now |
Dispara el respaldo en segundo plano |
| GET | /api/backups |
Lista los respaldos disponibles |
Servir contenido
| Ruta | Sirve |
|---|---|
/ o /index.html |
La SPA (frontend completo) |
/uploads/{entidad}/{archivo} |
Archivos subidos (requiere sesión) |
Notas de implementación
- IDs legibles (orden_id, oc_id) se generan con
MAX(num)+1, no count — evita colisiones tras borrados. - Validación de unicidad en
orden_idal insertar (devuelve 409 si existe). - CORS: headers
Access-Control-Allow-*habilitados;OPTIONSresponde preflight. - Sin dependencias externas: todo con
http.server,sqlite3,json,urllib,hashlib,hmac(stdlib).