Session 48: Name normalization at every layer + usage field (2156 tests)

Trace-first: the normalizer functions were correct (S47) but raw names still
flowed through paths that skipped them. Fixed each leaking path.

- 2a (source chokepoint): snapshotService.runSnapshot normalizes each grade's
  player to the de-dotted display AND dedupes to one grade per nameKey|stat
  (highest confidence) before writing grades:{sport} + snapshot:latest. Every
  consumer (GameCard, Explore, leaders, profile) now gets clean merged names.
- 2b: buildPlayerStripsFromProps dedupes a player's props by stat (graded >
  awaiting) → one row per stat (kills "Ks 5.5 AND Ks 3.5" variant dupes).
- 2c: scan tonightsPlayers grid groups by nameKey, displays normalized name.
- 3: profile VYNDR INTELLIGENCE "+0%"/"—" was buildIntel's defaults (separate
  from the grade card's buildIntelFields, which already works). resolvePlayerStats
  now attaches real usage (AB/G) + rest (B2B/Xd); buildIntel renders them; REST
  default is now "—".

Backend 2149 -> 2156 tests (+7), 181 suites. Web build clean (exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-06-19 02:42:13 -04:00
parent 78db55d499
commit 91b03c4044
10 changed files with 259 additions and 15 deletions
+32 -2
View File
@@ -4,8 +4,38 @@
2026-06-18
## Current Phase
SHIP BUILD v47.0 — Name normalization completed (nicknames/accents/parens),
full MLB VYNDR INTELLIGENCE (rest/usage), ticker SCAN dedup, BOMBER threshold.
SHIP BUILD v48.0 — Name normalization applied at EVERY layer (snapshot source,
game-card strips, scan grid) + profile usage/rest wired. The dup-player arc closed.
## Session 48 (2026-06-19) — SHIPPED ✅ NORMALIZATION AT EVERY LAYER
The normalizer functions were correct (S47) but raw names still flowed through
paths that skipped them. Traced top-down, fixed each. Backend 2149 → **2156
tests** (+7), 181 suites. Web build clean (exit 0).
### The trace (3 leaking paths)
1. **Snapshot grades** stored RAW player names + no dedup → Explore/leaders/
profile/GameCard-overlay all saw variants.
2. **Game-card strips** merged the player but pushed EVERY variant prop → "Ks 5.5
AND Ks 3.5" duplicate rows.
3. **Scan player grid** (`tonightsPlayers`) grouped by raw `p.player` → variant tiles.
### Fixes
- **2a (source chokepoint):** `snapshotService.runSnapshot` now normalizes each
grade's player to the de-dotted display AND dedupes to ONE grade per
normalized player+stat (highest confidence) BEFORE writing `grades:{sport}` +
`snapshot:{sport}:latest`. Every consumer now gets clean, merged names for free.
- **2b:** `buildPlayerStripsFromProps` dedupes a player's props by stat (prefers
the graded over an awaiting row) → one row per stat.
- **2c:** scan `tonightsPlayers` groups by `nameKey`, displays `normalizeName().display`.
- **3 (profile usage/rest):** the "+0%"/"—" was the PLAYER PROFILE's `buildIntel`
(separate from the grade card's `buildIntelFields`, which already works — the
full feature merge carries ab_per_game/rest_days, NOT filtered by FEATURE_NAMES
which is meta-only). `resolvePlayerStats` (MLB) now attaches real `usage`
(AB/G) + `rest` (B2B/Xd) and `buildIntel` renders them; REST default is now
"—" not "+0%".
## Session 47 (2026-06-19) — SHIPPED ✅ NAME NORM + INTEL + TICKER POLISH
## Session 47 (2026-06-19) — SHIPPED ✅ NAME NORM + INTEL + TICKER POLISH