fix: compute contract date client-side for local timezone #10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/9-contract-date-timezone"
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?
Summary
The contract signing page date was computed during SSR in the server's UTC timezone. Since the k8s pod runs UTC, Utah users (MDT, UTC-6) saw tomorrow's date after 6 PM local time. This moves date computation into
onMount()so it runs client-side with the user's local timezone.Changes
src/routes/contract/[token]/+page.svelte: changeddateStrfrom aconstcomputed at SSR time to a$statevariable populated inonMount(). SSR renders an empty string; client hydration fills in the correct local date. Both usages (date input field and success overlay) are covered.Test Plan
npm run buildsucceedsReview Checklist
Related
Review: Approved
Diff: 1 file, +8/-4. Minimal and surgical.
Correctness:
const dateStrwas computed once during SSR (UTC). Now$state('')+onMount()ensures the date is computed client-side in the user's local timezone. SSR renders empty string, hydration fills correct date. Both usages (date input on line 462, success overlay on line 494) read from the same reactivedateStr.No issues found:
onMountalready imported (line 2) -- no new imports neededonMountcalls are valid in Svelte (existing one at line 117 for signature pad)LGTM.
PR #10 Review
DOMAIN REVIEW
Stack: SvelteKit (Svelte 5 runes), TypeScript, adapter-node, SSR-enabled.
Fix correctness: The root cause is correctly identified.
new Date()at module scope executes during SSR on the k8s pod, which runs UTC. For users in MDT (UTC-6), any time after 6 PM local would produce tomorrow's date. Moving intoonMount()guarantees client-side execution with the browser's local timezone. The formatting options (en-US,year: 'numeric', month: 'long', day: 'numeric') are unchanged.SSR empty-string safety: During SSR,
dateStris''. Both usages are safe:.signature-area, which is gated behindclass:visible={agreed}-- a user interaction required before it renders visibly.showSuccessis true, which requires a successful POST -- exclusively a client-side event.No hydration mismatch risk: the server renders
'', and the client fills in the date before the user can see either element. Clean.Multiple
onMountcalls: The component now has twoonMount()calls (lines 26 and 117). Svelte 5 supports multipleonMountregistrations per component -- each callback runs independently. No issue.Accessibility: The date input (line 462) has
readonlyand a<label>withfor="signDate". No regression.BLOCKERS
None.
This is a bug fix that relocates existing logic from SSR to client-side. No new functionality is introduced -- the
Dateconstructor andtoLocaleDateStringcall are identical. The 12 existing validation tests cover the server-side signing logic. A unit test for "which timezone doesnew Date()run in" would be testing the browser/Node runtime, not application logic. No blocker applies.NITS
Two separate
onMountcalls could be consolidated (lines 26-32 and 117-130). Both run on mount. Merging them into a singleonMountcallback would be slightly cleaner and make the component's lifecycle easier to scan. Non-blocking -- the current approach works correctly.Inline date formatting on line 156: The "already signed" view formats
player.contract_signed_atwith an inlinenew Date(...).toLocaleDateString(...). This is fine because it formats a stored timestamp (not "now"), but it duplicates the same locale/options object used fordateStr. A shared formatter constant could reduce repetition. Out of scope for this PR -- noting for future cleanup.SOP COMPLIANCE
fix/9-contract-date-timezonereferences issue #9Closes #9PROCESS OBSERVATIONS
VERDICT: APPROVED