Session 46: Grade card intel + name normalization + pitchers (2122 tests)
Three focused P1 fixes on the Session-45 snapshot model.
- Grade card intel ROOT CAUSE: gameLogService is NBA/WNBA-only (offline Python),
so MLB props never got l5_avg/l20_avg and buildIntelFields returned {}. Wired
MLB game logs into featureCache.gameLogFeatures via mlbStatsAdapter.getPlayerStats
(pure mlbGameLogFeatures + MLB stat_type->field map). buildIntelFields gained
playerStats/projection fallbacks for partial intel.
- Player name normalization: src/utils/playerName.js (+ web/src/lib copy):
normalizeName -> {display,key}. Strips periods, de-dots suffix, accent-folds
the key. Applied in snapshotService grouping, slateAdapter grade index +
player-strip merge (variants collapse, longest name shown), and
playerIntelService. "A.J. Ewing"/"AJ Ewing" + "Jazz Chisholm"/"Jr." now merge.
- MLB starting pitchers: new GET /api/schedule/:sport/pitchers (probablePitchers
service wrapping mlbStatsAdapter.getScheduleWithPitchers + best-effort ERA).
Slate fetches it, builds a team->pitcher map (full name + mascot match),
attaches pitchers to MLB GameCardData. + Next proxy.
Backend 2100 -> 2122 tests (+22), 176 suites. Web build clean (exit 0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -131,6 +131,33 @@ inline with `GradeBadge`. `onPlayerClick` → `/player/:name?sport=` (`lib/playe
|
||||
|
||||
---
|
||||
|
||||
## 5b. Player name normalization (Session 46)
|
||||
|
||||
`src/utils/playerName.js` (+ identical `web/src/lib/playerName.js`) is the ONE
|
||||
source of truth for comparing/deduping names. `normalizeName(raw)` →
|
||||
`{ display, key }`: `display` strips periods + de-dots the suffix (keeps accents
|
||||
+ casing); `key` is accent-folded, lowercased, suffix-stripped for comparison.
|
||||
Used by snapshot grouping, `slateAdapter` (grade index + player strips), and
|
||||
`playerIntelService` so "A.J. Ewing"/"AJ Ewing" and "Jazz Chisholm"/"Jazz
|
||||
Chisholm Jr." collapse to one player.
|
||||
|
||||
## 5c. MLB intel features (Session 46)
|
||||
|
||||
`buildIntelFields` (grade-card STAT CONTEXT + VYNDR INTELLIGENCE) reads
|
||||
`l5_avg`/`l10_avg`/`l20_avg`/`opp_rank_stat`/`rest_days` from the feature vector.
|
||||
MLB game logs are now wired into `featureCache.gameLogFeatures` via
|
||||
`mlbStatsAdapter.getPlayerStats` (the old Python game-log path was NBA/WNBA-only,
|
||||
so MLB props had no intel). `buildIntelFields(features, { playerStats, projection })`
|
||||
also accepts fallbacks so partial intel still renders.
|
||||
|
||||
## 5d. MLB probable pitchers (Session 46)
|
||||
|
||||
`GET /api/schedule/:sport/pitchers` (MLB only) → `{ sport, date, games:
|
||||
[{ home:{team,pitcher,era}, away:{...} }] }` from `probablePitchers` /
|
||||
`mlbStatsAdapter.getScheduleWithPitchers` (the ESPN schedule lacks them). The
|
||||
Slate builds a team→pitcher map (`slateAdapter.buildPitcherMap` /
|
||||
`pitchersForGameTeams`) and attaches `pitchers` to MLB GameCardData.
|
||||
|
||||
## 6. Freshness & caching
|
||||
|
||||
- Schedule cache TTL ≤ 30 min (`scheduleService`). Frontend filters completed
|
||||
|
||||
Reference in New Issue
Block a user