Session 61 (pre-merge): live-verification fixes from day-one rows

1. [settlement] armed boot line — settlement WAS scheduled (the tick runs
   settleAllOutcomes + settleAllLedgers FIRST at every snapshot slot,
   src/snapshotScheduler.js) but was invisible at boot. Now verifiable
   from logs forever.
2. Null locked_odds root cause (4 day-one rows, all betmgm SB unders):
   genuinely absent in the DB — the first-seen book row carried no juice
   for that side. indexOdds/indexProps now PREFER a book row with both
   sides priced (still a real row, never synthesized). Display was
   correct: absent beats wrong.
3. Verified retry-safe: 'Odds data temporarily unavailable' is the
   odds-api quota gate (oddsService:423) — thrown BEFORE any spend or
   cache write; runSnapshot errors write nothing; the next cron retries
   fresh with PropLine first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kev
2026-07-11 10:16:27 -04:00
parent 7a35c96781
commit 4d2b27d1d0
4 changed files with 37 additions and 4 deletions
+5
View File
@@ -147,6 +147,11 @@ function startSnapshotScheduler(opts = {}) {
const interval = setInterval(() => { void tick(); void refreshTick(); }, 60_000);
if (interval.unref) interval.unref();
console.log(`[snapshotScheduler] armed — SNAPSHOT_CRON=${process.env.SNAPSHOT_CRON}, hours=${HOURS_UTC.join(',')} UTC, intraday=${process.env.INTRADAY_REFRESH === '0' ? 'off' : `${REFRESH_MINUTES}m (slate hours)`}`);
// Session 61 — settlement is scheduled IN THIS tick (settleAllOutcomes +
// settleAllLedgers run FIRST at every snapshot slot, before grading). It
// was invisible at boot, which made "is settlement scheduled?" unanswerable
// from logs. This line makes it verifiable forever.
console.log(`[settlement] armed — outcomes + ledger settle pass runs FIRST at each snapshot slot (${HOURS_UTC.join(',')} UTC), idempotent re-runs`);
return { interval, tick, refreshTick };
}