Skip to content

fix(baseball): Fairway routing + Helm Bridge observability (unified)#787

Merged
njrini99-code merged 7 commits into
mainfrom
cursor/baseball-fairway-routing-6886
Jul 4, 2026
Merged

fix(baseball): Fairway routing + Helm Bridge observability (unified)#787
njrini99-code merged 7 commits into
mainfrom
cursor/baseball-fairway-routing-6886

Conversation

@njrini99-code

@njrini99-code njrini99-code commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Unified Fairway shell routing + Helm Bridge observability on one branch.

Fairway routing

  • Hub-based nav with activeMatch / matchPrefixes wired through route-contract
  • Legacy bookmark redirects via middleware; stub redirect pages removed
  • Mobile bottom nav derived from same hub sections as desktop rail
  • Settings hub UI + management sub-tabs

Helm Bridge observability

  • Soft-failure capture (observeActionSoftFailure), incident feed, Ben+Leah board
  • Baseball auth/bootstrap polish, admin nav shortcut fixes

CodeRabbit polish (latest)

  • matchPrefixes moved onto BaseballNavEntry in nav-registry (single source of truth)
  • Player role resolution prefers cached navContext.role (no coach-nav flash)
  • Segment-boundary prefix matching aligned across shell + bottom nav
  • Shared RECRUITING_PROGRAM_TYPES export; management settings supplement dev guard
  • Settings page deduped (privacy/notifications); consolidated tiles get focus rings
  • FairwayBottomNav active state uses nullish coalescing like sidebar

CI fixes

  • Harden soft-failure logging for test mocks
  • Stat-layer scan excludes feature-registry metadata
  • Structured console.error for CodeQL

Supersedes #786 — close that PR when this merges.

Open in Web Open in Cursor 

Finish Codex's interrupted Fairway migration: hub-based nav with activeMatch
prefixes, player layout shell mounting, Management settings leaves, messages
thread ownership in route-contract, legacy bookmark redirects in middleware,
and player Settings in the secondary rail. Removes dead redirect stub pages
in favor of middleware aliases. Route coverage gaps reduced from 51 to 20
(all intentional auth/public/onboarding surfaces).
@supabase

supabase Bot commented Jul 4, 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 ↗︎.

@vercel

vercel Bot commented Jul 4, 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 Preview Jul 4, 2026 8:44pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 276d1317-06f7-44b7-b7f0-fb3003d11a1d

📥 Commits

Reviewing files that changed from the base of the PR and between 57e0de1 and 4f3e653.

📒 Files selected for processing (1)
  • src/lib/server-error-logger.ts

Summary by CodeRabbit

  • New Features

    • Added a new admin “Work log” timeline view for tracking recent shipping activity.
    • Expanded baseball navigation with clearer hub-based menus, including recruiting and settings sections.
    • Added a more structured issue tracker view in the admin area with workflow controls and auto-refresh.
  • Bug Fixes

    • Improved route handling by removing outdated redirects and aligning legacy links with current destinations.
    • Fixed pitching stats calculations for partial innings.
    • Updated auth/session behavior to keep active users signed in more reliably while reading pages.

Walkthrough

This PR removes legacy Baseball redirect pages, refactors Baseball auth and shell selection, adds admin work-log and incident-feed surfaces, and introduces Ben-Leah issue tracking plus workflow controls.

Changes

Baseball navigation, shells, and legacy routes

Layer / File(s) Summary
Hub definitions and active hub
src/app/baseball/(dashboard)/_components/hub-definitions.ts, src/app/baseball/(dashboard)/_components/resolve-active-hub.ts, src/lib/baseball/route-contract.ts, src/lib/baseball/nav-manifest.ts, src/lib/baseball/nav-registry.ts, src/lib/baseball/stats-route-aliases.ts, src/lib/baseball/__tests__/stats-route-aliases.test.ts
Adds settings and recruiting hub tabs, copies route match prefixes into hub tabs, extends route-contract and nav manifest coverage for the new hub and messages prefix behavior, and removes the legacy stats/games/new alias.
Shell selection and dashboard wiring
src/app/baseball/(dashboard)/BaseballFairwayShell.tsx, src/app/baseball/(dashboard)/layout.tsx, src/app/baseball/(player-dashboard)/player/layout.tsx, src/app/baseball/(player-dashboard)/player/passport/page.tsx, src/app/baseball/(coach-dashboard)/coach/template.tsx, src/app/baseball/(dashboard)/dashboard/settings/page.tsx, src/components/fairway/app-shell/FairwayBottomNav.tsx, src/components/fairway/app-shell/FairwaySidebar.tsx, src/components/layout/sidebar.tsx, src/app/baseball/(dashboard)/_components/hub-sub-nav.tsx
Rebuilds BaseballFairwayShell navigation, adds authVerified and requiredRole props, switches dashboard and player layouts to the redesign shell, updates the settings page, and tightens active-match typing and precedence.
Legacy redirects and route contract tests
src/lib/supabase/middleware.ts, src/test/helpers/baseball-route-inventory.ts, src/app/baseball/actions/__tests__/route-shell-contract.test.ts, scripts/__tests__/baseball-stale-route-links.test.mjs, src/lib/baseball/__tests__/settings-aliases-and-legacy-redirects.test.ts, src/lib/baseball/__tests__/resolve-active-hub.test.ts, src/lib/baseball/__tests__/nav-manifest.test.ts
Adds middleware-level legacy Baseball redirects, updates the route inventory manifest, removes stale route-link allowlist entries, and refreshes route-shell contract coverage for the legacy aliases and player nav checks.
Pitching rate conversion
src/app/baseball/actions/games.ts, src/app/baseball/actions/__tests__/save-full-box-score.test.ts, src/contracts/baseball/stats/pitching-invariants.test.ts
Uses ipToInnings in pitching calculations, adds my-stats to revalidation paths, and updates the save-full-box-score test plus pitching invariants contract to match the derived innings math.
Game card detail link
src/components/baseball/games/GameCard.tsx
Wraps GameCard in a detail Link, computes a stable opponent label, and replaces the Box Score and Enter Results links with non-link spans while keeping the same conditional rendering.

Baseball auth, session, and action observability

Layer / File(s) Summary
Baseball auth cache and redirects
src/components/auth/baseball-sign-in-form.tsx, src/components/baseball/BaseballDashboardBootstrap.tsx, src/components/baseball/BaseballShellLayout.tsx, src/hooks/use-baseball-auth.ts, src/hooks/use-baseball-nav-context.ts, src/hooks/__tests__/use-baseball-auth.test.tsx
Returns the full user record from baseball auth, warms auth/nav state from cache, hydrates the store with user data, changes sign-in redirects to replace, and adds the branded dashboard bootstrap loading component.
Visible-heartbeat session idle handling
src/lib/auth/session-activity.ts, src/lib/auth/session-idle-shared.ts, src/test/lib/auth/session-idle-shared.test.ts, src/components/providers/SessionActivityProvider.tsx
Adds the visible heartbeat interval, updates session logout redirects for admin routes, and wires visibility/page-restore listeners plus cleanup into the shared session-activity hook and its tests.
Soft-failure logging and trace enrichment
src/lib/admin/observe-action-result.ts, src/lib/admin/observed-action.ts, src/lib/baseball/with-baseball-action.ts, src/lib/lifting/with-lifting-action.ts, src/lib/server-error-logger.ts, src/lib/__tests__/server-error-logger-bridge.test.ts, src/lib/baseball/__tests__/with-baseball-action-observability.test.ts, src/lib/admin/__tests__/observe-action-result.test.ts, src/app/baseball/actions/__tests__/demo-access.test.ts, src/app/golf/actions/__tests__/coverage-contract.observability.test.ts
Adds soft-failure extraction and logging, wires Baseball and lifting wrappers to call it, and enriches server error trace persistence with inferred sport metadata and updated coverage/tests.
PR body parsing for work log
src/lib/admin/pr-body-parser.ts, src/lib/admin/__tests__/pr-body-parser.test.ts
Adds deterministic PR template parsing and tests for section extraction, area inference, and partner-readable summary splitting.

Admin work log, incident feed, and Ben-Leah tracking

Layer / File(s) Summary
Admin navigation and shell wiring
src/app/admin/_components/AdminShell.tsx, src/app/admin/_components/admin-nav.ts, src/app/admin/_components/__tests__/admin-nav.test.ts
Adds the /admin/work nav entry and shortcut set, updates the admin shell icon mapping, and wraps the shell in the session activity provider.
Work log page and timeline
src/app/admin/work/page.tsx, src/app/admin/work/WorkTimeline.tsx, src/lib/admin/github-pr-timeline.ts, .env.example
Adds the PR timeline fetcher and renders the dynamic admin work-log page with the month-grouped timeline UI and auto-refresh.
Incident feed and admin incident pages
src/lib/admin/data/incident-feed.ts, src/lib/admin/data/errors.ts, src/lib/admin/data/overview.ts, src/lib/admin/data/triage.ts, src/app/admin/errors/page.tsx, src/app/admin/page.tsx, src/lib/admin/data/__tests__/incident-feed.test.ts
Introduces the shared incident-feed module and rewires overview, triage, and errors pages to use aggregated counts and wider-window fields.
Ben-Leah issue tracking and GitHub workflow
src/lib/admin/ben-leah-issue-tracker.ts, src/lib/admin/ben-leah-issues.ts, src/lib/admin/github-issues-config.ts, src/lib/admin/github-issues-workflow.ts, src/lib/admin/github-feedback.ts, src/app/admin/ben-leah/page.tsx, src/app/admin/ben-leah/BenLeahIssueBoard.tsx, src/app/admin/ben-leah/BenLeahIssueTable.tsx, src/app/admin/ben-leah/BenLeahIssueWorkflowSelect.tsx, src/app/admin/ben-leah/actions.ts, src/lib/admin/__tests__/ben-leah-issues.test.ts
Adds the Ben-Leah tracking types and status derivation helpers, GitHub issue fetch/config helpers, workflow-label mutation helpers, the feedback issue path, and the admin board/table/select UI plus server action.
Estimated code review effort: 5 (Critical) ~120 minutes

Possibly related PRs

  • njrini99-code/helmv3#574: Both PRs touch the player onboarding completion flow—specifically completePlayerOnboarding in src/app/baseball/actions/onboarding.ts—so the redirect change here is directly related.
  • njrini99-code/helmv3#650: Both PRs modify the redesigned Baseball navigation shell, including BaseballFairwayShell.tsx and hub resolution.
  • njrini99-code/helmv3#730: Both PRs touch the shared session-idle behavior and visible-heartbeat timeout logic used by Baseball dashboards.
🚥 Pre-merge checks | ✅ 10 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning A golf-specific observability contract test was added in src/app/golf/actions/tests/coverage-contract.observability.test.ts, which is outside the Baseball/Fairway scope. Move the golf observability coverage into a separate PR unless it is explicitly required by the linked issue.
Conventional Commits ❓ Inconclusive HEAD subject matches the Conventional Commits regex, but the PR title isn't exposed here so I can't verify both required strings. Provide the actual PR title (or PR metadata) so the title and squash subject can both be checked against the regex.
✅ Passed checks (10 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR covers the linked issue goals: soft-failure logging, shared incident feed, route/login fixes, and admin platform additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
No Service-Role In Client Bundles ✅ Passed No changed client/server code outside allowed admin paths uses SUPABASE_SERVICE_ROLE_KEY or a service-role Supabase client; only .env.example:16 and server-error-logger.ts:667 are template/comment...
Rls Coverage On New Tables ✅ Passed No changed .sql migration files appear in the PR diff; only app/lib TS/TSX files changed, so the RLS coverage rule is vacuously satisfied.
Auth Check In Server Actions ✅ Passed Diff vs main shows only 5 changed src/app/**/actions test files; none export async functions, so no touched server action violates auth-before-RPC.
Sport-Prefixed Table Names ✅ Passed PASS: changed TS/TSX files only query prefixed tables (e.g. src/hooks/use-baseball-auth.ts:83-85, src/app/baseball/actions/games.ts:94-110); no `.from('coaches'|'players'|'teams'|'rounds'|'events')...
No Destructive Writes ✅ Passed games.ts uses atomic RPC instead of delete-then-insert (739-749); onboarding.ts uses upsert, not delete/insert (667-672).
No Edits To Historical Migrations ✅ Passed No files under supabase/migrations changed in the PR diff from the merge-base.
Title check ✅ Passed The title uses a valid Conventional Commits format and accurately summarizes the Baseball Fairway routing and Helm Bridge observability changes.
Description check ✅ Passed The description is clearly related to the PR and covers the Fairway routing, observability, admin, and CI work in the changeset.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/baseball-fairway-routing-6886
  • 🛠️ helm safety pass
  • 🛠️ dashboard ux pass
  • 🛠️ rls test pass

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.44.0)

ast-grep could not parse rule config: /ast-grep-rules/../git/.coderabbit/ast-grep/no-explicit-any.yml

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/lib/server-error-logger.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.


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

@coderabbitai coderabbitai Bot added ci CI, Vercel, test, build, deploy security Auth, secrets, RLS, PII, webhooks labels Jul 4, 2026
Combines fix/helm-bridge-observability-baseball-auth (soft-failure logging,
incident feed, baseball auth polish, Ben+Leah/work tabs) with the Fairway shell
routing and route-contract work. Dashboard layout keeps authVerified on both
shell branches after the session guard settles.
@cursor cursor Bot changed the title fix(baseball): complete Fairway shell routing and route-contract wiring fix(baseball): Fairway routing + Helm Bridge observability (unified) Jul 4, 2026
- Derive Fairway bottom tabs from the same hub sections as desktop rail
- Fix prefer-const in incident errors query builder
- Resolve ESLint token warnings in Ben+Leah workflow select and settings hub

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/baseball/(dashboard)/_components/hub-definitions.ts (1)

78-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded id-based matchPrefixes assignment is fragile.

toHubTab special-cases four registry ids (roster, performance, dev-plans, camps) by string literal to bolt on matchPrefixes. This duplicates route knowledge that should live alongside the registry entry itself (BaseballNavEntry) rather than as an out-of-band lookup table in the mapper function. If a fifth registry entry needs nested-route ownership, or if one of these ids is renamed, this silently stops working with no compile-time or test signal.

♻️ Suggested refactor
-function toHubTab(entry: BaseballNavEntry): HubSubNavTab {
-  const tab: HubSubNavTab = {
-    id: entry.id,
-    label: entry.label,
-    href: entry.href,
-    icon: entry.icon,
-    requiredCapability: entry.requiredCapability ?? undefined,
-    requiredAnyCapabilities: entry.requiredAnyCapabilities,
-    allowedProgramTypes: entry.allowedProgramTypes,
-  };
-
-  if (entry.id === 'roster') tab.matchPrefixes = ['/baseball/dashboard/players'];
-  if (entry.id === 'performance') tab.matchPrefixes = ['/baseball/dashboard/performance'];
-  if (entry.id === 'dev-plans') tab.matchPrefixes = ['/baseball/dashboard/dev-plans'];
-  if (entry.id === 'camps') tab.matchPrefixes = ['/baseball/dashboard/camps'];
-
-  return tab;
-}
+function toHubTab(entry: BaseballNavEntry): HubSubNavTab {
+  return {
+    id: entry.id,
+    label: entry.label,
+    href: entry.href,
+    icon: entry.icon,
+    requiredCapability: entry.requiredCapability ?? undefined,
+    requiredAnyCapabilities: entry.requiredAnyCapabilities,
+    allowedProgramTypes: entry.allowedProgramTypes,
+    matchPrefixes: entry.matchPrefixes,
+  };
+}

(requires adding matchPrefixes to BaseballNavEntry in the registry itself)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/baseball/`(dashboard)/_components/hub-definitions.ts around lines 78
- 95, The hardcoded id checks in toHubTab are duplicating route ownership and
making nested-route matching fragile. Move matchPrefixes onto BaseballNavEntry
in the registry itself, then have toHubTab simply copy that field into the
HubSubNavTab object along with the other entry properties. Update the registry
entries for roster, performance, dev-plans, and camps so the route prefixes live
beside the nav metadata instead of being inferred from entry.id.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/baseball/`(dashboard)/_components/hub-definitions.ts:
- Around line 187-193: Remove the redundant matchPrefixes entry from
SETTINGS_HOME_TAB in hub-definitions.ts; the tab’s href already contributes the
same path through resolve-active-hub.ts via ownedPrefixes, so keep only the href
and let the active-tab matching logic use that single source of truth.
- Around line 338-353: The COACH_MANAGEMENT_TABS supplement is keyed only by
'program-settings', so the SETTINGS_*_TAB block can disappear silently if that
base tab ever changes. Add a dev-time guard or unit test around
withSupplements/orderTabs in hub-definitions.ts that verifies the supplement key
exists in the hubEntries('management') result before applying the
SETTINGS_HOME_TAB through SETTINGS_AUDIT_TAB block, so the mismatch fails loudly
instead of dropping navigation.

In `@src/app/baseball/`(dashboard)/BaseballFairwayShell.tsx:
- Around line 573-592: The `resolvedRole` fallback in `BaseballFairwayShell` can
briefly default to `'coach'` on the `authVerified` dashboard path, causing the
wrong nav to flash for players. Update the role resolution to prefer the
synchronously available `navContext?.role` from `useBaseballNavContext()`
instead of falling back to a hardcoded coach value when `requiredRole` and
`role` are still null. Keep the existing auth gate in `BaseballFairwayShell`,
and ensure the role passed into `BaseballFairwayContent` stays aligned with the
cached session context rather than the async `useBaseballAuth` initial state.
- Around line 136-178: `playerHubToNavItem` uses a loose prefix match that can
incorrectly ակտիվate sibling routes; align it with `toNavItem` by checking
segment boundaries in the `activeMatch` logic. Update the `tabs?.some(...)` path
matching in `BaseballFairwayShell` so each `tab.matchPrefixes` comparison uses
the same `pathname === prefix || pathname.startsWith(`${prefix}/`)` pattern
already used in `toNavItem` and expected by `resolveActiveHub.ts`.
- Line 180: `RECRUITING_PROGRAM_TYPES` is duplicated in both
`BaseballFairwayShell` and `resolveActiveHub`, so move the shared set into a
single exported constant and import it from the other module. Use the existing
`RECRUITING_PROGRAM_TYPES` symbol as the source of truth, then update the hub
visibility logic and active-tab matching to reference that shared export so the
two nav paths stay aligned.

In `@src/app/baseball/`(dashboard)/dashboard/settings/page.tsx:
- Around line 94-107: Remove the duplicated settings navigation entries so each
destination is reachable from only one place. In the dashboard settings page,
update PLAYER_SETTINGS_LINKS and CONSOLIDATED_SETTINGS_LINKS to avoid re-adding
links that already exist as standalone cards, especially the privacy and
notification destinations. Use the existing settings card definitions and the
related link constants to keep a single source of truth for each settings page.
- Around line 259-276: The settings link card in the dashboard page uses
forbidden white background utilities outside the UI layer, so update the Link
styling in the CONSOLIDATED_SETTINGS_LINKS map render to replace bg-white/60 and
hover:bg-white with an approved surface treatment such as a glass utility,
bg-cream-* or a token-backed bg-surface-* class. Keep the rest of the card
structure unchanged and make the adjustment in the same Link/card block that
renders item.icon, item.label, and item.description.
- Around line 263-274: The consolidated tile links in the settings page lack a
visible keyboard focus indicator, unlike the interactive grid cards. Update the
raw Link-based tiles in the settings page so they include focus-visible styling
consistent with the Card variant="interactive" pattern, using the same kind of
focus-visible ring classes on the Link className. Locate the Link markup that
renders item.href/item.label/item.description and add a clear focus ring for
keyboard users.

In `@src/components/fairway/app-shell/FairwayBottomNav.tsx`:
- Around line 74-79: The bottom nav active state should match the sidebar’s
`NavItem.active` handling, since `FairwayBottomNav` currently uses `item.active
|| ...` and can override an explicit `false` value on route matches. Update the
active calculation in `FairwayBottomNav` to follow the same nullish-coalescing
pattern used in `FairwaySidebar`, so `NavItem.active` only falls back to
`activeMatch`/`matchActive` when it is unset and not when it is explicitly
false. Use the `items.map` block and the `active` assignment in
`FairwayBottomNav` as the target for the fix.

---

Outside diff comments:
In `@src/app/baseball/`(dashboard)/_components/hub-definitions.ts:
- Around line 78-95: The hardcoded id checks in toHubTab are duplicating route
ownership and making nested-route matching fragile. Move matchPrefixes onto
BaseballNavEntry in the registry itself, then have toHubTab simply copy that
field into the HubSubNavTab object along with the other entry properties. Update
the registry entries for roster, performance, dev-plans, and camps so the route
prefixes live beside the nav metadata instead of being inferred from entry.id.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 32013dbd-9357-422a-9bd0-8c091c15ced0

📥 Commits

Reviewing files that changed from the base of the PR and between afbbd27 and b133e8a.

📒 Files selected for processing (39)
  • scripts/__tests__/baseball-stale-route-links.test.mjs
  • src/app/baseball/(coach-dashboard)/coach/college/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/high-school/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/juco/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/showcase/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/template.tsx
  • src/app/baseball/(dashboard)/BaseballFairwayShell.tsx
  • src/app/baseball/(dashboard)/_components/hub-definitions.ts
  • src/app/baseball/(dashboard)/_components/resolve-active-hub.ts
  • src/app/baseball/(dashboard)/dashboard/settings/page.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/NewGameClient.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/error.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/loading.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/page.tsx
  • src/app/baseball/(dashboard)/dashboard/team/high-school/error.tsx
  • src/app/baseball/(dashboard)/dashboard/team/high-school/page.tsx
  • src/app/baseball/(dashboard)/layout.tsx
  • src/app/baseball/(player-dashboard)/player/college/page.tsx
  • src/app/baseball/(player-dashboard)/player/high-school/page.tsx
  • src/app/baseball/(player-dashboard)/player/juco/page.tsx
  • src/app/baseball/(player-dashboard)/player/layout.tsx
  • src/app/baseball/(player-dashboard)/player/passport/page.tsx
  • src/app/baseball/(player-dashboard)/player/showcase/page.tsx
  • src/app/baseball/actions/__tests__/route-shell-contract.test.ts
  • src/app/baseball/actions/__tests__/save-full-box-score.test.ts
  • src/app/baseball/actions/games.ts
  • src/components/baseball/games/GameCard.tsx
  • src/components/fairway/app-shell/FairwayBottomNav.tsx
  • src/components/fairway/app-shell/FairwaySidebar.tsx
  • src/contracts/baseball/stats/pitching-invariants.test.ts
  • src/lib/baseball/__tests__/resolve-active-hub.test.ts
  • src/lib/baseball/__tests__/settings-aliases-and-legacy-redirects.test.ts
  • src/lib/baseball/__tests__/stats-route-aliases.test.ts
  • src/lib/baseball/nav-manifest.ts
  • src/lib/baseball/nav-registry.ts
  • src/lib/baseball/route-contract.ts
  • src/lib/baseball/stats-route-aliases.ts
  • src/lib/supabase/middleware.ts
  • src/test/helpers/baseball-route-inventory.ts
💤 Files with no reviewable changes (15)
  • src/app/baseball/(player-dashboard)/player/showcase/page.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/loading.tsx
  • src/app/baseball/(coach-dashboard)/coach/high-school/page.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/NewGameClient.tsx
  • src/app/baseball/(player-dashboard)/player/college/page.tsx
  • src/app/baseball/(dashboard)/dashboard/team/high-school/page.tsx
  • scripts/tests/baseball-stale-route-links.test.mjs
  • src/app/baseball/(dashboard)/dashboard/team/high-school/error.tsx
  • src/app/baseball/(coach-dashboard)/coach/juco/page.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/college/page.tsx
  • src/app/baseball/(player-dashboard)/player/high-school/page.tsx
  • src/app/baseball/(player-dashboard)/player/juco/page.tsx
  • src/app/baseball/(coach-dashboard)/coach/showcase/page.tsx
  • src/app/baseball/(dashboard)/dashboard/stats/games/new/error.tsx

Comment thread src/app/baseball/(dashboard)/_components/hub-definitions.ts
Comment thread src/app/baseball/(dashboard)/_components/hub-definitions.ts
Comment thread src/app/baseball/(dashboard)/BaseballFairwayShell.tsx
Comment thread src/app/baseball/(dashboard)/BaseballFairwayShell.tsx Outdated
Comment thread src/app/baseball/(dashboard)/BaseballFairwayShell.tsx Outdated
Comment thread src/app/baseball/(dashboard)/dashboard/settings/page.tsx
Comment thread src/app/baseball/(dashboard)/dashboard/settings/page.tsx
Comment thread src/app/baseball/(dashboard)/dashboard/settings/page.tsx
Comment thread src/components/fairway/app-shell/FairwayBottomNav.tsx
@coderabbitai coderabbitai Bot removed the ci CI, Vercel, test, build, deploy label Jul 4, 2026
Comment on lines +75 to +82
const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}`, {
method: 'PATCH',
headers: {
...githubIssuesHeaders(token),
'content-type': 'application/json',
},
body: JSON.stringify({ labels }),
});
};

function stripHtmlComments(text: string): string {
return text.replace(/<!--[\s\S]*?-->/g, '');
Comment thread src/lib/server-error-logger.ts Fixed
Comment thread src/lib/server-error-logger.ts Fixed
Comment thread src/lib/server-error-logger.ts Fixed
Comment thread src/lib/server-error-logger.ts Fixed
Comment thread src/lib/server-error-logger.ts Fixed
Comment thread src/lib/server-error-logger.ts Fixed
return Promise.resolve(cachedContext);
}

if (userId === null) {
Wrap logServerError in Promise.resolve + try/catch so incomplete test mocks
and sync throws never break action results. Lower deprecated-entry sanity
threshold now that coach/player type redirects live in middleware.
@njrini99-code

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

♻️ Duplicate comments (1)
src/app/baseball/(dashboard)/BaseballFairwayShell.tsx (1)

168-174: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Loose prefix match still inconsistent with resolveActiveHub.ts's segment-boundary matching.

tab.matchPrefixes?.some((prefix) => pathname.startsWith(prefix)) matches on a bare string prefix. A sibling route sharing the same string prefix (e.g. /baseball/dashboard/lift vs. /baseball/dashboard/lift-report) will incorrectly light up this item's activeMatch, same as flagged previously.

🐛 Proposed fix
     activeMatch: (pathname) =>
       pathname === href ||
       Boolean(
         tabs?.some(
-          (tab) => pathname === tab.href || tab.matchPrefixes?.some((prefix) => pathname.startsWith(prefix)),
+          (tab) =>
+            pathname === tab.href ||
+            tab.matchPrefixes?.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`)),
         ),
       ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/baseball/`(dashboard)/BaseballFairwayShell.tsx around lines 168 -
174, The activeMatch logic in BaseballFairwayShell is using a loose
pathname.startsWith(prefix) check for tab.matchPrefixes, which can incorrectly
mark sibling routes as active. Update the activeMatch callback to use the same
segment-boundary-aware matching approach as resolveActiveHub.ts so only true
route descendants match, and keep the href equality check plus tabs?.some(...)
behavior intact while changing the prefix comparison inside tabs matching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/admin/_components/admin-nav.ts`:
- Line 34: Admin shortcut matching is case-sensitive because `AdminShell` passes
raw `e.key` into the lookup while `admin-nav` stores shortcut keys as uppercase
in the nav config and match logic. Normalize the key consistently by uppercasing
the input in `AdminShell` before lookup or by normalizing both sides inside the
admin navigation shortcut matcher used by the nav config entries. Use the
existing `AdminShell` key handler and the admin nav shortcut fields (`key`
values like the Work log entry) as the place to apply the fix.

In `@src/app/admin/ben-leah/actions.ts`:
- Around line 80-112: The updateBenLeahIssueWorkflow mutation updates GitHub
labels but does not invalidate the cached Ben + Leah issues data, so the page
can show stale labels after success. After the setBenLeahIssueWorkflow write
succeeds, call revalidatePath for the admin Ben + Leah issues page from this
server action file, and add the next/cache import if needed. Keep the existing
validation and error handling intact, and ensure the cache refresh happens only
after the mutation completes successfully.

In `@src/app/admin/ben-leah/BenLeahIssueTable.tsx`:
- Line 1: Remove the unnecessary client boundary from BenLeahIssueTable so it
can render as a Server Component. The file-level 'use client' directive is the
issue; delete it from BenLeahIssueTable.tsx and keep IssueRow and
BenLeahIssueTable as plain render-only components since they do not use hooks,
browser APIs, or event handlers. Leave BenLeahIssueWorkflowSelect as the
existing client boundary.

In `@src/app/admin/errors/page.tsx`:
- Around line 166-171: The “Open 7-day view” link in the admin errors page is
using a dead ternary and always resolves to the same URL, so it drops all active
filters instead of preserving them. Update the Link in the errors page JSX to
reuse the existing filter-building logic used for `chipHref`/`clearParamHref`,
and construct a `wider7dHref` that keeps `filters.sport`, `severity`, `source`,
and `feature` while only overriding `window` to 168. Ensure the `Link` for “Open
7-day view” uses that new href rather than a hardcoded query string.

In `@src/app/baseball/`(dashboard)/layout.tsx:
- Around line 89-99: The dashboard layout is always passing authVerified as true
to the shell components, which can render the real shell for unauthorized
sessions. Update the shell selection in layout.tsx so both BaseballFairwayShell
and BaseballShellLayout receive authVerified from the actual authorized state,
using the authorized value in the layout condition and props. Make sure the
inner loading/unauthorized guard in BaseballShellLayout and BaseballFairwayShell
still blocks rendering until authorization is confirmed.

In `@src/hooks/use-baseball-auth.ts`:
- Around line 82-89: The `useBaseballAuth` flow is over-fetching the `users`
record by calling `supabase.from('users').select('*')` and then casting it to
`User`, which can pull unnecessary fields into `useAuthStore`. Update the query
to select only the columns actually needed by `User` and the downstream
`store.setUser`/`userRecord` usage, then keep the `maybeSingle()` handling and
`userRecord?.role` logic intact. Use the `useBaseballAuth` hook, `userResult`,
and `store.setUser` as the main anchors when narrowing the selected fields.

In `@src/hooks/use-baseball-nav-context.ts`:
- Around line 64-71: `hasWarmNavCache` is treating a legitimate resolved null
from `getBaseballNavContext` as a cache miss. Update the caching logic in
`use-baseball-nav-context` so “resolved” is tracked separately from
`cachedContext` being non-null, and let teamless users reuse the cached null
result within `NAV_CACHE_TTL_MS`. In the resolve-commit path where
`cachedContext`, `cacheResolvedAt`, and related state are updated, also mark a
dedicated resolved flag (for example alongside the existing cache user/timestamp
state) and have `hasWarmNavCache` check that flag instead of `cachedContext !==
null`.

In `@src/lib/admin/ben-leah-issues.ts`:
- Around line 92-133: The admin issues fetch path can hang because the fallback
GitHub search request in fetchRawIssues does not use the same timeout signal as
the primary fetch. Update the searchRes fetch call to reuse the existing abort
signal/timeout wiring already used for the main GitHub issues request, so both
requests are bounded consistently.

In `@src/lib/admin/data/errors.ts`:
- Around line 121-146: The 7-day fallback count queries in errors.ts only apply
the sport filter, so the empty-state hint can ignore the active filter set.
Update the wider-window logic around widerQuery and widerUntaggedQuery to
propagate the current severity, source, and feature filters as well, matching
the same filter criteria used by the main admin_events query. Keep the change
localized to the fallback count construction so the “unresolved incidents in the
last 7 days” copy in the admin errors page reflects the active filters.

In `@src/lib/admin/data/overview.ts`:
- Around line 140-142: The `sentryUnresolved` KPI in `overview.ts` is being
computed from the length of the paged `incidentFeed24h.sentry.data` array, which
only reflects the limited results returned by `fetchSentryIssues` and
`sentry-api` pagination. Update the `incidentFeed24h`/`sentryUnresolved` path to
use a dedicated unresolved total or count from the Sentry API instead of
`data?.length`, so the admin overview reports the full org-wide unresolved
number. Locate the fix in `overview.ts` where `sentryUnresolved` is assigned,
and in the `incident-feed`/`sentry-api` flow that currently fetches paged issue
data.

In `@src/lib/admin/github-issues-workflow.ts`:
- Around line 60-88: The label update in setBenLeahIssueWorkflow is PATCHing a
full label set from stale client-supplied currentLabels, which can overwrite
concurrent label changes. Change the server action to fetch the issue’s latest
labels immediately before calling applyWorkflowSelection and build the PATCH
from that fresh state instead of the browser snapshot. Then update
updateBenLeahIssueWorkflow and the BenLeahIssueWorkflowSelect call site to stop
passing currentLabels now that the action reads labels server-side.
- Around line 20-58: `ensureBenLeahGitHubLabels` is doing uncached label
bootstrapping on every call, and `createLabelIfMissing` uses an unbounded
`fetch`, so a slow GitHub API can block hot paths like `fetchBenLeahIssueBoard`,
`createGitHubFeedbackIssue`, and `setBenLeahIssueWorkflow`. Add a timeout to the
`createLabelIfMissing` request, and memoize successful completion of
`ensureBenLeahGitHubLabels` at module scope so repeated invocations in the same
warm instance skip the label-creation sequence when it has already succeeded.

In `@src/lib/admin/github-pr-timeline.ts`:
- Around line 103-129: The GitHub API requests in the pull request timeline
fetch path have no timeout, so a stalled response can block the admin render
indefinitely. Update the fetch logic in github-pr-timeline’s request flow to use
an AbortController with a short timeout for both the search and fallback list
requests, and ensure the timeout error is handled by the existing failure path
so the admin UI can fall back cleanly instead of hanging.
- Around line 92-101: The GitHub search query in github-pr-timeline uses literal
plus signs in authorQuery, which URLSearchParams encodes as %2B and prevents
GitHub from treating the qualifiers as separate terms. Update the query
construction in the timeline search logic so author filters are joined with
spaces instead of pluses, keeping the q value in the expected repo:... is:pr
author:... format and preserving the existing author filtering behavior in the
search API.

In `@src/lib/admin/observe-action-result.ts`:
- Around line 74-105: The issue is that observeActionSoftFailure can throw
synchronously and accidentally flip a successful action into a failure. Wrap the
body of observeActionSoftFailure in its own try/catch so any errors from
extractActionSoftFailure, shouldEmit, drainCollapsedCount,
severityForSoftFailure, or logServerError cannot escape. Keep the guard local to
observeActionSoftFailure in src/lib/admin/observe-action-result.ts and
swallow/log internal observability errors without affecting the calling action
paths in with-lifting-action, with-baseball-action, or observed-action.

In `@src/lib/admin/observed-action.ts`:
- Around line 78-100: The happy path in withAdminObserved is doing an
unnecessary auth lookup because resolveObservedUser() is awaited before
observeActionSoftFailure can determine whether the result is a soft failure.
Move the user enrichment behind a soft-failure check in the observed-action flow
so createClient()/supabase.auth.getUser() only run when
extractActionSoftFailure(result) indicates it is needed; keep the existing
context extraction and observeActionSoftFailure call in observed-action.ts, but
avoid resolving the user for normal successful results.

---

Duplicate comments:
In `@src/app/baseball/`(dashboard)/BaseballFairwayShell.tsx:
- Around line 168-174: The activeMatch logic in BaseballFairwayShell is using a
loose pathname.startsWith(prefix) check for tab.matchPrefixes, which can
incorrectly mark sibling routes as active. Update the activeMatch callback to
use the same segment-boundary-aware matching approach as resolveActiveHub.ts so
only true route descendants match, and keep the href equality check plus
tabs?.some(...) behavior intact while changing the prefix comparison inside tabs
matching.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 372f52ba-6dd1-402d-bbec-d3d1bcd6a965

📥 Commits

Reviewing files that changed from the base of the PR and between b133e8a and c845f06.

📒 Files selected for processing (51)
  • .env.example
  • src/app/admin/_components/AdminShell.tsx
  • src/app/admin/_components/__tests__/admin-nav.test.ts
  • src/app/admin/_components/admin-nav.ts
  • src/app/admin/ben-leah/BenLeahIssueBoard.tsx
  • src/app/admin/ben-leah/BenLeahIssueTable.tsx
  • src/app/admin/ben-leah/BenLeahIssueWorkflowSelect.tsx
  • src/app/admin/ben-leah/actions.ts
  • src/app/admin/ben-leah/page.tsx
  • src/app/admin/errors/page.tsx
  • src/app/admin/page.tsx
  • src/app/admin/work/WorkTimeline.tsx
  • src/app/admin/work/page.tsx
  • src/app/baseball/(dashboard)/BaseballFairwayShell.tsx
  • src/app/baseball/(dashboard)/dashboard/settings/page.tsx
  • src/app/baseball/(dashboard)/layout.tsx
  • src/app/baseball/actions/__tests__/complete-player-onboarding.test.ts
  • src/app/baseball/actions/onboarding.ts
  • src/app/golf/actions/__tests__/coverage-contract.observability.test.ts
  • src/components/auth/baseball-sign-in-form.tsx
  • src/components/baseball/BaseballDashboardBootstrap.tsx
  • src/components/baseball/BaseballShellLayout.tsx
  • src/components/providers/SessionActivityProvider.tsx
  • src/hooks/__tests__/use-baseball-auth.test.tsx
  • src/hooks/use-baseball-auth.ts
  • src/hooks/use-baseball-nav-context.ts
  • src/lib/__tests__/server-error-logger-bridge.test.ts
  • src/lib/admin/__tests__/ben-leah-issues.test.ts
  • src/lib/admin/__tests__/observe-action-result.test.ts
  • src/lib/admin/__tests__/pr-body-parser.test.ts
  • src/lib/admin/ben-leah-issue-tracker.ts
  • src/lib/admin/ben-leah-issues.ts
  • src/lib/admin/data/__tests__/incident-feed.test.ts
  • src/lib/admin/data/errors.ts
  • src/lib/admin/data/incident-feed.ts
  • src/lib/admin/data/overview.ts
  • src/lib/admin/data/triage.ts
  • src/lib/admin/github-feedback.ts
  • src/lib/admin/github-issues-config.ts
  • src/lib/admin/github-issues-workflow.ts
  • src/lib/admin/github-pr-timeline.ts
  • src/lib/admin/observe-action-result.ts
  • src/lib/admin/observed-action.ts
  • src/lib/admin/pr-body-parser.ts
  • src/lib/auth/session-activity.ts
  • src/lib/auth/session-idle-shared.ts
  • src/lib/baseball/__tests__/with-baseball-action-observability.test.ts
  • src/lib/baseball/with-baseball-action.ts
  • src/lib/lifting/with-lifting-action.ts
  • src/lib/server-error-logger.ts
  • src/test/lib/auth/session-idle-shared.test.ts

Comment thread src/app/admin/_components/admin-nav.ts
Comment thread src/app/admin/ben-leah/actions.ts
Comment thread src/app/admin/ben-leah/BenLeahIssueTable.tsx
Comment thread src/app/admin/errors/page.tsx
Comment thread src/app/baseball/(dashboard)/layout.tsx
Comment thread src/lib/admin/github-issues-workflow.ts
Comment thread src/lib/admin/github-pr-timeline.ts
Comment thread src/lib/admin/github-pr-timeline.ts
Comment thread src/lib/admin/observe-action-result.ts
Comment thread src/lib/admin/observed-action.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/lib/admin/observe-action-result.ts (1)

74-111: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Try/catch still doesn't cover the whole function body — partial fix of prior finding.

The previous review flagged that extractActionSoftFailure, shouldEmit, drainCollapsedCount, and severityForSoftFailure can throw synchronously and must be guarded, since this function runs inside the outer try blocks of with-lifting-action.ts, with-baseball-action.ts, and observed-action.ts. The new try { ... } catch at Lines 88-110 only wraps the logServerError call — extractActionSoftFailure(result) (Line 78) and shouldEmit/drainCollapsedCount (Lines 81-86) still execute outside any guard. Since logServerError is async, it was already implicitly safe via .catch(() => {}); the calls that actually needed protection are still exposed.

🩺 Proposed fix — move the try/catch to wrap the whole function body
 export function observeActionSoftFailure(
   result: unknown,
   context: ActionSoftFailureContext,
 ): void {
-  const failure = extractActionSoftFailure(result);
-  if (!failure) return;
-
-  const throttleKey = `soft:${context.action}:${failure.code ?? failure.message.slice(0, 120)}`;
-  if (!shouldEmit(throttleKey)) return;
-
-  const collapsedCount = drainCollapsedCount(throttleKey);
-  const expected = isExpectedSoftFailureMessage(failure.message);
-  const severity = severityForSoftFailure(failure.message);
-
   try {
+    const failure = extractActionSoftFailure(result);
+    if (!failure) return;
+
+    const throttleKey = `soft:${context.action}:${failure.code ?? failure.message.slice(0, 120)}`;
+    if (!shouldEmit(throttleKey)) return;
+
+    const collapsedCount = drainCollapsedCount(throttleKey);
+    const expected = isExpectedSoftFailureMessage(failure.message);
+    const severity = severityForSoftFailure(failure.message);
+
     void Promise.resolve(
       logServerError(
         failure.message,
         {
           ...context,
           title: `[${context.action}] ${failure.message}`.slice(0, 500),
           handled: true,
           skipSentry: expected,
           errorCode: failure.code ?? undefined,
           fingerprint: ['server_action_soft', context.feature ?? context.featureArea ?? 'unknown', context.action],
           metadata: {
             ...(context.metadata ?? {}),
             soft_failure: true,
             ...(collapsedCount > 0 ? { collapsed_count: collapsedCount } : {}),
           },
         },
         severity,
       ),
     ).catch(() => {});
   } catch {
     // Fire-and-forget: observability must never change action results.
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/admin/observe-action-result.ts` around lines 74 - 111, Wrap the
entire observeActionSoftFailure flow in a single try/catch instead of only
guarding the logServerError call. The synchronous calls that can
throw—extractActionSoftFailure, shouldEmit, drainCollapsedCount, and
severityForSoftFailure—must be inside the protected block so this helper remains
fire-and-forget when invoked from with-lifting-action, with-baseball-action, and
observed-action. Keep the logServerError promise handling as-is, but move the
surrounding guard to cover all logic in observeActionSoftFailure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/lib/admin/observe-action-result.ts`:
- Around line 74-111: Wrap the entire observeActionSoftFailure flow in a single
try/catch instead of only guarding the logServerError call. The synchronous
calls that can throw—extractActionSoftFailure, shouldEmit, drainCollapsedCount,
and severityForSoftFailure—must be inside the protected block so this helper
remains fire-and-forget when invoked from with-lifting-action,
with-baseball-action, and observed-action. Keep the logServerError promise
handling as-is, but move the surrounding guard to cover all logic in
observeActionSoftFailure.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0bfeeba3-8453-4796-99fb-adb4ad5f5029

📥 Commits

Reviewing files that changed from the base of the PR and between c845f06 and b66a598.

📒 Files selected for processing (3)
  • src/app/baseball/actions/__tests__/demo-access.test.ts
  • src/lib/admin/observe-action-result.ts
  • src/lib/baseball/__tests__/nav-manifest.test.ts

Exclude feature-registry metadata from stat-layer scan (table names only,
not a DB consumer). Use structured console.error objects to satisfy CodeQL
log-injection rules in server-error-logger.
@njrini99-code

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai resolve

- Move matchPrefixes onto BaseballNavEntry in nav-registry (roster, performance,
  dev-plans, camps); toHubTab copies verbatim
- Drop redundant SETTINGS_HOME_TAB matchPrefixes; add dev guard for management
  settings supplement keyed on program-settings
- Prefer navContext.role for resolvedRole; segment-boundary prefix matching;
  export shared RECRUITING_PROGRAM_TYPES from resolve-active-hub
- Settings hub: dedupe privacy/notification cards, add focus ring on consolidated tiles
- FairwayBottomNav: nullish-coalesce active state like FairwaySidebar

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/app/baseball/(dashboard)/dashboard/settings/page.tsx (1)

31-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Share the coach settings route map

src/app/baseball/(dashboard)/dashboard/settings/page.tsx:31-92 hardcodes the same coach-settings routes/icons that are already declared in src/app/baseball/(dashboard)/_components/hub-definitions.ts:28-83 (season, philosophy, roles, permissions, teams, imports, integrations, audit). Extract the shared route/icon/capability map and let this page render its own labels/descriptions from that source so route or permission changes don’t drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/baseball/`(dashboard)/dashboard/settings/page.tsx around lines 31 -
92, The coach settings page is duplicating the same route/icon/capability
definitions already kept in hub-definitions, which can drift over time. Refactor
page.tsx to consume the shared settings map from hub-definitions and derive the
page’s labels/descriptions from that source, using the existing symbols like
COACH_SETTINGS_LINKS and the hub definition entries for season, philosophy,
roles, permissions, teams, imports, integrations, and audit.
src/app/baseball/(dashboard)/_components/resolve-active-hub.ts (1)

200-210: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Gate the player recruiting hub on activation

  • src/app/baseball/(dashboard)/_components/resolve-active-hub.ts:94-120,200-210 always includes playerHubs() and returns PLAYER_RECRUITING_TABS unchanged for players, so the recruiting strip still resolves on player routes.
  • The only activation gate is src/hooks/use-route-protection.ts:31-50, and it is only wired in src/app/baseball/(dashboard)/dashboard/college-interest/CollegeInterestClient.tsx:190-193; src/app/baseball/(dashboard)/dashboard/journey/page.tsx:187-225 and src/app/baseball/(dashboard)/dashboard/colleges/page.tsx:23-124 do not apply it.
  • Move the opt-in / college-player check into playerHubs() or filter PLAYER_RECRUITING_TABS before returning from resolveActiveHub().
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/baseball/`(dashboard)/_components/resolve-active-hub.ts around lines
200 - 210, The player recruiting hub is still being resolved for player routes
because resolveActiveHub() always includes playerHubs() and returns
PLAYER_RECRUITING_TABS without checking activation. Update playerHubs() or the
resolveActiveHub() flow so the opt-in/college-player gate is applied before
PLAYER_RECRUITING_TABS can be selected, and make sure the filtered tabs are
excluded for non-activated players while preserving the existing coach tab
filtering logic.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/server-error-logger.ts`:
- Line 330: The persist-failure log in ServerErrorLogger is leaking PII because
it prints the full enriched context. Update the failure handling around the
failed trace persistence in ServerErrorLogger to log only a minimal redacted
shape instead of the full enriched object. Use the existing normalizeContext and
enriched context flow as the place to trim or omit userId and userEmail before
the console.error call.

---

Outside diff comments:
In `@src/app/baseball/`(dashboard)/_components/resolve-active-hub.ts:
- Around line 200-210: The player recruiting hub is still being resolved for
player routes because resolveActiveHub() always includes playerHubs() and
returns PLAYER_RECRUITING_TABS without checking activation. Update playerHubs()
or the resolveActiveHub() flow so the opt-in/college-player gate is applied
before PLAYER_RECRUITING_TABS can be selected, and make sure the filtered tabs
are excluded for non-activated players while preserving the existing coach tab
filtering logic.

In `@src/app/baseball/`(dashboard)/dashboard/settings/page.tsx:
- Around line 31-92: The coach settings page is duplicating the same
route/icon/capability definitions already kept in hub-definitions, which can
drift over time. Refactor page.tsx to consume the shared settings map from
hub-definitions and derive the page’s labels/descriptions from that source,
using the existing symbols like COACH_SETTINGS_LINKS and the hub definition
entries for season, philosophy, roles, permissions, teams, imports,
integrations, and audit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 50304d20-41cd-4f4e-a307-95bae9845674

📥 Commits

Reviewing files that changed from the base of the PR and between b66a598 and 57e0de1.

📒 Files selected for processing (11)
  • src/app/baseball/(dashboard)/BaseballFairwayShell.tsx
  • src/app/baseball/(dashboard)/_components/hub-definitions.ts
  • src/app/baseball/(dashboard)/_components/hub-sub-nav.tsx
  • src/app/baseball/(dashboard)/_components/resolve-active-hub.ts
  • src/app/baseball/(dashboard)/dashboard/settings/page.tsx
  • src/components/fairway/app-shell/FairwayBottomNav.tsx
  • src/components/layout/sidebar.tsx
  • src/lib/baseball/__tests__/resolve-active-hub.test.ts
  • src/lib/baseball/nav-registry.ts
  • src/lib/baseball/stat-layer-manifest.ts
  • src/lib/server-error-logger.ts

Comment thread src/lib/server-error-logger.ts Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 4, 2026
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

The PR description images show two dark-themed pill-shaped buttons: the first reads "Open in Web" with an arrow icon pointing up/right, and the second reads "Open in Cursor" with the Cursor logo icon. Both are standard "open in editor" link controls unrelated to the code review itself.

@njrini99-code Got it — kicking off a full review and resolving existing CodeRabbit comments on this PR.

✅ Action performed

Comments resolved and changes approved.


Full review finished.

@linear-code linear-code Bot marked this pull request as ready for review July 4, 2026 20:40
@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown

Too many files changed for review. (92 files found, 50 file limit)

Bypass the limit by tagging @greptile-apps to review.

Use static Sentry capture titles and synthetic Error shells so user/error
copy flows through scope context (trace_message) instead of format strings.
Renames console payload keys to traceMessage for log-injection hygiene.
@cursor

cursor Bot commented Jul 4, 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.

@njrini99-code njrini99-code merged commit b544c0f into main Jul 4, 2026
35 of 37 checks passed
@njrini99-code njrini99-code deleted the cursor/baseball-fairway-routing-6886 branch July 4, 2026 20:45
@sentry

sentry Bot commented Jul 10, 2026

Copy link
Copy Markdown

Issues attributed to commits in this pull request

This pull request was merged and Sentry observed the following issues:

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.

2 participants