Compare commits

..

1 Commits

Author SHA1 Message Date
Savannah Savings 7edf132bfe fix(portal): send preferredTime as HH:MM:SS and format booking slot labels (GRO-2211)
CI / Test (pull_request) Successful in 20s
CI / Lint & Typecheck (pull_request) Successful in 26s
CI / Build & Push Docker Image (pull_request) Successful in 46s
The 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>
2026-06-08 16:39:27 +00:00
-18
View File
@@ -237,24 +237,6 @@ export const { signIn, signOut, useSession, changePassword } = authClient;
> absolute `startTime` in `isUpcoming`, and hardens `parseTimeTo24Hour` against
> blank/undefined input.
#### 5.12e Book New `preferredTime` Formatting (GRO-2211, GRO-2213)
| # | Scenario | Steps | Expected |
|---|----------|-------|----------|
| TC-WEB-5.12.22 | Slot buttons show formatted label | Sign in as `uat-customer@groombook.dev`, open `Appointments`, click "Book New", select a pet and service, pick a date with availability | Each time-slot button shows a human-readable label like `10:00 AM` (UTC), never a raw ISO timestamp (e.g. not `2026-06-09T10:00:00.000Z`) |
| TC-WEB-5.12.23 | Confirmation review shows formatted label | Continue the Book New wizard to the Review step | The "Date & Time" summary and the final confirmation both display the formatted slot label (e.g. `10:00 AM`), not a raw ISO string |
| TC-WEB-5.12.24 | Booking submit succeeds (regression) | Complete the Book New wizard and submit the request | Request succeeds with no `500` / `invalid input syntax for type time` error; the booking POST sends `preferredTime` as `HH:MM:SS` (e.g. `10:00:00`); the new appointment appears in the Upcoming list |
> **GRO-2211/GRO-2213 note:** The Book New wizard previously rendered the raw
> UTC ISO slot string as the button/confirmation label and submitted that same
> ISO value as `preferredTime`, which the API rejected with
> `invalid input syntax for type time` (HTTP 500). The fix adds shared UTC
> helpers `formatSlotLabel(slot)` (display → `10:00 AM`) and `slotToTime(slot)`
> (payload → `HH:MM:SS`) in `src/portal/sections/Appointments.tsx`, so the
> displayed label and the submitted `preferredTime` both derive from the same
> canonical UTC ISO slot. (The sibling `RescheduleFlow` `startTime` raw-ISO issue
> on a different endpoint is tracked separately and is out of scope here.)
### 5.13 Reports UI
| # | Scenario | Steps | Expected |