Small-fix bundle: round-detail scorecard, rounds-list copy, saved-views demo toast, On-the-Record drift, Ask rail layout - #928
Conversation
Bundle of 7 small, verified-live fixes:
1. Round detail scorecard: back nine's total column said "Out" (copied
from the front nine) — now reads "In" per golf convention.
2. Rounds list rows: "· 18h" read as hours — now "· 18 holes" / "· 9 holes".
3. Rounds list rows: a course with only course_state set (no course_city)
rendered the bare state code ("Va") as a stray unlabeled fragment next
to the type chip — location text is now only rendered when there's an
actual city to anchor it. Fixed across the round row, round card, and
the in-progress banner (same shared pattern in all three).
4. Baseball Stats Center saved-views loader: getStatVisualViews was a pure
read but not marked demoSafe, so the shared read-only demo account hit
withBaseballAction's fail-closed guard on every load and threw
BaseballDemoReadOnlyError — surfacing as a permanent "Saved views
unavailable" toast. Marked demoSafe: true (it performs no write); the
client hook also now silences the toast for permission/demo-flavored
failures specifically (genuine errors still toast for owners) and
dismisses any in-flight toast on unmount so it can't outlive a route
change.
5. "On the Record" KPI: Command Center derived it from the broader
box-score+practice rosterPulse (any session at all), Stats Center
derived it from officially-recorded games only — the two drifted
(8 vs 0) for a team with only practice sessions logged. Command Center
now reads Stats Center's own getStatsCenter() summary for this figure
instead of re-deriving it, so both surfaces share one definition.
Added regression coverage in command-center.test.ts.
6. Renamed the dev-y "Needs Recalc" KPI label to "Pending Updates". Golf
/golf/dashboard/coachhelm interstitial: a coach landing there now
redirects straight to their CoachHelm Brief (/golf/dashboard/intelligence)
instead of seeing the "access player insights from the roster page"
notice; the interstitial remains as a fallback for a coach with no
resolved organization yet.
7. Ask CoachHelm thread rail: the "Threads" bezel heading truncated to
"Thr…" against the thread-count readout because InstrumentPanel's
side-by-side bezel breakpoint reads viewport width, not this narrow
rail's own width — passed it as a ReactNode so InstrumentPanel skips
its default truncate class. Also removed a single-crumb breadcrumb
(the open thread's title) that rendered with none of CoachHelmShell's
breadcrumb affordances — just a bare span between the masthead and the
sub-nav tab bar, reading as a stray echo of the thread's question.
Gates: tsc --noEmit clean; eslint clean on all 12 changed files; vitest
run across command-center, stats-center, stat-visuals, and coachhelm
contract/regression suites — 60+192+78+528 tests, all passing.
Part of #908, Part of #909, Part of #916, Part of #917
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMdviLDsAg2YYJ8adsM6fg
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Warning Review limit reached
Next review available in: 10 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
✨ Finishing Touches🧪 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 |
|
🤖 Mission Control — PR summary What it changes: Bundle of 7 small, verified-live fixes:
Risk / areas: golf round-detail / rounds-list, baseball stats-center demo guard, CoachHelm Ask rail. Watch: CI: ✅ green so far — 34 checks passing, 4 pending, 0 failing; mergeable state BLOCKED on required review (no CI failure). Awaiting review. |
Problem
Seven small, verified-live bugs, bundled per the parent issue set:
· 18hreads as "18 hours" instead of holes.course_stateis set butcourse_cityis null renders the bare state code (e.g."Va") as a stray, unlabeled fragment next to the type chip ("TOURNAMENT Va · 18h"). Same pattern existed in the round card and the in-progress banner.getStatVisualViewsis a pureSELECTbut wasn't markeddemoSafe, sowithBaseballAction's fail-closed demo guard blocked every load for the shared read-only demo account, throwingBaseballDemoReadOnlyErrorand surfacing a permanent "Saved views unavailable" toast that also outlived route changes (sonner's Toaster is mounted once at the app root, independent of the component that fired the toast).rosterPulse(any session at all counts), Stats Center derived it from officially-recorded games only (noData= zero batting/pitching/catching/fielding/baserunning events). Same team, same moment: Command Center showed 8, Stats Center showed 0./golf/dashboard/coachhelmroute saw an interstitial pointing them at "the roster page" instead of just being routed to their own Brief.CoachHelmShell's breadcrumb affordances — just a bare span sitting between the masthead and the tab bar, reading as a stray echo of the thread's question.Fix
FairwayRoundDetail.tsx—ScorecardNine's desktop table now derives the total-column label from which nine it's rendering (Front→ "Out",Back→ "In") instead of a hard-coded "Out".FairwayRoundRow.tsx(+FairwayRoundCard.tsxfor the same badge pattern) —{holesPlayed}h→{holesPlayed} {holesPlayed === 1 ? 'hole' : 'holes'}.FairwayRoundRow.tsx,FairwayRoundCard.tsx,FairwayUnfinishedBanner.tsx— the sharedcityderivation now only joinscourse_stateonto an actualcourse_city; a state alone is dropped rather than rendered bare.stat-visual-views.ts—getStatVisualViewsmarkeddemoSafe: true(it performs no write, matching the established pattern for every other read-only action instats.ts/academics.ts/discover.ts).use-stat-visual-views.tsadditionally silences the toast for permission-denied/demo-flavored failures specifically (genuine load failures still toast for real owners) and captures the toast id to dismiss it in the effect's cleanup, so it can't survive an unmount/route change.command-center.ts—summary.playersWithDatanow readsstatsCenterModel.summary.playersWithData(the samegetStatsCenter()call this file already makes for career-avg reconciliation) instead of re-deriving its own count fromrosterPulse. Both surfaces now share one function/definition of "on the record." Added regression assertions incommand-center.test.tslocking in both the practice-only (0) and box-score (1) cases.StatsCenterClient.tsx— KPI label "Needs Recalc" → "Pending Updates".golf/dashboard/coachhelm/page.tsx— a coach with a resolved organization nowredirect()s straight to/golf/dashboard/intelligence(the coach Brief); the interstitial remains only for the genuine edge case of a coach with no resolved organization yet (mid-onboarding), where the Brief route can't resolve a team either.AskConversationRail.tsx— the "Threads" header is now passed as aReactNoderather than a string, soInstrumentPanelskips its defaulttruncateclass (only applied to string headers) and the heading wraps instead of hard-ellipsizing.AskWorkspace.tsx— dropped the single-crumb thread-title breadcrumb entirely (no href, no navigational value — the rail already highlights the open thread) rather than restyling a crumb trail that never had real ancestor/chevron chrome to begin with.Gates
npx tsc --noEmit -p tsconfig.json— clean.npx eslint <12 changed files>— clean.npx vitest runacross the touched/adjacent suites — all passing:command-center.test.ts+command-center-stats-center-drift.test.ts(60 tests)CoachHelmSubNav.test.tsx,nav-registry.test.ts,FairwayUnsyncedRoundBanner.test.ts(528 tests)StatVisualsSection.import-href.test.tsx,stat-visuals.test.ts,elite-stat-events.test.ts(192 tests)Caveats
FairwayRoundCard.tsx's micro-stat hover reveal or any other card content — it isn't currently mounted byFairwayRoundsLibrary(onlyFairwayRoundRowis), so its "18h"/city fixes are dead-code-safe consistency fixes, not a live-bug fix on their own.NotPlayerStatein place (now gated on!coach.organization_id) rather than deleting it —noUnusedLocalsrequires it stay reachable, and it's a reasonable fallback for a coach mid-onboarding.Part of #908, Part of #909, Part of #916, Part of #917
🤖 Generated with Claude Code
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01MMdviLDsAg2YYJ8adsM6fg