Session D (night2): Phase 2.5 — intraday refresh + directional movement
Odds-only refresh every 20 min during slate hours (noon–midnight ET), in-process (INTRADAY_REFRESH=0 kill switch; skips full-snapshot slots): - signed delta RELATIVE TO THE GRADED SIDE; direction is the signal. - WITH the grade → STEAM badge, never a re-grade. - AGAINST >=1.0 → re-grade THAT PROP ONLY at the real current line: holds/refuses → VALUE (better entry, same read); drops → PUBLIC revision (grade updates, revised_from_grade preserves the ORIGINAL forever, UI strikethrough on slate strips + ledger cards). - Every run recaptures closing_line/odds → the close is now refresh- fidelity; SYNC goes live by dropping SNAPSHOT_EXPECTED_INTERVAL to 1200. - Ticker MOVE events feed from the refresh (>=1.0 moves). - QUOTA MATH: 36 runs/day/sport x 4 sports <= 144 PropLine calls/day vs 9,000/day free capacity (3 keys x 3,000). Re-grades are internal compute. - POST /api/internal/refresh/all for manual runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -318,6 +318,28 @@ async function settleLedger(sport, opts = {}) {
|
||||
return { settled, pending };
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase 2.5 (Session 60) — a PUBLIC grade revision. The intraday refresh
|
||||
* re-graded a prop whose line moved ≥1.0 against the graded side and the
|
||||
* grade dropped: update the locked row's grade and set revised_from_grade
|
||||
* ONCE (the original letter is preserved forever — revisions are public,
|
||||
* never silent). Only unsettled public rows for today are touched.
|
||||
*/
|
||||
async function applyRevision(sport, { playerKey, stat, line, side, newGrade, fromGrade }, opts = {}) {
|
||||
if (!opts.sb && !isConfigured()) return { skipped: 'supabase not configured' };
|
||||
const sb = opts.sb || defaultClient();
|
||||
const { error } = await sb.from('ledger_entries')
|
||||
.update({ grade: newGrade, revised_from_grade: fromGrade })
|
||||
.is('user_id', null)
|
||||
.eq('sport', String(sport).toLowerCase())
|
||||
.eq('player_key', playerKey)
|
||||
.eq('stat', stat)
|
||||
.eq('line', line)
|
||||
.eq('side', side)
|
||||
.is('outcome', null);
|
||||
return error ? { error: error.message } : { revised: true };
|
||||
}
|
||||
|
||||
async function settleAllLedgers(opts = {}) {
|
||||
const sports = opts.sports || ['mlb', 'nba', 'wnba', 'soccer'];
|
||||
const results = [];
|
||||
@@ -400,6 +422,7 @@ module.exports = {
|
||||
captureClosing,
|
||||
settleLedger,
|
||||
settleAllLedgers,
|
||||
applyRevision,
|
||||
getModelAggregate,
|
||||
MIN_AGG_SAMPLE,
|
||||
__internals: {
|
||||
|
||||
Reference in New Issue
Block a user