fix(baseball): render CoachHelm insight body on player profile (#474)#644
Conversation
The CoachHelm engine persists insight detail copy in the `body` column (engine-run.ts `buildInsightRow` sets `body: c.body`), but the player profile and command-center peek UIs read only `insight.description`, which is never populated on engine-generated rows. Titles rendered while detail/recommended-action copy was blank, making insights look broken. - Add optional `body?: string | null` to `BaseballCoachInsight` so the UI can read the engine-persisted column (page selects `*` → body present). - PlayerInsightsPanel: read `insight.body ?? insight.description` for both the collapsed preview and the expanded detail paragraph. - TeamPlayerPeekPanel: read `insight.body ?? insight.description`, matching the daily brief (`item.body`). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017VUauUXsm9aXegShmpJi5n
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR Summary by QodoFix CoachHelm insight detail rendering by falling back to body text
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
93 rules 1. Insight type not type-safe
|
| title: string; | ||
| description: string; | ||
| body?: string | null; // Engine-persisted insight text (baseball_coach_insights.body); UI reads body ?? description |
There was a problem hiding this comment.
1. Insight type not type-safe 🐞 Bug ⚙ Maintainability
BaseballCoachInsight still requires description: string even though persisted baseball_coach_insights rows (including engine-generated rows) use body and do not include a description column, so TypeScript will continue to allow insight.description reads without null/undefined handling. This undercuts the PR’s “type-safe” goal and makes it easy for future UI code to regress back to rendering blank insight detail.
Agent Prompt
## Issue description
`BaseballCoachInsight` currently models `description` as a required string, but persisted CoachHelm insights are stored in `baseball_coach_insights.body` (and the generated DB types/schema reflect `body` with no `description`). This means UI code can compile while still incorrectly assuming `description` exists.
## Issue Context
This PR updates UI code to render `body ?? description`, implicitly acknowledging that `description` may be absent on engine rows.
## Fix Focus Areas
- src/lib/types/index.ts[255-279]
## Suggested fix
- Update `BaseballCoachInsight` so `description` is `optional` and `nullable` (e.g. `description?: string | null`) to match the reality that many rows will not have it.
- Keep `body?: string | null` (or make it non-optional if you want the interface to represent a full DB row), and consider adding a small comment/docstring clarifying that `body` is the persisted detail field and `description` is legacy/compat.
- Re-run TypeScript checks and update any callers that relied on `description` being required.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
🤖 Mission Control — PR summary Changes: Player profile + command-center peek now read |
CI Feedback 🧐A test triggered by this PR failed. Here is an AI-generated analysis of the failure:
|
What & Why
The CoachHelm engine persists per-player insight detail copy in the
bodycolumn ofbaseball_coach_insights(engine-run.tsbuildInsightRowsetsbody: c.body). The player profile and command-center peek panels, however, read onlyinsight.description, which is not populated on engine-generated rows. Result: insight titles rendered but the detail/recommended-action copy was blank, making CoachHelm signals look broken or low-confidence on the two primary places coaches review per-player insights.Changes
src/lib/types/index.ts— add optionalbody?: string | nulltoBaseballCoachInsight(the player page selects*, so the column is present at runtime; this makes the read type-safe).src/components/baseball/player-profile/PlayerInsightsPanel.tsx— computeconst detail = insight.body ?? insight.descriptionand use it for both the collapsed one-line preview and the expanded detail paragraph.src/components/baseball/command-center/TeamPlayerPeekPanel.tsx— renderinsight.body ?? insight.description.Read-model normalization on a single field (
body ?? description) keeps legacy/manually-authored rows (which usedescription) working while surfacing engine rows.Acceptance criteria
insight.body ?? insight.description.item.body).Scope
Minimal, display-only. No server-action, auth, migration, or table changes.
🤖 Generated with Claude Code