Build /api/props/top-graded server selector: rank with p_win, serve without it
New READ endpoint. No grade, ledger row, lock_line, or scoring write. Push
scoring untouched.
REVIEW ZERO CORRECTED THE PREMISE: the handler NEVER EXISTED in any commit
(searched git rev-list --all for a /top-graded definition in src/ — zero hits).
Not "removed" — the three axios callers (cheatsheetGenerator, gradeOfTheDay,
widget) and the Next proxy were written against a phantom endpoint, so those
three content generators have silently received [] for their entire life.
Contract recovered from the four consumers, not guessed: {props:[...]},
?sport=UPPERCASE (absent = all sports, which gradeOfTheDay relies on) + ?limit,
rows carrying player/stat/line/direction/sport/grade/confidence? plus the
player_name/stat_type aliases and game_id.
POPULATED-PATH RISK FOUND: the board's populated branch had never run in prod,
and dashboard/page.tsx:463 calls g.stat.replace(/_/g,' ') UNGUARDED (g.player
also feeds the row key, /scan URL and heading; sport must be UPPERCASE for
SportPill). toRow requires non-empty string player+stat and a finite line,
uppercases sport, and DROPS unrenderable rows — a shorter board beats a broken
one.
THE LEAK BOUNDARY (why this is server-side): the browser cannot rank on p_win
for all tiers because stripModelPrice deliberately withholds it from unentitled
tiers. Order of operations is
read cache -> RANK with p_win (every tier) -> map rows incl. model fields
-> stripModelPrice(rows, tier) -> serialize
so a free caller receives the paid RANKING without the paid VALUES. Tier comes
from resolveTierFromRequest, which FAILS CLOSED to 'free'. Cache-Control is
private under a bearer token, public otherwise (the /api/snapshot precedent).
ONE SHARED DEFINITION, no drift: new src/utils/gradeRanking.js
(takeablePWin/descNullsLast/rankGrades). heroPropService now imports
takeablePWin instead of its inline copy (behaviour unchanged — it was that
logic verbatim); the selector imports rankGrades; web/src/lib/slateAdapter
keeps its mirror (the browser cannot import src/, S25) and a test cross-checks
the two on identical fixtures (playerName.js precedent). Board is grade-first
("top GRADES"), hero is p_win-first ("top read") — they differ BY DESIGN and
agree within the leading tier.
HONEST LIMIT: the Next proxy (cachedBackendJson) sends no Authorization header
and caches under a shared key, so via the dashboard every viewer gets the
free-tier payload — correct order, no paid values. That is the SAFE behaviour;
forwarding auth into a shared cache is exactly how a paid payload leaks to
anonymous viewers. Per-tier delivery through the proxy needs a tier-keyed cache
and is not done here.
Verified on real prod snapshot data (anonymous path): MLB 8 props, WNBA 10,
0 paid-field leaks, render-contract safe on every row, sport uppercase.
Floor: 311 suites / 3882 tests green (18 new — leak test uses POPULATED p_win,
not today's nulls: entitled gets p_win and it drove the order, unentitled gets
a byte-identical order with all five MODEL_FIELDS absent and no trace in
JSON.stringify, while book/fair market facts survive). Web build exit 0.
Dashboard visual is auth-gated -> tagged for the Chrome audit, not faked.
Held: edge_pct rescale/retirement (Order B); board columns/contract unchanged;
tier-keyed proxy caching.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
This commit is contained in:
@@ -359,3 +359,36 @@ OVER @0.5 → `0.5•(C) 1(C) 1.5(F)` (line-ASC PASS), UNDER @1.5 → `2.5(C) 2(
|
||||
(line-DESC PASS). Only the *rendered* Desk card remains unverified anonymously → tagged for the Chrome
|
||||
audit, no visual faked. **Held:** edge_pct rescale/display retirement, building
|
||||
the missing `/api/props/top-graded` selector, exposing p_win to unentitled tiers.
|
||||
|
||||
---
|
||||
|
||||
# /api/props/top-graded SERVER SELECTOR — 2026-07-29 (spec `specs/top-graded-selector.md`, shipped)
|
||||
|
||||
The dashboard TOP GRADES board had no feed. **The handler NEVER existed in any commit** (searched
|
||||
`git rev-list --all`) — so the three axios callers (cheatsheetGenerator, gradeOfTheDay, widget) plus
|
||||
the Next proxy had always received `[]`. Contract recovered from those consumers, not guessed.
|
||||
|
||||
**The leak boundary — the whole point of doing it server-side.** The browser cannot rank on `p_win`
|
||||
for all tiers because `stripModelPrice` deliberately withholds it from unentitled tiers ("shipping
|
||||
p_win is shipping the price in a different base", S67). Order of operations:
|
||||
`read cache → RANK with p_win (every tier) → map rows incl. model fields → stripModelPrice(rows, tier)
|
||||
→ serialize`. A free caller gets the paid RANKING without the paid VALUES. Tier resolution FAILS
|
||||
CLOSED to `free`; `Cache-Control` is `private` under a bearer token, `public` otherwise.
|
||||
|
||||
**Populated-path risk found and handled:** the board's populated branch had never run in prod, and
|
||||
`dashboard/page.tsx:463` calls `g.stat.replace(/_/g,' ')` **unguarded** — `toRow` requires string
|
||||
`player`+`stat`, a finite `line`, uppercases `sport` for `SportPill`, and drops unrenderable rows.
|
||||
|
||||
**One shared ranking definition:** new `src/utils/gradeRanking.js`; `heroPropService` now imports
|
||||
`takeablePWin` (was an inline copy, behaviour unchanged), the selector imports `rankGrades`, and the
|
||||
web mirror is cross-checked by test. Board is grade-first ("top GRADES"), hero is p_win-first ("top
|
||||
read") — they differ by design and agree within the leading tier.
|
||||
|
||||
**Honest limit:** the Next proxy forwards no Authorization and caches under a shared key, so via the
|
||||
dashboard every viewer receives the free-tier payload — correct order, no paid values. That is the safe
|
||||
default (forwarding auth into a shared cache is how paid payloads leak); per-tier delivery through the
|
||||
proxy needs a tier-keyed cache and is NOT done here.
|
||||
|
||||
**Verified:** 311 suites / 3882 tests green (18 new, leak test on POPULATED p_win), web build exit 0,
|
||||
and induced on real prod snapshot data — MLB 8 / WNBA 10 props, 0 paid-field leaks, render-contract
|
||||
safe. Dashboard visual is auth-gated → tagged for the Chrome audit, not faked.
|
||||
|
||||
Reference in New Issue
Block a user