fix(portal): send preferredTime as HH:MM:SS and format booking slot labels (GRO-2211) #51
Reference in New Issue
Block a user
Delete Branch "flea/gro-2213-portal-preferredtime"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
FIX (web, root cause): portal booking 500 — send
preferredTimeasHH:MM:SSParent defect: GRO-2211. Root-cause fix for GRO-2213.
Why it broke
GET /api/book/availabilityreturns canonical UTC ISO slot strings (e.g.2026-06-09T10:00:00.000Z= the 10:00 UTC business slot). The Book New wizard held these raw, rendered them verbatim on the slot buttons / Review "Date & Time" / success screen, and POSTedpreferredTime: selectedTimeraw. The api inserts that into the Postgrestimecolumn →invalid input syntax for type time: "2026-06-09T10:00:00.000Z"→ unhandled 500.Changes (
src/portal/sections/Appointments.tsx)formatSlotLabel(slot)andslotToTime(slot)so display label and submit payload derive from the same canonical UTC ISO slot and never desync. Both format/extract in UTC (slots are UTC business hours — a browser-local conversion would mislabel and desync from the stored column). Guards tolerate already-formatted labels andHH:MM:SSvalues.formatSlotLabel(...)→ e.g.10:00 AM, never a raw ISO.preferredTime: slotToTime(selectedTime)→HH:MM:SS.BookingFlowfor testing.Tests
formatSlotLabel/slotToTime.10:00 AM(never raw ISO) and the/api/portal/waitlistPOST bodypreferredTimematches/^\d{2}:\d{2}:\d{2}$/(10:00:00).tsc --noEmitclean; lint 0 errors.Scope note
RescheduleFlowhas a sibling raw-ISO display/submit issue againststartTime(different endpoint/contract). Left untouched to keep this fix tightly scoped to thepreferredTime500; can be filed as a follow-up.AC
preferredTimeisHH:MM:SSThe Book New wizard held raw ISO slot strings (e.g. "2026-06-09T10:00:00.000Z") from /api/book/availability and rendered them verbatim on the slot buttons, the Review "Date & Time" line, and the success screen, and POSTed them straight as preferredTime. The api inserts that into the Postgres `time` column, so a full ISO datetime is `invalid input syntax for type time` → unhandled 500, breaking portal booking (GRO-2211). - Add shared UTC helpers formatSlotLabel(slot) and slotToTime(slot) so the display label and the submitted time derive from the same canonical UTC ISO slot and never desync. Both format/extract in UTC (slots are UTC business hours); guards tolerate already-formatted labels and HH:MM:SS values. - BookNew: render formatSlotLabel(time) on slot buttons, the Review line, and the confirmation; submit preferredTime: slotToTime(selectedTime) → HH:MM:SS. - Export BookingFlow for testing. - Tests: helper unit tests + a Book New funnel integration test asserting the rendered slot label is "10:00 AM" (never raw ISO) and the waitlist POST body preferredTime matches /^\d{2}:\d{2}:\d{2}$/. GRO-2213 Co-Authored-By: Paperclip <noreply@paperclip.ing>