Skip to content

feat(usage): anchor day/hour grid to each user's actual reset time#139

Open
jonasnobile wants to merge 1 commit into
mainfrom
feat/usage-grid-reset-anchored
Open

feat(usage): anchor day/hour grid to each user's actual reset time#139
jonasnobile wants to merge 1 commit into
mainfrom
feat/usage-grid-reset-anchored

Conversation

@jonasnobile

Copy link
Copy Markdown
Member

Summary

Follow-up to #137. The usage-bar grid was a plain even split (i / segments), which only coincidentally lined up with day/hour boundaries for clean windows — it wasn't actually derived from the reset. It drifted for any other reset time, for non-integer windows (Codex 30d → 14 even blocks, 1d → 12 even blocks), and across DST.

Now boundaries are computed from the real reset timestamp using jiff calendar arithmetic, so blocks land on the user's own reset time-of-day. A Sun 12:00 weekly reset yields noon-to-noon day blocks; a user whose reset is Wed 03:00 gets blocks anchored there. The current-segment highlight uses the same boundaries, so it always marks the real "today" / "this hour" block.

Changes

  • Claude: thread the raw ISO reset + window length through TierUsage. Session → hour granularity; the 7-day tiers → day granularity. New reset_aligned_segments() returns the divider fractions + current-block range.
  • Codex: add jiff; derive boundaries from the epoch reset_at + window_seconds, choosing hour/day granularity per window (segment_unit_for_window); sub-hour windows get no grid.
  • Long windows step by a whole multiple of the unit (e.g. every 2 days) so a thin bar stays legible while staying reset-anchored.
  • Replaced the old segments_for_window test with segment_unit_for_window + reset_aligned_segments tests (guards + weekly-window invariants).

Notes

  • Boundaries use wall-clock calendar steps (jiff), so a block stays "noon to noon" across a DST change even though that block is 23h/25h of real time. The pace marker still uses the fixed-seconds elapsed %, so across a DST transition the marker and a boundary can sit up to ~1h apart for that one block — acceptable and rare.
  • For the common 7-day / 5-hour windows in a DST-free week this is visually identical to the previous even split — the change is correctness for other reset times, odd window lengths, and DST.

Test plan

  • cargo build (pinned 1.95.0 toolchain) — both crates
  • cargo clippy — clean
  • cargo test — 28 pass
  • Visual check in the running app that the weekly grid lines sit on local noon and "today" is highlighted

🤖 Generated with Claude Code

The usage-bar grid previously split the bar into N even segments, which only
*coincidentally* lined up with day/hour boundaries for clean windows — it was
not derived from the reset at all, and drifted for any other reset time, for
non-integer windows (e.g. Codex 30d/1d), and across DST.

Compute boundaries from the real reset timestamp with jiff calendar
arithmetic instead, so blocks land on the user's own reset time-of-day (a
Sun 12:00 weekly reset yields noon-to-noon day blocks) and stay correct
across DST. The current-segment highlight now uses the same boundaries, so
it always marks the real "today"/"this hour" block.

- Claude: thread the raw ISO reset + window length through TierUsage; Session
  uses hour granularity, the 7-day tiers use day granularity.
- Codex: add jiff; derive boundaries from the epoch reset_at + window_seconds,
  picking hour/day granularity per window (sub-hour windows get no grid).
- Long windows step by a whole multiple of the unit so a thin bar stays
  legible while remaining reset-anchored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant