Skip to content

fix: Codex QA follow-ups on Today's Pulse (refresh wiring, cache hour guard, hook tests) - #46

Merged
pitimon merged 1 commit into
mainfrom
fix/pulse-qa-followups
Jul 5, 2026
Merged

fix: Codex QA follow-ups on Today's Pulse (refresh wiring, cache hour guard, hook tests)#46
pitimon merged 1 commit into
mainfrom
fix/pulse-qa-followups

Conversation

@pitimon

@pitimon pitimon commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Independent QA gate (Codex gpt-5.5, 7-gate pass) on the shipped 0.39.30 pulse. Verdicts: Accuracy Pass, UX/Flow Pass, Security/Privacy Pass; two correctness Fixes + a Handoff Risk addressed here.

Summary

  • Goal (Fix): refreshAll() refreshed every dashboard panel except Pulse — the manual/auto refresh button left the card to catch up only via effect deps. Now refreshPulse() is in refreshAll's Promise.all + deps.
  • Edge Case (Fix): cache could paint stale across an hour rollover — storageKey is day-keyed, so a pulse cached at 13:xx could show under the 14:00 "same time of day" label. Added readFreshCache() that only reuses an entry whose stored cutoffHour matches the current hour (guards both the instant-seed paint and the error fallback).
  • Handoff (Risk): the highest-risk hook logic (window off-by-one, daily+hourly reduction) had no direct tests. Extracted it to a pure pulse-plan.ts and added table tests: day/week/month key math, no double-count of today/boundary days, zero trailing days, missing prev, offset-hour derivation, inclusive ranges.

Deferred (honest disposition, not "pass")

  • Copy (Fix): PulseCard hardcodes user-facing strings instead of the copy() i18n registry. Deferred: this is an English-primary local tool, copy() would fall back to English for ja/ko/zh anyway (no translations exist), and the ui-hardcode baseline already accepts the entries. Tracked as follow-up if full i18n is wanted.

Test plan

  • pulse-plan tests (10) + pulse-stats tests (17) green
  • Full dashboard vitest: 282 pass (+10)
  • ci:local green — root 775, copy, ui-hardcode (unchanged), guardrails 4/4
  • Build clean; pure extraction is behavior-preserving (live behavior already verified pre-refactor on :17680)
  • Post-merge: fold into next release (no user-visible change beyond correct refresh + no stale-hour flash)

Independent QA (Codex gpt-5.5, 7-gate) on the shipped 0.39.30 pulse
surfaced two correctness gaps + a test-coverage gap. Fixes:

- Goal: refreshAll() didn't refresh the pulse — the manual/auto refresh
  button updated every panel except Pulse (it only re-ran via effect
  deps). Wire refreshPulse into refreshAll's Promise.all + deps.
- Edge Case: cache stale across hour rollover — storageKey is keyed by
  day, so a pulse cached at 13:xx could paint under the 14:00
  "same time of day" label. Add readFreshCache() that only reuses a
  cache entry whose stored cutoffHour matches the current hour (guards
  both the seed paint and the error fallback).
- Handoff: the highest-risk hook logic (buildPlan window off-by-one,
  daily+hourly reduction) had no direct tests. Extract it to a pure
  pulse-plan.ts module and add table tests for day/week/month key math,
  no-double-count of today/boundary days, zero trailing days, missing
  prev, DST-free offset hour, and inclusive ranges.

Accuracy + Security gates passed as-is. Copy gate (hardcoded PulseCard
strings vs the i18n registry) is deferred — see PR notes.
@pitimon
pitimon merged commit 06ef3bd into main Jul 5, 2026
1 check passed
@pitimon
pitimon deleted the fix/pulse-qa-followups branch July 5, 2026 10:43
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