Session B (night2): streaks/hot-list engine — producer + form heat + THE LENS

RESURRECT verdict: the Session-23 engine existed, was pure, tested, and
mounted — it starved because every producer was external and unarmed
(tank01-prefetch via n8n, offline Python flow). The snapshot pipeline is
now the producer: each run merges slate players' real game logs (already
fetched for archetypes — zero extra calls) into rosterlogs:{sport}.

- computeFormHeat: hot hitters (7d AVG), hot sluggers (SLG), hot shooters
  (FG%) — correct sum/sum rate math, season baseline else prior stretch,
  min-sample refusals, never extrapolated.
- streakLens: no raw streak renders alone — built-vs opponents, tonight's
  matchup + opposing SP w/ ERA, step-up/step-down difficulty, one-line
  read. Absent context = say less, never invent.
- /api/streaks/:sport: heat merged into the feed, lens applied from cached
  schedule + pitchers (time-bounded, can never hang the route), snapshot
  grade letters joined.
- ACCEPTANCE (live statsapi, real 2026 logs): 32 rows found — Turang
  12-gm on-base, Reynolds 8-gm on-base, Pratt 7-gm on-base + 3-gm
  multi-hit, Meidroth 5-gm on-base, Cortes 5-gm on-base.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-11 00:39:18 -04:00
parent 4ddfb84232
commit 2c9cbca7bd
6 changed files with 486 additions and 13 deletions
+9
View File
@@ -130,6 +130,15 @@ async function resolvePlayerStats(name, sport, opts = {}) {
season: mlbSeasonRows(res.season, res.group),
last10: mlbLast10Rows(res.last10, res.group),
splits: [],
// Session 60 (night2/B) — the RAW flattened game log, most-recent
// first, for the streaks/hot-list roster blob. Free: the adapter
// already fetched it for this resolve; nothing extra is called.
rawLog: (res.last10 || [])
.map((r) => ({ date: r.date || null, opponent: r.opponent || null, isHome: r.isHome ?? null, ...(r.stat || {}) }))
.reverse(),
seasonRaw: res.season || null,
group: res.group || null,
playerId: res.id ?? null,
};
}
if (sp === 'nba' || sp === 'wnba') {