Reservas y pre-reservas
Estados de la reserva, la pre-reserva de 10 minutos, señas por Pix y la garantía de cero sobreturnos.
Por qué una pre-reserva
Una conversación por WhatsApp puede tardar minutos: el cliente elige horario, después le pedís el nombre, quizás una seña. Mientras tanto otros clientes, la página de reserva y la API compiten por el mismo horario. La pre-reserva (hold) guarda el horario por 10 minutos (15 cuando hay seña por Pix) y vence sola.
Estados
| Estado | Significado | Ocupa el horario |
|---|---|---|
held | Pre-reserva temporal | Sí |
pending_payment | Esperando la seña por Pix | Sí |
confirmed | Reservado | Sí |
checked_in | El cliente llegó | Sí |
completed | Atendido | No |
cancelled | Cancelado (o reemplazado por una reprogramación) | No |
no_show | Ausencia marcada por una persona | No |
expired | Pre-reserva no confirmada a tiempo | No |
held ──confirm──► confirmed ──check-in──► checked_in ──► completed
│ └─(seña)──► pending_payment ──pagada──► confirmed
└─vence──► expired confirmed ──cancela──► cancelled
Garantías
- Cada recurso que ocupa una reserva se guarda como una asignación con un rango de tiempo.
- Para recursos
exclusive, PostgreSQL rechaza asignaciones superpuestas con una constraint de exclusión. - Para recursos
pooled, los contadores de capacidad nunca superan el límite (chequeo atómico). - Una reserva con varios recursos se escribe en una sola transacción: si cualquier recurso choca, no se reserva nada.
POST /holdsyPOST /holds/{id}/confirmexigenIdempotency-Key: reintentar un request nunca crea una segunda reserva.
Si el horario se ocupó mientras el cliente decidía, recibís 409 con code: "slot_taken" y una lista de alternatives.
Reprogramar y cancelar
- Reprogramar crea una reserva nueva y cancela la anterior (vinculadas por
rescheduled_to). Los recordatorios se mueven solos. - Cancelar libera el horario y cancela los recordatorios pendientes.
- Ausencia nunca es automática: el sistema la sugiere, una persona la confirma.
Señas
Si el servicio tiene deposit_cents, confirmar la pre-reserva devuelve pending_payment con un código Pix. Cuando el proveedor de pagos avisa, la reserva pasa a confirmed y se emite payment.paid. Un pago que llega después de que venció la pre-reserva queda marcado para reembolso.