Repository navigation
docs(working-hours): state that hours are the physical location's local time - #2907
Conversation
…al time
Working hours describe when a physical place is open, so both the weekly times
and the date overrides are absolute and location-local — never relative to
whoever is looking. The schema already says this on `WorkingHours.weeklySchedule`
("no timezone conversion … interpreted as local wall time, not UTC"), but nothing
surfaced it to users or to contributors, and it has caused confusion before.
The Weekly Schedule settings copy actively said the opposite: "Times will be
displayed in your local format", which reads as though hours are viewer-relative.
Replaced with a statement that they are the location's local hours and are not
converted for anyone. The booking form's working-hours info box gains the same
note, since that is where the constraint is actually felt.
Adds `.claude/rules/working-hours-are-location-local.md` recording the semantics,
which half is enforced, and which is not:
- DATES are enforced — `getOverrideDateKey()` reads the override day from UTC
because the column is `@db.Date` and Prisma hydrates it at UTC midnight;
formatting that instant locally shifted it a day west of UTC.
- TIMES are not. `validateWorkingHours` and `getBookingDefaultStartEndTimes`
compare against the acting user's preference zone, so an Amsterdam org's 9-5 is
judged in Tokyo wall time for a Tokyo user.
That second gap is now an explicitly accepted risk rather than an open question.
There is no `Organization.timeZone` to evaluate against, and the people
constrained by an org's hours are at that location in practice; a stored location
zone (migration + settings UI + backfill) is not worth it for the ~0.1% case. The
rule says so plainly so nobody re-files it as a bug or "fixes" it by threading
more user-zone logic through working hours.
Also corrects the note at `prefsForDeclaredZone`, which framed the same gap as a
deferred product decision. It is the same rule reached from the client side, and
now points at the rule file.
🩺 React Doctor — webapp✅ No new findings on the files changed by this PR. Run locally with |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d35fcc4371
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <strong>local hours of your physical location</strong> — they are | ||
| not converted to anyone's timezone, so 9:00 means 9:00 on site | ||
| for everyone. |
There was a problem hiding this comment.
Don't promise location-local enforcement before it exists
When an organization member's stored timezone differs from the asset's physical location, this statement is false: validateWorkingHours extracts the booking's weekday and time using prefs.timeZone in forms-schema.ts (lines 77–82 and 303–307), and the default-time calculation does the same. Thus two users with different preferences can have the same 09:00–17:00 schedule applied in different zones, despite this UI promising that 09:00 means 09:00 on site for everyone. Reword this and the matching booking-form label to describe current behavior, or defer the claim until a location timezone is stored and enforced.
Useful? React with 👍 / 👎.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review. WalkthroughThe change documents location-local working-hour semantics, records existing timezone behavior as accepted risk, and updates booking and schedule UI text to identify physical-location local hours. ChangesLocation-local working-hours
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to This PR clarifies that working hours use the physical location’s local time and updates related documentation; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…te's (#252) * content: booking times follow your clock, working hours follow the site's Triggered by: Shelf-nu/shelf.nu#2896 Shelf-nu/shelf.nu#2905 Shelf-nu/shelf.nu#2907 Shelf-nu/shelf.nu#2908 The working-hours article never mentioned time zones at all, while the date-preferences article told readers every timestamp follows their own clock. Working hours are the one thing that does not: they are the local hours of the physical location. #2907 put that in the product; this puts it on the site. The same article also sent readers to a Working Hours sidebar item that does not exist, promised the picker greys out unavailable times, said every day of a multi-day booking is checked, and offered an override edit that was never built. All four corrected against source. * content: the opening window is judged in the booker's zone, and an override is a date CodeRabbit review on #252, both findings. The 'everything else is a moment in time' claim was too broad: a closed-day override is a calendar date, which the same article says two sections above. On the second, the suggestion's premise did not hold, so the fix is different from what was proposed. validateWorkingHours reads the weekday, the wall-clock time and the date from prefs.timeZone (forms-schema.ts:303, :322), the booking user's own preference. There is no site-local validation to apply, so matching the site's zone is not optional decoration. The real hazard CodeRabbit was pointing at is that the preference is account-wide, so the paragraph now states the consequence, names the case where you should NOT change it, and quotes the three refusal messages. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Carlos Virreira <macwhale@Carlos-MacBook-Pro.local> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Working hours describe when a physical place is open, so both the weekly times and the date overrides are absolute and location-local — never relative to whoever is looking. "Open 9–5" means 9–5 where the assets are; it does not become 2–10 because the person reading it is in another country.
The schema already says this on
WorkingHours.weeklySchedule— "no timezone conversion … interpreted as local wall time, not UTC" — but nothing surfaced it to users or contributors, and it has caused confusion more than once.The settings copy said the opposite
That reads as though hours are viewer-relative. Replaced with a statement that they are the location's local hours and are not converted for anyone. The booking form's working-hours info box gets the same note, since that is where the constraint is actually felt.
The rule
.claude/rules/working-hours-are-location-local.mdrecords the semantics and — more usefully — which half is enforced and which isn't:getOverrideDateKey()reads an override's day from UTC, because the column is@db.Dateand Prisma hydrates it at UTC midnight. Formatting that instant in a local zone shifted it a day west of UTC, which made a "closed on the 24th" override match bookings on the 23rd.validateWorkingHoursandgetBookingDefaultStartEndTimescompare against the acting user's preference zone, so an Amsterdam org's 9–5 is judged in Tokyo wall time for a Tokyo user.Why the second one is accepted rather than fixed
There is no
Organization.timeZone/WorkingHours.timeZoneto evaluate against, and in practice the people constrained by an org's working hours are at or near that location. Fixing it properly means storing the location's zone — migration, settings UI, backfill decision — which isn't worth it for the ~0.1% case of someone booking from another timezone.The rule states that plainly so nobody re-files it as a bug or "fixes" it by threading more user-zone logic through working hours. If it ever does need solving, the answer is a stored location zone, not a different user-side zone.
Also corrects the note at
prefsForDeclaredZone(added in #2896), which framed the same gap as a deferred product decision. It's the same rule reached from the client side, and now points at the rule file.Scope
Copy and documentation only — no behaviour change. Typecheck clean; 127 tests pass across the booking, working-hours and date-fns suites.
Related: #2896 (decode direction), #2905 (produce direction).
Summary by CodeRabbit