Reservas
O módulo de reservas (backend/src/reservations/) gerencia reservas de mesa com ciclo de vida completo, anti-spam por telefone, detecção de double-booking e NPS pós-visita automático.
Visão Geral
| Característica | Detalhe |
|---|---|
| Módulo backend | backend/src/reservations/ |
| View admin | frontend-react/src/views/admin/ReservationsView.tsx |
| Rota | /t/:slug/admin/reservations |
| Schema | Reservation |
| Scheduler | NoShowScheduler — marca no_show automaticamente |
| Permissão admin | Permission.AllReservations |
| Módulo habilitado | tenant.reservationsEnabled = true |
Schema Reservation
| Campo | Tipo | Descrição |
|---|---|---|
customerName | string | |
customerPhone | string | |
customerEmail | string? | |
date | Date | Data da reserva |
time | string | HH:MM |
partySize | number | Min 1 |
table | ObjectId? → Table | Mesa atribuída |
status | enum | Ver tabela abaixo |
notes | string? | Observações |
tenant | ObjectId | |
npsToken | string? | Token único para link de NPS pós-visita |
npsRequestedAt | Date? | Quando o email de NPS foi enviado |
npsScore | number? | 0–10 (NPS do cliente) |
Status
| Status | Descrição |
|---|---|
pending | Aguardando confirmação do admin |
confirmed | Confirmada — cliente notificado |
cancelled | Cancelada (por admin ou cliente) |
completed | Cliente chegou e foi atendido |
no_show | Marcou e não compareceu (atribuído automaticamente) |
Regras de Negócio
Anti-spam por telefone
Um mesmo customerPhone não pode ter mais de 5 reservas em aberto (pending ou confirmed) simultaneamente por tenant. Retorna 400 Bad Request ao exceder o limite.
Anti-double-booking
Mesma mesa + data + horário com status diferente de cancelled/no_show → 409 Conflict.
Reservas no passado
Datas anteriores a hoje retornam 400 Bad Request.
Throttle público
O endpoint POST /t/:slug/reservations tem rate-limit de 3 requisições/minuto por IP (proteção contra bots).
Endpoints
| Método | Rota | Permissão | Descrição |
|---|---|---|---|
POST | /t/:slug/reservations | Público | Cliente cria reserva |
GET | /t/:slug/reservations | AllReservations | Lista (filtro ?date=&status=) |
GET | /t/:slug/reservations/stats | AllReservations | Estatísticas do período |
PUT | /t/:slug/reservations/:id | AllReservations | Atualiza (confirmar, cancelar, etc.) |
GET | /t/:slug/reservations/nps/:token | Público | Cliente responde NPS |
Pré-pedido com Slots de Capacidade
O PreOrderSlotsService (backend/src/orders/pre-order-slots.service.ts) calcula a capacidade disponível por janela de tempo configurável por filial:
branch.preOrderSlots = {
bucketMinutes: 15, // janela de tempo (padrão 15 min)
capacityPerBucket: 10, // pedidos por janela (padrão 10)
prepTimeMinutes: 15, // antecedência mínima (padrão 15 min)
}Janelas esgotadas retornam full: true. O serviço projeta 7 dias à frente a partir de fromDate.
Integração com Notificações
- Confirmação: WhatsApp/email ao confirmar (via
NotificationsService) - Lembrete: 24h antes da reserva
- NPS: Email com link
/reservations/nps/:tokenapós marcarcompleted