Session 28: Parlay builder, line movement tracker, book comparison — 3 features, zero credits (1623 tests)

This commit is contained in:
Kev
2026-06-13 12:37:08 -04:00
parent 66fafd8429
commit c48aecd510
23 changed files with 1567 additions and 1 deletions
+65
View File
@@ -4,6 +4,71 @@
2026-06-12
## Current Phase
SHIP BUILD v28.0 — Parlay builder, line-movement tracking, book comparison (Session 28)
## Session 28 (2026-06-13) — SHIPPED
The three features every competitor has: parlay building, line movement,
book comparison. All zero-credit (pure math / Redis snapshots / cached
odds). Reused existing primitives heavily (payoutCalculator, the existing
ParlayTray/ParlayContext frontend).
Backend 1584 → **1623 tests** (+39), 130 suites, zero regressions. Web
build clean.
### PHASE 1-2 — Parlay builder
- `parlayService.js` — combined American/decimal odds (reuses
payoutCalculator), confidence-weighted combined grade, correlation
detection via an interaction matrix (same-game teammates = positive,
opposing rebounds = negative, cross-game = independent), kill-condition
aggregation, and `suggestParlays` (greedy, conflict-avoiding).
- `POST /api/parlay/calculate` + `/suggestions`. Frontend parlay builder
already existed (ParlayTray + ParlayContext → /api/scan/parlay grading);
left intact. Added the calculate proxy for the lightweight path.
- 15 unit + 3 route tests.
### PHASE 3-4 — Line movement
- `lineSnapshotService.js` — Redis-only rolling history
(`linehistory:{sport}:{gameId}:{player}:{stat}`, cap 100, 48h TTL),
`classifyMovement` (stable/rising/dropping + sharp signal ≥1.5 pts),
`getBiggestMovers` (scan + classify + sort by |delta|). Complements the
existing Supabase-backed lineMovementService rather than replacing it.
- Wired `recordSnapshots` into oddsService's existing best-effort block.
- `GET /api/lines/:sport/movers` + per-prop history.
- Frontend: `LineMovementChart` (dependency-free SVG sparkline) +
`MoversPanel` (mounted in the Slate, self-hiding, tier-gated).
- 9 unit + 2 route tests.
### PHASE 5-6 — Book comparison
- `bookComparisonService.js` — best line per side (highest decimal
payout), savings vs field average per $100, over the grouped odds
`lines[]`. `GET /api/books/:sport` (best lines) + per-prop grid, reading
CACHED odds props (zero credits).
- Frontend: `BookComparison` (book grid, BEST badge) + `BestLinesPanel`
(mounted in the Slate, self-hiding, tier-gated).
- 7 unit + 3 route tests.
### PHASE 7 — Wiring
- Mounted /api/parlay, /api/lines, /api/books in app.js.
- Next proxies: `parlay/calculate/route.ts` (explicit, avoids catch-all
conflict with existing grade/add-leg), `lines/[...path]`, `books/[...path]`.
- MoversPanel + BestLinesPanel added to the Slate below streaks/hot lists.
### Files created
- `src/services/parlayService.js`, `src/routes/parlay.js`
- `src/services/lineSnapshotService.js`, `src/routes/lineMovement.js`
- `src/services/bookComparisonService.js`, `src/routes/bookComparison.js`
- `web/src/components/{LineMovementChart,MoversPanel,BestLinesPanel,BookComparison}.tsx`
- `web/src/app/api/parlay/calculate/route.ts`, `api/lines/[...path]/route.ts`, `api/books/[...path]/route.ts`
- 4 new test files (parlayService, lineSnapshotService, bookComparisonService, session28Routes)
### Files modified
- `src/app.js` (3 mounts), `src/services/oddsService.js` (snapshot recording)
- `web/src/components/Slate.tsx` (2 panels)
---
## Previous Phase
SHIP BUILD v27.0 — PWA autopilot: deployment-aware service worker, push foundation, offline fallback, install + cookie + tier polish (Session 27)
## Session 27 (2026-06-13) — SHIPPED