Reservations
Daily seat list
Overview
Same DataTable chrome as Assignments. Columns: PASSENGER, ROUTE, DATE, PARTY (a small integer), STATUS, NOTES (free-form text — 'Wedding scouting', 'Anniversary trip'). The date picker filters server-side. The +RESERVATION modal lets a dispatcher add a reservation on behalf of a passenger — useful for phone bookings.
How it works
`GET /admin/reservations?date=YYYY-MM-DD` returns reservations with the joined passenger user and route. The notes field is text and rendered as-is in the table cell.
Status pills follow the same color tokens as the mobile app — sage for confirmed, wheat for pending, cabernet for cancelled.
Creating a reservation runs the capacity check — partySize summed for the date and route may not exceed the assignment's vehicle capacity. The API enforces this with a transaction.
Cancellation soft-deletes via status — the row stays, the status flips. We fan out a notification to the passenger and (if dispatch toggles it) refund any prepaid amount.
Notes are a true text field, max 280 chars, rendered exactly as typed. We rely on dispatcher discipline rather than structure — categories felt premature.
Key decisions
One date at a time
A weekly or monthly view would show too much for the daily operating cadence. Pick a date, see that date's bookings, move on. The history surface lives in Reports for the cases where a multi-day view actually adds value.
Free-form notes over structured fields
We considered enum-style 'occasion' fields. But the long tail — 'second anniversary trip after losing our dog' — doesn't fit enums. Free text gives the dispatcher a place to capture context without us pre-deciding the shape.
