Session 59: Addendum + work-order 1.6 + Phase 2 + Phase 3 (2352 tests)
Overnight sprint for the Saturday 10 AM ET deploy gate — day one of the
public ledger record locks against freshly posted lines.
Task A — ledger team/opponent (migration 020, applied at 0 rows):
populated in both write paths from the real feed; opponent only when the
player's team matches a game participant (never guessed). Roadmap: Phase
4.5 WNBA ESPN-boxscore settlement (due ~Jul 24) + Phase 5 per-tier
calibration logged.
Task B — work-order 1.6 CLOSED (canonical player keys):
- searchPlayer resolves via nameKey; the old matcher deleted accents
("Sanchez" with acute -> "snchez") and substring-guessed onto the WRONG
player (the mismatched last-10 bug). Ambiguous -> null, never guess.
- Slate JOIN INVARIANT: a graded prop whose player's real team isn't in
the game is dropped (TB player can't render under MIL@PIT) — locked by
tests that fail the suite on regression.
- grades:{sport} TTL 2h -> 6h (expired between 5h cron gaps — the real
cause of /team "No active props" for slate players).
Task C — Phase 2 slate UX: tabs are THE filter (URL ?sport=, deep-linkable,
duplicate legacy tablist removed); cards cap at 6 graded props sorted
A+->F with ALL N READS in-place expander; waiting states show the real
next pipeline run ("Grades post ~6:00 PM ET").
Task D — Phase 3 mobile P0: root cause of vanished 390px nav was HIDE_ON
including '/' (landing had zero navigation) — fixed; html/body overflow-x
contained; GAME LINES collapses to best-line summary + "N BOOKS" expander
below 640px; venue drops before time/pitchers ever truncate.
Live verification: raw ESPN today STILL returns the Jun 13 NYK@SA Finals
game without a date pin; the pinned fetch returns 0 games, 0 off-date.
Backend 2327 -> 2352 tests (202 suites), web build exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+48
-4
@@ -4,10 +4,54 @@
|
||||
2026-07-10
|
||||
|
||||
## Current Phase
|
||||
SHIP BUILD v58.0 — Phase 1 "Truth Infrastructure": ledger_entries live in
|
||||
Supabase (migration applied + RLS verified), both write paths wired, nightly
|
||||
settlement + CLV, /ledger MY READS | MODEL tabs, honest scan refusals.
|
||||
Next: work-order Phase 2 (slate UX) + Phase 3 (mobile), then Phase 2.5.
|
||||
SHIP BUILD v59.0 — Overnight session: ledger team/opponent addendum,
|
||||
work-order 1.6 closed (canonical player keys + slate join invariant),
|
||||
Phase 2 slate UX, Phase 3 mobile P0. DEPLOY GATE: Coolify by Sat 10 AM ET;
|
||||
first snapshot locks against freshly posted lines (manual internal trigger).
|
||||
|
||||
## Session 59 (2026-07-10 overnight) — SHIPPED ✅ ADDENDUM + 1.6 + PHASE 2 + PHASE 3
|
||||
|
||||
Backend 2327 → **2352 tests** (+25), 202 suites. Web build clean (exit 0).
|
||||
Migration 020 (team/opponent) APPLIED while ledger_entries was at 0 rows —
|
||||
zero backfill needed; VYNDR-on-team unblocked.
|
||||
|
||||
- **Task A** — `ledger_entries.team/opponent` populated in both write paths
|
||||
(pipeline: stats-resolve team + prop's other side via nickname match,
|
||||
NEVER guessed; scan: snapshot-grade team, opponent null). Roadmap: Phase
|
||||
4.5 (WNBA ESPN box-score settlement — DUE ~Jul 24) + Phase 5 calibration-
|
||||
by-grade-tier logged.
|
||||
- **Task B (work-order 1.6 CLOSED)** — `mlbStatsAdapter.searchPlayer` now
|
||||
resolves via canonical `nameKey` (the old matcher DELETED accents:
|
||||
"Sánchez"→"snchez"≠"sanchez", then substring-guessed → wrong player's
|
||||
last-10). Fallback = UNIQUE last-name+first-initial or null.
|
||||
`buildPlayerStripsFromProps` gained the JOIN INVARIANT: a graded prop
|
||||
whose player's real team isn't a game participant is DROPPED (TB player
|
||||
can't render under MIL@PIT — suite fails if it regresses). Snapshot
|
||||
grades now carry `team`. Root cause of /team "No active props":
|
||||
grades:{sport} TTL (2h) < cron gap (5h) → now SNAP_TTL (6h).
|
||||
- **Task C (Phase 2)** — 2.1 sport tabs are THE filter, URL-driven
|
||||
(?sport=, deep-linkable); the dashboard's duplicate legacy tablist is
|
||||
GONE (legacy sections subscribe via onTabChange). 2.2 cards cap at 6
|
||||
graded props sorted A+→F with "ALL N READS →" expanding in place.
|
||||
2.3 waiting states show the REAL next pipeline run ("Grades post
|
||||
~6:00 PM ET" via lib/pipelineSchedule — mirrors SNAPSHOT_HOURS_UTC;
|
||||
update BOTH if the cron changes). 2.4 = TTL fix + join fix (verify on
|
||||
the live Yankees page post-deploy).
|
||||
- **Task D (Phase 3)** — ROOT CAUSE of vanished mobile nav: HIDE_ON
|
||||
included '/' — the landing had NO nav at 390px (desktop links hidden,
|
||||
hamburger retired S37, tab bar suppressed). '/' removed. 3.2: html/body
|
||||
overflow-x hidden <768; GAME LINES collapses to a best-line summary +
|
||||
"N BOOKS ⌄" expander <640; venue (.gc-venue) drops first on phones.
|
||||
- **Live verification:** raw ESPN (no date pin) STILL returns the Jun 13
|
||||
NYK@SA Finals game today; the pinned fetch returns 0 games, 0 off-date.
|
||||
|
||||
### Morning deploy runbook (Sat, before ~10 AM ET)
|
||||
1. Push already sent to gitea (Coolify betonblk) — confirm deploy finished.
|
||||
2. `GET /api/internal/snapshot/status` (x-internal-key) → cron_armed true.
|
||||
3. When the day's lines post: `POST /api/internal/snapshot/all`
|
||||
(x-internal-key) → first public ledger rows lock against fresh lines.
|
||||
4. Verify: `SELECT count(*), count(*) FILTER (WHERE team IS NOT NULL) FROM
|
||||
ledger_entries WHERE user_id IS NULL;` + one sample row.
|
||||
|
||||
## Session 58 (2026-07-10) — SHIPPED ✅ PHASE 1: TRUTH INFRASTRUCTURE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user