Add an on-demand endpoint for the lineup-context ingest

The first prod run wrote zero rows while the parser demonstrably works locally
(144 rows, 10 games with lineups posted), so the zero was wiring rather than
absence -- but diagnosing that required a full snapshot, which now takes about
three minutes and 524s at the edge.

Same reasoning as the statcast refresh endpoint: a job is proven by running it
and reading the result, never by waiting for the slot it rides in. This makes
the ingest verifiable in seconds, so 'zero rows' can be told apart from 'no
lineups posted yet' immediately -- which is the exact confusion the defence
ingest hit when a doubled path 404'd and read as 'Statcast has no fielding
data'.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
This commit is contained in:
Kev
2026-08-04 16:13:53 -04:00
parent 08276c0880
commit 7f69fef14c
+27
View File
@@ -487,6 +487,33 @@ router.get('/gamectx/accrual', async (req, res) => {
* by waiting for the cron slot. Idempotent — running it twice is a no-op beyond
* refreshing values and updated_at.
*/
/**
* POST /api/internal/lineup-context/refresh — INDUCE the lineup + baserunner
* context ingest.
*
* Exists for the same reason the statcast one does: a job is proven by running
* it and reading the result, never by waiting for the slot it rides in. It also
* makes the ingest verifiable WITHOUT a full snapshot, which now takes ~3
* minutes and 524s at the edge — so a zero row count can be diagnosed as a
* wiring bug rather than an honest absence in seconds.
*/
router.post('/lineup-context/refresh', async (req, res) => {
try {
const svc = require('../services/lineupContextService');
const sb = require('../utils/supabase').getSupabaseServiceClient();
if (!sb) return res.status(500).json({ ok: false, error: 'no supabase service client' });
const out = await svc.refreshContext({
supabase: sb,
sport: 'mlb',
date: req.query.date || undefined,
});
return res.status(out.ok ? 200 : 500).json(out);
} catch (err) {
console.error('[internal/lineup-context]', err.message);
return res.status(500).json({ ok: false, error: err.message });
}
});
router.post('/statcast/refresh', async (req, res) => {
try {
const agg = require('../services/statcastAggregateService');