blocker fix phases added
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Phase 04 — The 30-minute payment countdown can lie
|
||||
|
||||
**Blocker:** blockers.md § "Payments" (the timezone item).
|
||||
**Depends on:** nothing. Small and contained.
|
||||
**Related:** [13-booking-lifecycle.md](13-booking-lifecycle.md)'s "today's visits" fix needs a consistent
|
||||
timezone decision — resolve that the same way once you land this.
|
||||
|
||||
---
|
||||
|
||||
**Root cause, precise.** `BookingRequest.PaymentDeadlineAt`/`NurseResponseDeadlineAt` are `DateTime` (not
|
||||
`DateTimeOffset`, deliberately, per a comment about SQLite test-provider compatibility —
|
||||
`BookingRequest.cs:53-60`). The value is written correctly as UTC
|
||||
(`AcceptBookingRequestCommand.Handler.cs:41-50`), but **SQL Server's `datetime2` carries no timezone**, and
|
||||
EF's SQL Server provider returns `Kind = Unspecified` on read — nothing resets it to `Utc`
|
||||
(`BookingRequestConfig.cs:19-26` has no `.HasConversion(...)` for these two properties, unlike
|
||||
`BaseEntity.CreatedAt`/`ModifiedAt`, which correctly use `DateTimeOffset`). System.Text.Json therefore
|
||||
serializes it **without** a trailing `Z`. `Date.parse()` on the client
|
||||
(`client/src/components/CountdownTimer/CountdownTimer.tsx:84`) reads a `Z`-less ISO string as **local time**,
|
||||
not UTC — for a Tehran browser (UTC+3:30) that's ~3.5 hours added to the true deadline, so the countdown
|
||||
shows hours more time than actually remains and expires while still showing time left.
|
||||
|
||||
**The fix.** Add an EF Core value converter (new file, e.g.
|
||||
`server/src/Infrastructure/Baya.Infrastructure.Persistence/ValueConversion/UtcDateTimeConverter.cs`, same
|
||||
pattern as the existing `EncryptedStringConverter.cs`): `convertFromProvider: v =>
|
||||
DateTime.SpecifyKind(v, DateTimeKind.Utc)` (no-op on write). Apply it to both `PaymentDeadlineAt` and
|
||||
`NurseResponseDeadlineAt` in `BookingRequestConfig.cs:19-26`. No migration needed — same column type, only
|
||||
the in-memory `Kind` tag changes on read.
|
||||
|
||||
**Flag:** the same defect class (a `DateTime` read back from `datetime2` losing `Kind`) likely recurs
|
||||
anywhere else a server-frozen instant feeds a client countdown (e.g. `dispute_window_ends_at`, BNPL
|
||||
`settled_at`) — worth a grep for other `DateTime` (not `DateTimeOffset`) properties before considering this
|
||||
class of bug fully closed, not just the one already reported.
|
||||
Reference in New Issue
Block a user