Promote dev → uat: GRO-2180 portal Appointments ISO startTime fix #50
Reference in New Issue
Block a user
Delete Branch "dev"
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?
Promote dev → uat: GRO-2180 portal Appointments ISO startTime fix
Promotes the merged GRO-2180 fix (web PR #49,
devHEAD2b494c01) touatso it can be deployed to the UAT environment. Unblocks UAT sign-off for the booking-funnel portal flow (GRO-1808 TC-7..11).What's promoted
Appointmentsnow normalizes the ISOstartTimeAPI shape (normalizeAppointment/getAppointmentStart/formatAppointmentDate), fixing theisUpcomingTypeError that put the page in an error state and made "Book New" unreachable. (#49, #45)dev, previously promoted/validated): GRO-2105 (#46), GRO-2094 (#43), GRO-2099 (#44), GRO-2089 (#42).Tests
src/__tests__/Appointments.test.tsxcovers the normalized shape + upcoming/past partition.UAT_PLAYBOOK
Deploy note
UAT does not auto-deploy via Flux. After merge, the
uatCI build will producegit.farh.net/groombook/web:<date>-<sha7>; a follow-up infra overlay bump (apps/overlays/uat/kustomization.yaml) will roll it.Tracking: GRO-2189. Source fix: GRO-2180.
cc @cpfarhood
The bundle at /login was executing but the React tree never painted — no console errors, no fallback UI, just an empty <div id='root'>. Add three layers of defense so a future failure of this shape is captured instead of being silently swallowed: 1. window 'error' and 'unhandledrejection' listeners in main.tsx, printing structured context to console.error so Playwright sees the failure in the console log even if React unmounts the tree. 2. A top-level <ErrorBoundary> in main.tsx that renders the actual exception (name, message, stack) inside the DOM instead of leaving <div id='root'> empty. The boundary also logs to console.error via componentDidCatch. 3. New tests for the ErrorBoundary (renders children, surfaces thrown errors visibly) and two new UAT_PLAYBOOK test cases (TC-WEB-5.1.6 / 5.1.7) that explicitly assert the 'never-blank-root' invariant on UAT. Co-Authored-By: Paperclip <noreply@paperclip.ing>QA code-quality review passed. Approved for dev → uat promotion.
Review findings:
normalizeAppointment: correctly maps ISOstartTime/endTime+ nestedpet/service/staffto flatAppointmentshape at the fetch boundary; null-safe for missing nested objectsparseTimeTo24Hour: hardened againstundefined/null/empty input — returns"00:00:00"for falsy values (root cause of GRO-2180 TypeError)isUpcoming: prefers absolutestartTimefor past/future classification, falls back to legacydate/timefieldsAppointments.test.tsx;normalizeAppointment,parseTimeTo24Houredge cases,isUpcoming,CustomerNotesSection,ConfirmationSection,RescheduleFlow,StatusBadgeall coveredUAT_PLAYBOOK.md §5.12d: 4 new test cases (TC-WEB-5.12.18–5.12.21) with a clear regression note ✓ErrorBoundary: correct React class component usinggetDerivedStateFromError; tests cover render-time throw fallback.mcp.json: standard MCP config referencing${GITEA_TOKEN}env var — no hardcoded secretsCI note: PR-level CI fails at git fetch (12-min timeout) — known infrastructure issue affecting multiple PRs. Push CI for sha
2b494c01passed lint, typecheck, test, and build independently. Safe to merge once PR CI resolves.Code review: PASS — CI re-run required. Both CI jobs failed with runner timeout (11m50s setup, 0s on all subsequent steps). Same SHA passed push CI — transient runner issue. No code changes needed, re-trigger CI to proceed.
QA Review — Code PASS, CI Re-run Required
Code Review: ✅ PASS
normalizeAppointment(Appointments.tsx:167–193)startTime/endTimevianew Date()date/timedisplay strings from the absolute instantstartTime/endTimeon the output shape forisUpcomingto usepet,service,staff)isUpcoming(Appointments.tsx:113–121)appt.startTime(ISO), falls back to date+time pair for legacy shapeparseTimeTo24Hour(Appointments.tsx:98–111)null/undefined/empty input as requiredTest coverage: 50+ tests across
parseTimeTo24Hour,normalizeAppointment,isUpcoming,CustomerNotesSection,ConfirmationSection,StatusBadge,RescheduleFlow. All GRO-2180 regression scenarios covered.UAT_PLAYBOOK.md §5.12d: Present and thorough.
CI Status: ❌ Runner timeout (transient — re-run needed)
This is a runner infrastructure timeout, not a code failure. The exact same commit (
2b494c01) passed all CI on thepushevent (dev merge): lint ✅ test ✅ build ✅. Thepull_requestrunner exhausted its time budget entirely in "Set up job" and then failed all subsequent steps at 0s.No code changes needed. Please re-trigger CI (re-run failed jobs or push an empty commit). Once CI is green, this PR is approved and ready to merge.