Catalogo de Servicios (builder): codigo + documentacion extensiva

Builder multi-proveedor de servicios (tour / A&B / transportacion).
Python stdlib + SQLite + vanilla JS SPA. Hereda filosofia del Hub.

Secretos y datos (catalogo.db, secret.key, uploads/) excluidos via .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
consultoria-as
2026-06-09 21:00:50 -07:00
commit 38e9e4b91c
8 changed files with 1814 additions and 0 deletions

66
API.md Normal file
View File

@@ -0,0 +1,66 @@
# API REST — Catálogo de Servicios
Servidor: `server.py` (Python stdlib `http.server`), puerto **4403**. Respuestas JSON.
Autenticación por **cookie de sesión** firmada (HMAC). Sin sesión: `/api/*` y `/uploads/*` → bloqueados; las páginas muestran login.
---
## Autenticación
| Método | Ruta | Descripción |
|---|---|---|
| GET | `/api/needs-setup` | ¿Primera vez? (pública) |
| POST | `/api/setup` | Crea la cuenta admin inicial. Body `{username, password, nombre}` |
| POST | `/api/login` | Inicia sesión. Body `{username, password}` → cookie |
| POST | `/api/logout` | Cierra sesión |
Contraseñas: **PBKDF2-SHA256** + salt. Sesión firmada con HMAC (clave en `secret.key`).
---
## CRUD genérico
Un handler sirve todas las tablas vía el dict `TABLES` en `server.py`:
| Método | Ruta | Descripción |
|---|---|---|
| GET | `/api/{tabla}` | Lista registros |
| POST | `/api/{tabla}` | Crea (body = campos) |
| PUT | `/api/{tabla}/{id}` | Actualiza |
| DELETE | `/api/{tabla}/{id}` | Elimina |
Tablas: `proveedores`, `servicios`.
El dict define `fields`, `int_fields`, `float_fields`, `nullable_fields` por tabla (casteo automático).
---
## Endpoints especiales
| Método | Ruta | Descripción |
|---|---|---|
| GET | `/api/servicios` | Servicios con `proveedor_nombre` (join) |
| GET | `/api/proveedores` | Proveedores con `servicios_count` |
| GET | `/api/dashboard` | KPIs (conteos, totales) |
| GET | `/api/file-counts` | `{entidad: {count, first_image}}`. `first_image` prefiere `foto_`, excluye docs y `menu` |
| GET | `/api/files/{entidad}` | Lista archivos de un servicio |
| POST | `/api/upload/{entidad}?tipo=foto&label=...` | Sube archivo(s). `tipo`=`foto`/`menu`/`doc` define el prefijo |
| DELETE | `/api/files/{entidad}/{nombre}` | Elimina un archivo |
`{entidad}` = `servicio_{id}`.
---
## Servir contenido
| Ruta | Sirve |
|---|---|
| `/` o `/index.html` | La SPA (builder + vista cliente) |
| `/uploads/servicio_{id}/{archivo}` | Archivos del servicio (requiere sesión) |
---
## Notas
- Sin dependencias externas: `http.server`, `sqlite3`, `json`, `urllib`, `hashlib`, `hmac` (stdlib).
- CORS y preflight `OPTIONS` habilitados.
- Para agregar una tabla: `CREATE TABLE` en `init_db()` + entrada en `TABLES` → CRUD automático.