Motor de reservas por capacidad con lista de espera. Registra clientes contra un cupo (una franja horaria, una clase o un evento) con un límite máximo; cuando el cupo se llena, los nuevos registros entran a una lista de espera ordenada, y al liberarse un lugar el siguiente asciende automáticamente.
Un cupo lleno no tiene por qué ser una venta perdida. En vez de decir "no hay campo", el sistema pone al cliente en lista de espera y lo promueve solo en cuanto alguien cancela — sin que nadie tenga que estar pendiente del teléfono.
Backend en Python + FastAPI, asíncrono y stateless por petición (apto para serverless). Separado por responsabilidades:
app/
schemas.py modelos de reserva, cupo y cancelación (Pydantic)
store.py cupos con sus listas de confirmados y de espera (en memoria)
service.py capacidad, lista de espera y ascenso automático
main.py capa HTTP (rutas FastAPI)
La capacidad y el orden de la lista de espera (FIFO) viven en service.py. En
producción, store.py se cambia por una base de datos; conviene confirmar dentro
de una transacción o con un lock por cupo para evitar sobrecupo bajo concurrencia.
| Método | Ruta | Descripción |
|---|---|---|
GET |
/health |
Estado del servicio. |
POST |
/reservations |
Reserva un cupo (confirmado o en lista de espera). |
POST |
/reservations/cancel |
Cancela y asciende al siguiente de la lista si aplica. |
GET |
/slots |
Cupos con su ocupación y tamaño de lista de espera. |
GET |
/slots/{slot_id} |
Detalle de un cupo: confirmados y lista de espera. |
Reservar en un cupo lleno devuelve la posición en la lista de espera:
curl -X POST http://localhost:8000/reservations \
-H "Content-Type: application/json" \
-d '{"slot_id": "S-2", "client_id": "C-99", "client_name": "Laura"}'{
"slot_id": "S-2",
"client_id": "C-99",
"client_name": "Laura",
"status": "waitlisted",
"position": 3,
"created_at": "2026-06-15T12:00:00Z"
}Al cancelar un confirmado de ese cupo, el primero de la lista asciende solo:
curl -X POST http://localhost:8000/reservations/cancel \
-H "Content-Type: application/json" \
-d '{"slot_id": "S-2", "client_id": "C-10"}'{
"slot_id": "S-2",
"client_id": "C-10",
"cancelled": true,
"promoted": { "client_id": "C-30", "status": "confirmed", "...": "..." }
}El modelo es genérico (slot_id, capacity, client_id), así que el mismo
motor sirve para:
- Gimnasios y estudios: clases con cupo (spinning, crossfit, yoga).
- Restaurantes: mesas o turnos por franja horaria.
- Coworkings y oficinas: salas de reunión y puestos.
- Eventos y talleres: entradas con aforo y lista de espera.
Solo cambian los cupos y su capacidad; la lógica de espera y ascenso no se toca.
pip install -r requirements.txt
uvicorn app.main:app --reloadDocumentación interactiva en http://localhost:8000/docs.
En demo/GestionReservasDemo.astro hay un simulador visual (sin backend) que
muestra cómo se llenan los cupos, cómo entran los clientes a la lista de espera
y cómo ascienden al cancelarse un lugar. Es el componente que se integra en la web.