Agendamentos e pré-reservas

Estados do agendamento, a pré-reserva de 10 minutos, sinal via Pix e a garantia de zero overbooking.

Por que pré-reserva

Uma conversa no WhatsApp pode levar minutos: o cliente escolhe o horário, depois você pergunta o nome, talvez um sinal. Enquanto isso, outros clientes, a página de reserva e a API disputam o mesmo horário. A pré-reserva (hold) segura o horário por 10 minutos (15 quando há sinal via Pix) e expira sozinha.

Estados

StatusSignificadoOcupa o horário
heldPré-reserva temporáriaSim
pending_paymentAguardando o sinal via PixSim
confirmedAgendadoSim
checked_inO cliente chegouSim
completedAtendidoNão
cancelledCancelado (ou substituído por reagendamento)Não
no_showFalta marcada por uma pessoaNão
expiredPré-reserva não confirmada a tempoNão
held ──confirm──► confirmed ──check-in──► checked_in ──► completed
 │  └─(sinal)──► pending_payment ──pago──► confirmed
 └─expira──► expired          confirmed ──cancela──► cancelled

Garantias

  • Cada recurso ocupado por um agendamento é gravado como uma alocação com intervalo de tempo.
  • Para recursos exclusive, o PostgreSQL rejeita alocações sobrepostas com uma constraint de exclusão.
  • Para recursos pooled, os contadores de capacidade nunca passam do limite (verificação atômica).
  • Um agendamento com vários recursos é gravado numa única transação: se qualquer recurso conflitar, nada é agendado.
  • POST /holds e POST /holds/{id}/confirm exigem Idempotency-Key: reenviar uma requisição nunca cria um segundo agendamento.

Se o horário foi ocupado enquanto o cliente decidia, você recebe 409 com code: "slot_taken" e uma lista de alternatives.

Reagendar e cancelar

  • Reagendar cria um novo agendamento e cancela o anterior (ligados por rescheduled_to). Os lembretes se movem sozinhos.
  • Cancelar libera o horário e cancela lembretes pendentes.
  • Falta nunca é automática: o sistema sugere, uma pessoa confirma.

Sinal

Se o serviço tem deposit_cents, confirmar a pré-reserva devolve pending_payment com um código Pix. Quando o provedor de pagamento avisa, o agendamento vira confirmed e o evento payment.paid é emitido. Um pagamento que chega depois da pré-reserva expirar é marcado para estorno.