Session 28: Parlay builder, line movement tracker, book comparison — 3 features, zero credits (1623 tests)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user