Skip to content

fix(baseball): populate demo program season/risks/recruiting + Command Center & calendar polish - #937

Closed
njrini99-code wants to merge 1 commit into
mainfrom
feat/baseball-demo-population
Closed

fix(baseball): populate demo program season/risks/recruiting + Command Center & calendar polish#937
njrini99-code wants to merge 1 commit into
mainfrom
feat/baseball-demo-population

Conversation

@njrini99-code

Copy link
Copy Markdown
Owner

Problem

The public BaseballHelm demo ("Demo University Baseball", entered via /baseball/demo) promises "fully-populated" but — once past the Phase-1 seed (scripts/seed-baseball-demo.ts) — actually shows an empty program:

  • Stats Center: 0 games on record
  • Command Center: 0 open risk flags
  • Pipeline: an empty recruiting board
  • Calendar: a single, likely-stale practice

Separately (#911 polish):

  • Command Center stacked two identical "Standing by — awaiting first pitch." empty-state cards (CoverHero's weekly-cover letter and the morning-brief letter), reading as a bug rather than two distinct honest empty states.
  • The baseball calendar's month label could collapse to "J…" at desktop widths, and a long event title in the month-view grid clipped hard (no ellipsis) at the day cell's right edge instead of eliding.

Fix

New idempotent seed script — scripts/seed-baseball-demo-program.ts (Phase 4 of the existing demo-seed family; re-derives Phase-1's org/team/coach/roster ids the same way seed-baseball-lifting-demo.ts already does, rather than re-seeding them):

  1. A believable, already-completed ~20-game season (17 official + 3 scrimmage) spanning Feb–May of an "evergreen" season year (computed from now, not hardcoded), with box-score-level baseball_box_score_batting/baseball_box_score_pitching lines for the roster's 6 hitters + 2 pitchers. Generated by a new deterministic simulator, src/lib/baseball/seed/demo-program-sim.ts, whose invariants — team runs == sum of batting r, runs allowed == sum of pitching r, IP always sums to exactly 9 — are enforced by construction (derived from the simulation, never independently targeted and reconciled after the fact). baseball_player_season_stats is then derived via the same recalculate_baseball_season_stats RPC the app's own box-score save flow calls — never a hand-authored aggregate row.
  2. 3 open (status='active') baseball_coach_insights risk flags, each citing real seeded data (a pitcher-workload flag, a batting cold-streak flag, a stale-recruiting-outreach flag).
  3. A recruiting board: 3 small, clearly-fictional feeder programs (a high school, a showcase org, a JUCO) + 8 recruit baseball_players rows (recruiting_activated=true, never college type) in baseball_watchlists across all 4 active pipeline stages (watchlist/high_priority/offer_extended/committed).
  4. A rolling lifting-session history (8 sessions/player, alternating squat/bench, reusing Phase-1's own exercises — no duplicate catalog entries).
  5. A rolling calendar: 7 more upcoming baseball_events (practices, a team meeting, a fall exhibition) + 2 more baseball_practices (with blocks), so Practice Planner shows more than Phase-1's single practice.

Safety: dry-run by default (prints the plan, writes nothing); --confirm required to write; every id is deterministic (sha1 under its own namespace, distinct from every sibling seed script's); every write is .upsert(..., { onConflict }) — no .delete() anywhere. Wired into the existing npm run seed:baseball:demo chain, and scripts/verify-baseball-demo-coverage.ts + docs/seed/BASEBALLHELM_DEMO_DATA_CONTRACT.md updated to reflect the newly-covered surfaces (baseball_games, box scores, baseball_watchlists moved out of "intentionally empty").

UI polish (#911):

  • CommandCenterFairway.tsx: the morning-brief empty state now reads "Standing by — the desk is quiet." (calls back to the "— From the desk of CoachHelm" signoff already on that card) instead of duplicating CoverHero's own weekly-cover "Standing by — awaiting first pitch." verbatim.
  • page-header.tsx (shared calendar header, golf + baseball): the month-label <h2> was the only header item with min-w-0 and no floor — any shortfall in available width (even a small one at desktop widths) dumped entirely onto it via the flex-shrink algorithm, collapsing "September 2026" down to "J…". Added md:/lg: min-width floors (mobile keeps the original unconstrained min-w-0 — the fix that already exists there for the 390px Today-pill-clipping case is untouched) and shrink-0 on the nav-arrows/Today controls so they stop competing with the title for space.
  • PremiumEventBlock.tsx (month-view event chip, golf + baseball): the title <span> was a flex item of its row without min-w-0, so truncate's overflow:hidden/ellipsis never actually activated (flex items default to min-width:auto, refusing to shrink below their content). A long event title overflowed the pill and got hard-clipped (no ellipsis) at the day cell's edge — visible at the calendar's right edge for the rightmost day-of-week column. Fixed with min-w-0 on the title span.

Gates

  • npx tsc --noEmit -p tsconfig.json — 0 errors (full project)
  • npx eslint <every changed/new file> — 0 errors, 0 warnings
  • npx vitest run --project unitfull suite: 557 files, 5413 passed, 14 pre-existing skips, 0 failed. Includes the new src/lib/baseball/seed/__tests__/demo-program-sim.test.ts (17 tests: determinism, tie-avoidance, and every invariant above, individually asserted per-game rather than spot-checked) and the existing scripts-no-committed-secrets.test.mjs (extended with the new script's allowlisted demo-password literal) and verify-baseball-demo-coverage.test.ts (unaffected — confirmed via node --test since that suite isn't wired into vitest, same as its 46 siblings).
  • Hand-verified the season generator end-to-end via a standalone tsx run outside the repo (20/20 games self-consistent under every invariant, 9-11 record, believable per-game score lines and season batting lines .244–.387) — not committed, scratch-only.

Caveats

  • The seed script is shipped REVIEWED-ONLY — I never ran it against the shared prod Supabase (no .env.local in this environment, and per instructions this ships as a script for a human to run with --confirm).
  • Season dates are "evergreen" (computed from the script's run date each time, not hardcoded to 2026), so a future re-run still reads as a just-finished spring instead of silently going stale — same pattern already used by Phase-1's calendar events.
  • docs:check reports pre-existing, unrelated inventory drift on memory/projects/golfhelm.md (new admin/golf routes from already-merged PRs this branch didn't touch) — confirmed unrelated and left untouched rather than folded into this diff.

Fixes #912. Part of #911.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01MMdviLDsAg2YYJ8adsM6fg

…d Center & calendar polish

Fixes #912 + #911 polish.

Problem: the public BaseballHelm demo ("Demo University Baseball", entered
via /baseball/demo) promises "fully-populated" but past Phase-1 seeding
shows an empty program — 0 games on record in Stats Center, 0 open risk
flags, an empty recruiting board, and one stale practice on the calendar.
Separately, Command Center stacked two identical "Standing by — awaiting
first pitch." empty-state cards, and the calendar header's month label
could collapse to "J…" at desktop widths with the event pill clipping
(no ellipsis) at the calendar's right edge.

Fix:
- New idempotent scripts/seed-baseball-demo-program.ts (Phase 4 of the
  demo-seed family, re-derives Phase-1's org/team/coach/roster ids rather
  than re-seeding them): a believable ~20-game completed season (17
  official + 3 scrimmage) with box-score-level batting/pitching lines per
  roster player, generated by a deterministic simulator
  (src/lib/baseball/seed/demo-program-sim.ts, unit-tested) whose invariants
  (batting R == team score, pitching R == runs allowed, IP always sums to
  9) are enforced by construction, not asserted after the fact. Season
  stats are derived via the same recalculate_baseball_season_stats RPC the
  app's own box-score save flow calls, never hand-authored. Also seeds 3
  open (status='active') risk flags, a recruiting board (3 fictional
  feeder programs + 8 recruits across all 4 active pipeline stages), a
  rolling lifting-session history, and more upcoming calendar
  events/practices. Dry-run by default; --confirm required to write;
  wired into the existing `npm run seed:baseball:demo` chain and
  verify-baseball-demo-coverage.ts's required-surface list.
- CommandCenterFairway.tsx: the morning-brief empty state now reads
  "Standing by — the desk is quiet." (ties to the "From the desk of
  CoachHelm" signoff) so it no longer duplicates CoverHero's own weekly-
  cover "Standing by — awaiting first pitch." card verbatim.
- page-header.tsx (shared calendar header, golf + baseball): the month
  label was the ONLY header item with `min-w-0` and no floor, so any
  shortfall in available width dumped entirely onto it even at desktop
  widths — added `md:`/`lg:` min-width floors (mobile keeps the original
  unconstrained behavior) and `shrink-0` on the nav/Today controls so they
  stop competing with the title for space.
- PremiumEventBlock.tsx (month-view event chip, golf + baseball): the
  title span was a flex item without `min-w-0`, so `truncate`'s ellipsis
  never actually activated — a long title overflowed the pill and got hard
  -clipped (no ellipsis) at the day cell's edge instead of eliding.

Gates: npx tsc --noEmit (0 errors) — npx eslint on every changed file (0
errors/warnings) — npx vitest run --project unit (full suite: 557 files,
5413 passed, 14 pre-existing skips, 0 failed), including the new
demo-program-sim.test.ts (17 tests covering determinism + every
by-construction invariant) and the existing
scripts-no-committed-secrets.test.mjs / verify-baseball-demo-coverage
tests. Also hand-verified the season generator via a standalone tsx run
(20/20 games self-consistent, 9-11 record, believable score lines).

Caveats: the seed script is shipped REVIEWED-ONLY — never executed
against the shared prod Supabase from this session; a human runs
--confirm. Season dates are evergreen (computed from "now" each run, not
hardcoded to 2026) so a future re-run still reads as a just-finished
spring instead of going stale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMdviLDsAg2YYJ8adsM6fg
@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

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.

@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
helmv3 Ignored Ignored Jul 17, 2026 10:53pm

Request Review

@supabase

supabase Bot commented Jul 17, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project qmnssrrolpinvwjjnufo because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@njrini99-code, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4d7f6578-015b-4660-beec-94929a59aa6e

📥 Commits

Reviewing files that changed from the base of the PR and between 6d25e44 and 8b920f5.

📒 Files selected for processing (10)
  • docs/seed/BASEBALLHELM_DEMO_DATA_CONTRACT.md
  • package.json
  • scripts/__tests__/scripts-no-committed-secrets.test.mjs
  • scripts/seed-baseball-demo-program.ts
  • scripts/verify-baseball-demo-coverage.ts
  • src/components/baseball/command-center/CommandCenterFairway.tsx
  • src/components/golf/calendar/PremiumEventBlock.tsx
  • src/components/ui/page-header.tsx
  • src/lib/baseball/seed/__tests__/demo-program-sim.test.ts
  • src/lib/baseball/seed/demo-program-sim.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/baseball-demo-population
  • 🛠️ helm safety pass
  • 🛠️ dashboard ux pass
  • 🛠️ rls test pass

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@njrini99-code

Copy link
Copy Markdown
Owner Author

🤖 Mission Control — PR summary

What it changes: Populates the public BaseballHelm demo program (#912) + Command Center / calendar polish (#911). Adds idempotent scripts/seed-baseball-demo-program.ts (Phase 4 — re-derives Phase-1 org/team/coach/roster ids rather than re-seeding) generating a believable ~20-game completed season (17 official + 3 scrimmage) with box-score-level batting/pitching lines per player via a deterministic simulator (src/lib/baseball/seed/demo-program-sim.ts + test). UI: dedups Command Center's doubled "Standing by — awaiting first pitch" empty-state (CommandCenterFairway.tsx) and fixes the calendar month-label collapse + event-pill clip (PremiumEventBlock.tsx, page-header.tsx).

Area: BaseballHelm.

Risk / reviewers watch:

  • Seed-script idempotency + id re-derivation (must not duplicate Phase-1 rows).
  • Simulator determinism / box-score realism — covered by demo-program-sim.test.ts.
  • Command Center empty-state de-dup + calendar clip at desktop widths.

CI: 4 required gates green. CodeRabbit advisory + REVIEW_REQUIREDBlocked. No action taken.

@njrini99-code

Copy link
Copy Markdown
Owner Author

Superseded — landed on main inside merge train #938 (commit 6ecede6). Branch kept.

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.

[QA] Baseball public demo contradicts its own pitch — 'fully-populated' but empty

1 participant