// Session 60 (night2/D) — Phase 2.5 intraday refresh. Direction is the // signal: WITH the grade = STEAM (no re-grade); AGAINST ≥1.0 = re-grade // that prop only (holds → VALUE, drops → PUBLIC revision). All lines are // real feed values; the refresh recaptures the close. const { runIntradayRefresh, inSlateHours, __internals } = require('../../src/services/intradayRefreshService'); const { signedDelta, trackHistory, HISTORY_CAP } = __internals; const NOW = '2026-07-11T20:00:00.000Z'; function harness({ grades, oddsProps, analyzeResult }) { const store = new Map([[`snapshot:mlb:latest`, { sport: 'mlb', updated_at: NOW, grades, deltas: [] }]]); const calls = { analyze: [], revisions: [], closing: 0, ticker: [] }; const deps = { cacheGet: async (k) => store.get(k) ?? null, cacheSet: async (k, v) => { store.set(k, v); }, getOdds: async () => ({ props: oddsProps }), analyze: async (prop) => { calls.analyze.push(prop); return analyzeResult; }, ledger: { applyRevision: async (sport, rev) => { calls.revisions.push(rev); return { revised: true }; }, captureClosing: async () => { calls.closing += 1; return { updated: 0 }; }, }, pushTickerItems: async (events) => { calls.ticker.push(...events); }, now: () => NOW, }; return { deps, store, calls }; } const GRADE = { player: 'Aaron Judge', stat_type: 'home_runs', line: 0.5, direction: 'over', grade: 'A', confidence: 78, gradedAt: { line: 0.5, odds: -115, timestamp: NOW }, }; const prop = (line) => ({ player: 'Aaron Judge', stat_type: 'home_runs', line, book: 'draftkings' }); describe('signedDelta — relative to the graded side', () => { test('over: rising line = positive (market chasing the over)', () => { expect(signedDelta('over', 1.5, 2.5)).toBe(1); expect(signedDelta('over', 1.5, 1.0)).toBe(-0.5); }); test('under: falling line = positive', () => { expect(signedDelta('under', 1.5, 1.0)).toBe(0.5); expect(signedDelta('under', 1.5, 2.5)).toBe(-1); }); test('missing values → null, never a fabricated zero', () => { expect(signedDelta('over', null, 2)).toBeNull(); }); }); describe('runIntradayRefresh — directional handling', () => { test('moved WITH the grade → STEAM, NO re-grade', async () => { const { deps, store, calls } = harness({ grades: [GRADE], oddsProps: [prop(1.5)], analyzeResult: null }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ status: 'ok', steam: 1, value: 0, revised: 0 }); expect(calls.analyze).toHaveLength(0); // steam never re-grades const snap = store.get('snapshot:mlb:latest'); expect(snap.grades[0].movement).toMatchObject({ kind: 'steam', delta: 1, currentLine: 1.5 }); expect(calls.ticker.length).toBeGreaterThan(0); // ≥1.0 move → ticker MOVE expect(calls.ticker[0].text).toContain('o0.5 → o1.5'); }); test('moved AGAINST ≥1.0, re-grade HOLDS → VALUE (better entry)', async () => { const { deps, store, calls } = harness({ grades: [{ ...GRADE, gradedAt: { line: 2.5, odds: -110, timestamp: NOW }, line: 2.5 }], oddsProps: [prop(1.5)], analyzeResult: { grade: 'A', confidence: 70 }, // same grade at the new line }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ value: 1, revised: 0 }); expect(calls.analyze).toHaveLength(1); expect(calls.analyze[0].line).toBe(1.5); // re-graded at the REAL current line expect(store.get('snapshot:mlb:latest').grades[0].movement.kind).toBe('value'); expect(calls.revisions).toHaveLength(0); }); test('moved AGAINST ≥1.0, grade DROPS → PUBLIC revision (original preserved)', async () => { const { deps, store, calls } = harness({ grades: [{ ...GRADE, gradedAt: { line: 2.5, odds: -110, timestamp: NOW }, line: 2.5 }], oddsProps: [prop(1.5)], analyzeResult: { grade: 'C', confidence: 40 }, }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ revised: 1 }); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.grade).toBe('C'); expect(g.revised_from_grade).toBe('A'); // the original, forever expect(calls.revisions[0]).toMatchObject({ newGrade: 'C', fromGrade: 'A', line: 2.5, side: 'over' }); }); test('a second drop keeps the ORIGINAL revised_from_grade', async () => { const already = { ...GRADE, grade: 'B', revised_from_grade: 'A', gradedAt: { line: 2.5, odds: null, timestamp: NOW }, line: 2.5 }; const { deps, store } = harness({ grades: [already], oddsProps: [prop(1.5)], analyzeResult: { grade: 'C' } }); await runIntradayRefresh('mlb', deps); expect(store.get('snapshot:mlb:latest').grades[0].revised_from_grade).toBe('A'); }); test('an insufficient re-read HOLDS the original grade (never blanks it)', async () => { const { deps, store } = harness({ grades: [{ ...GRADE, gradedAt: { line: 2.5, odds: null, timestamp: NOW }, line: 2.5 }], oddsProps: [prop(1.5)], analyzeResult: { grade: null, insufficient_data: true }, }); const res = await runIntradayRefresh('mlb', deps); expect(res.value).toBe(1); expect(store.get('snapshot:mlb:latest').grades[0].grade).toBe('A'); }); test('prop gone from the feed → frozen untouched; close recaptured every run', async () => { const { deps, store, calls } = harness({ grades: [GRADE], oddsProps: [prop(0.5)], analyzeResult: null }); const res = await runIntradayRefresh('mlb', deps); expect(res.checked).toBe(1); expect(store.get('snapshot:mlb:latest').grades[0].movement).toBeNull(); // <0.5 noise expect(calls.closing).toBe(1); // refresh-fidelity closing capture }); test('no snapshot → honest skip, zero quota spent', async () => { const calls = { odds: 0 }; const res = await runIntradayRefresh('mlb', { cacheGet: async () => null, cacheSet: async () => {}, getOdds: async () => { calls.odds += 1; return { props: [] }; }, ledger: {}, pushTickerItems: async () => {}, now: () => NOW, }); expect(res.status).toBe('skipped'); expect(calls.odds).toBe(0); }); }); // S6 (A1 board) — sparkline fuel: {t, line} history capture on each grade's // movement tracking, persisted inside the snapshot write-back (no new keys). describe('trackHistory — real {t, line} points, seeded, deduped, capped', () => { const LOCK_TS = '2026-07-11T14:00:00.000Z'; const g = (extra = {}) => ({ ...GRADE, gradedAt: { line: 0.5, odds: -115, timestamp: LOCK_TS }, ...extra }); test('first capture seeds the LOCKED line at its own timestamp, then the move', () => { const h = trackHistory(g(), 1.5, NOW); expect(h).toEqual([{ t: LOCK_TS, line: 0.5 }, { t: NOW, line: 1.5 }]); }); test('a flat line never appends a duplicate point (a point means it MOVED)', () => { const h = trackHistory(g(), 0.5, NOW); // current == locked expect(h).toEqual([{ t: LOCK_TS, line: 0.5 }]); const again = trackHistory(g({ history: h }), 0.5, '2026-07-11T21:00:00.000Z'); expect(again).toHaveLength(1); }); test('an unparseable current line appends nothing (real points only)', () => { expect(trackHistory(g(), null, NOW)).toBeUndefined(); const prior = [{ t: LOCK_TS, line: 0.5 }]; expect(trackHistory(g({ history: prior }), 'n/a', NOW)).toBe(prior); }); test('capped at 24 points, newest kept', () => { const prior = Array.from({ length: HISTORY_CAP }, (_, i) => ({ t: `t${i}`, line: i })); const h = trackHistory(g({ history: prior }), 99, NOW); expect(h).toHaveLength(HISTORY_CAP); expect(h[HISTORY_CAP - 1]).toEqual({ t: NOW, line: 99 }); expect(h[0]).toEqual({ t: 't1', line: 1 }); // oldest point aged out }); }); describe('runIntradayRefresh — history rides the snapshot write-back', () => { test('a steam move persists history on the grade (locked point + current)', async () => { const { deps, store } = harness({ grades: [GRADE], oddsProps: [prop(1.5)], analyzeResult: null }); await runIntradayRefresh('mlb', deps); const snap = store.get('snapshot:mlb:latest'); expect(snap.grades[0].history).toEqual([ { t: NOW, line: 0.5 }, // seeded from the lock (gradedAt.timestamp === NOW here) { t: NOW, line: 1.5 }, ]); // grades:{sport} carries the same enriched grades. expect(store.get('grades:mlb').grades[0].history).toHaveLength(2); }); test('a flat run keeps a single seeded point — the sparkline stays hidden (<3)', async () => { const { deps, store } = harness({ grades: [GRADE], oddsProps: [prop(0.5)], analyzeResult: null }); await runIntradayRefresh('mlb', deps); expect(store.get('snapshot:mlb:latest').grades[0].history).toEqual([{ t: NOW, line: 0.5 }]); }); test('a prop gone from the feed leaves prior history untouched', async () => { const withHist = { ...GRADE, stat_type: 'hits', history: [{ t: 'x', line: 1 }] }; const { deps, store } = harness({ grades: [withHist], oddsProps: [prop(1.5)], analyzeResult: null }); await runIntradayRefresh('mlb', deps); const frozen = store.get('snapshot:mlb:latest').grades.find((g) => g.stat_type === 'hits'); expect(frozen.history).toEqual([{ t: 'x', line: 1 }]); }); }); describe('inSlateHours — noon–midnight ET', () => { test('3 PM ET yes, 4 AM ET no', () => { expect(inSlateHours(new Date('2026-07-11T19:00:00Z'))).toBe(true); // 3 PM EDT expect(inSlateHours(new Date('2026-07-11T08:00:00Z'))).toBe(false); // 4 AM EDT }); });