Files
art4hotel-hub/API.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

74 lines
3.2 KiB
Markdown

# 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_session` firmada con HMAC (clave en `secret.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_id` al insertar (devuelve 409 si existe).
- **CORS**: headers `Access-Control-Allow-*` habilitados; `OPTIONS` responde preflight.
- Sin dependencias externas: todo con `http.server`, `sqlite3`, `json`, `urllib`, `hashlib`, `hmac` (stdlib).