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>
67 lines
2.2 KiB
Markdown
67 lines
2.2 KiB
Markdown
# 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.
|