'use strict'; /** * calibrationService.loadSettledRows — the Fix A1 regression. * * This reader measured 24.8% corrupt on production (617 of 2,490 rows returned * twice, an equal number never returned) via two independent defects: an * unordered page walk, and a query error swallowed as end-of-data. Both are * locked here against a fake `sb`, so the regression cannot return silently. */ const calSvc = require('../../src/services/model/calibrationService'); /** * A fake PostgREST client for `ledger_entries`. Every filter in the reader's * chain is accepted and RECORDED, so a dropped filter fails the test rather than * quietly changing the row set. */ function fakeSb(rows, opts = {}) { const state = { rows, filters: [], selected: null, rangeCalls: 0, ordered: [] }; const q = { select(cols) { state.selected = cols; return q; }, eq(c, v) { state.filters.push(['eq', c, v]); return q; }, is(c, v) { state.filters.push(['is', c, v]); return q; }, in(c, v) { state.filters.push(['in', c, v]); return q; }, not(c, o, v) { state.filters.push(['not', c, o, v]); return q; }, lt(c, v) { state.filters.push(['lt', c, v]); return q; }, order(c, o) { state.ordered.push([c, o && o.ascending !== false]); return q; }, async range(from, to) { state.rangeCalls += 1; if (opts.errorOnRange && opts.errorOnRange(from)) { return { data: null, error: { message: 'connection reset by peer' } }; } if (opts.beforeRange) opts.beforeRange(from, state); const key = state.ordered.length ? state.ordered[state.ordered.length - 1][0] : null; const out = key ? [...state.rows].sort((a, b) => (a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0)) : [...state.rows]; return { data: out.slice(from, to + 1), error: null }; }, }; return { state, from() { return q; } }; } const led = (id, p, won, date) => ({ id, p_win: p, outcome: won ? 'hit' : 'miss', game_date: date, quarantine_reason: null, }); const many = (n) => Array.from({ length: n }, (_, i) => led(i + 1, 0.5 + (i % 40) / 100, i % 2 === 0, '2026-08-01')); describe('loadSettledRows — orders on a UNIQUE key, every page', () => { it('returns every row exactly once across a multi-page walk', async () => { const sb = fakeSb(many(2490)); const rows = await calSvc.loadSettledRows(sb, { sport: 'mlb', stat: 'hits', before: '2026-08-09' }); expect(rows).toHaveLength(2490); expect(new Set(rows.map((r) => r.id)).size).toBe(2490); expect(sb.state.rangeCalls).toBe(3); }); it('orders by id on EVERY page, not just the first', async () => { const sb = fakeSb(many(2490)); await calSvc.loadSettledRows(sb, { before: '2026-08-09' }); expect(sb.state.ordered).toHaveLength(sb.state.rangeCalls); for (const [col, asc] of sb.state.ordered) { expect(col).toBe('id'); // a UNIQUE key — an order on a non-unique expect(asc).toBe(true); // column still lets ties scramble } }); it('selects id — without it the ordering key is not in the payload', async () => { const sb = fakeSb(many(10)); await calSvc.loadSettledRows(sb, { before: '2026-08-09' }); expect(sb.state.selected).toMatch(/\bid\b/); }); it('keeps the point-in-time cut and every identity filter', async () => { const sb = fakeSb(many(10)); await calSvc.loadSettledRows(sb, { sport: 'mlb', stat: 'hits', before: '2026-08-09' }); expect(sb.state.filters).toEqual(expect.arrayContaining([ ['eq', 'sport', 'mlb'], ['is', 'user_id', null], ['eq', 'stat', 'hits'], ['in', 'outcome', ['hit', 'miss']], ['not', 'p_win', 'is', null], ['lt', 'game_date', '2026-08-09'], // STRICTLY before — never the answer ])); }); }); describe('loadSettledRows — a failed read THROWS, never a short fit', () => { it('throws when a later page errors instead of returning the earlier pages', async () => { // The :117 defect returned 1,000 rows here and `build()` fitted a map on // them, indistinguishable from a complete fit. const sb = fakeSb(many(2490), { errorOnRange: (from) => from === 1000 }); await expect(calSvc.loadSettledRows(sb, { before: '2026-08-09' })) .rejects.toThrow(/read failed at range 1000-1999/); }); it('propagates through fromLedger — a read failure is not "thin history"', async () => { // null means "not enough settled rows to fit"; a throw means "the read // broke". Collapsing them is what let a fragment look like a fit. const sb = fakeSb(many(2490), { errorOnRange: (from) => from === 1000 }); await expect(calSvc.fromLedger(sb, { sport: 'mlb', stat: 'hits', before: '2026-08-09' })) .rejects.toThrow(/read failed/); }); it('still returns null (not a throw) when there is genuinely no client', async () => { await expect(calSvc.fromLedger(null, {})).resolves.toBeNull(); }); }); describe('loadSettledRows — concurrent append (the production condition)', () => { it('returns every pre-existing row exactly once while the cron appends mid-walk', async () => { // ledger_entries is written at 14/19/22/1/3 UTC. With a stable ascending // unique key, an appended row lands after the cursor: nothing already // returned can repeat, nothing pending can be skipped. const original = many(2500); let nextId = 90000; const sb = fakeSb([...original], { beforeRange: (from, state) => { if (from > 0) state.rows.push(led(nextId++, 0.6, true, '2026-08-08')); }, }); const rows = await calSvc.loadSettledRows(sb, { before: '2026-08-09' }); const seen = rows.map((r) => r.id); expect(new Set(seen).size).toBe(seen.length); // zero duplicates for (const o of original) expect(seen).toContain(o.id); // zero dropped }); it('THROWS rather than returning a corrupted set if the walk ever repeats a row', async () => { // Belt and braces: if the ordering guarantee were ever lost, the reader // refuses instead of handing a duplicated sample to the fit. const sb = fakeSb([led(1, 0.5, true, '2026-08-01'), led(1, 0.5, true, '2026-08-01')]); await expect(calSvc.loadSettledRows(sb, { before: '2026-08-09' })) .rejects.toThrow(/duplicate key \(id\)=1/); }); }); describe('Fix A1 does not change what is SERVED', () => { it('the deploy set is still empty — no stat serves a calibrated number', () => { const snapshotService = require('../../src/services/snapshotService'); expect(snapshotService.CALIBRATION_DEPLOYED).toEqual([]); }); });