Session 23: All-day intelligence layer — schedule, game lines, streaks, hot lists, stat filtering, ParlayAPI dead (1567 tests)
This commit is contained in:
@@ -4,6 +4,97 @@
|
||||
2026-06-12
|
||||
|
||||
## Current Phase
|
||||
SHIP BUILD v23.0 — All-Day Intelligence Layer: schedule, game lines, streaks, hot lists, stat filtering (Session 23)
|
||||
|
||||
## Session 23 (2026-06-12) — SHIPPED
|
||||
|
||||
Built the all-day content layer that makes VYNDR an intelligence
|
||||
terminal, not a prop-grading widget. EVERYTHING coexists: schedule,
|
||||
stats, streaks, hot lists, and game lines all visible at once —
|
||||
nothing replaces anything. When odds-api props are empty, the other
|
||||
(free/cheap) layers keep the platform alive. NO odds-api credits were
|
||||
spent this session.
|
||||
|
||||
Baseline 1505 → **1567 tests** (+62), 124 suites, zero regressions.
|
||||
Web build clean.
|
||||
|
||||
### PHASE 1 — Schedule API (`/api/schedule/:sport`)
|
||||
- `src/services/scheduleService.js` — cache-aside read of free ESPN
|
||||
scoreboards. Reads `schedule:{sport}:{date}` first; on a miss it
|
||||
self-heals by fetching ESPN directly (the same free endpoint the
|
||||
pollers hit), normalizes, caches 60s. The platform is NEVER empty.
|
||||
- Per-game `hasOdds` / `hasGameLines` flags read OTHER caches
|
||||
(odds-api props, Tank01 lines) WITHOUT triggering a fetch.
|
||||
- `src/routes/schedule.js` — returns an empty slate (never 5xx) on
|
||||
error. Unknown sport → 404. Mounted in `app.js`.
|
||||
|
||||
### PHASE 2 — Tank01 Game Lines (`/api/gamelines/:sport`)
|
||||
- Added `getMLBBettingOdds` to `tank01MlbAdapter` (NBA already had
|
||||
`getNBABettingOdds`). 15-min cache TTL, shares RAPID_API_KEY quota.
|
||||
- `src/routes/gameLines.js` — normalizes the book-by-book body
|
||||
(bet365 / betmgm / caesars: ML, spread, total) into a flat shape,
|
||||
parses teams from the `YYYYMMDD_AWAY@HOME` gameID. Missing key →
|
||||
graceful `configured:false`. Adapter throw → empty, never 500.
|
||||
|
||||
### PHASE 3 — Streaks Engine (`/api/streaks/:sport`)
|
||||
- `src/services/streaksService.js` — pure, data-driven. Consecutive
|
||||
run from the latest game backward; collapses tiered specs (25+/20+
|
||||
pts) to the more impressive one. NBA (14 specs incl. dd/td/PRA/hot-
|
||||
shooter), MLB (9), NFL (5), soccer (4). Through VYNDR's lens —
|
||||
"4-game 28+ scoring streak", not "31 PPG".
|
||||
- `src/services/rosterLogs.js` — Redis-only roster loader (prefetch
|
||||
blob fast-path, else SCAN over `gamelogs:{sport}:*`). Never throws.
|
||||
|
||||
### PHASE 4 — Hot Lists (`/api/hotlist/:sport`)
|
||||
- `src/services/hotListService.js` — "hot" = ABOVE the player's own
|
||||
baseline (explicit seasonAvg, else games outside the window), not
|
||||
just high raw numbers. Ranked by delta, tie-broken by raw recent
|
||||
average. Date-based 7-day window when rows carry dates.
|
||||
|
||||
### PHASE 5 — Stat Filtering
|
||||
- `src/config/statFilters.js` (+ `web/src/config/statFilters.ts`
|
||||
mirror). `?stat=` param on streaks/hotlist. Discovery endpoint
|
||||
`GET /api/stats/filters/:sport`. `StatFilterPills` component.
|
||||
|
||||
### PHASE 6 — Unified Dashboard
|
||||
- `StreaksPanel` + `HotListPanel` (headshots, tier-gated, self-hide
|
||||
when empty), wired into the Slate below the games AND mounted as
|
||||
landing-page teasers. Stat pills narrow both; schedule + game lines
|
||||
stay visible regardless. Free tier sees 3, paid sees all.
|
||||
|
||||
### PHASE 7 — Cleanup
|
||||
- ParlayAPI marked `status: 'dead'` in `src/config/providers.js`
|
||||
(Chrome Claude: `api.parlayapi.io` unreachable on 2026-06-12).
|
||||
Excluded from `getFallbackChain` + `getConfiguredProviders`; new
|
||||
`isDeadProvider` helper. Config still resolves so adapter tests
|
||||
(network-mocked) pass unchanged.
|
||||
|
||||
### Files created
|
||||
- `src/services/scheduleService.js`, `src/routes/schedule.js`
|
||||
- `src/routes/gameLines.js`
|
||||
- `src/services/streaksService.js`, `src/routes/streaks.js`
|
||||
- `src/services/hotListService.js`, `src/routes/hotlist.js`
|
||||
- `src/services/rosterLogs.js`
|
||||
- `src/config/statFilters.js`
|
||||
- `web/src/config/statFilters.ts`
|
||||
- `web/src/components/StatFilterPills.tsx`
|
||||
- `web/src/components/StreaksPanel.tsx`
|
||||
- `web/src/components/HotListPanel.tsx`
|
||||
- 7 new test files (schedule, gamelines, streaks/hotlist routes,
|
||||
streaksService, hotListService, rosterLogs, statFilters,
|
||||
providersRegistry)
|
||||
|
||||
### Files modified
|
||||
- `src/app.js` (mounted 4 routes)
|
||||
- `src/services/adapters/tank01MlbAdapter.js` (getMLBBettingOdds)
|
||||
- `src/routes/stats.js` (filters discovery endpoint)
|
||||
- `src/config/providers.js` (ParlayAPI dead)
|
||||
- `web/src/app/page.tsx`, `web/src/components/Slate.tsx`
|
||||
- `tests/unit/tank01MlbAdapter.test.js`
|
||||
|
||||
---
|
||||
|
||||
## Previous Phase
|
||||
SHIP BUILD v22.0 — Tracker-driven quota guard, env-configurable cache TTL, opt-in odds prewarmer (Session 22)
|
||||
|
||||
## Session 22 (2026-06-12) — SHIPPED
|
||||
|
||||
Reference in New Issue
Block a user