Sessions 5-7a: 955 tests, deployment ready

This commit is contained in:
Kev
2026-06-08 18:35:13 -04:00
parent 06b82624a2
commit 1fa04dc776
371 changed files with 49366 additions and 955 deletions
+59
View File
@@ -0,0 +1,59 @@
/**
* Pipeline routes — orchestrate the data pipeline.
*
* POST /api/pipeline/refresh body: { sport, graded? }
* GET /api/pipeline/status
*
* Refresh is the only write path; it's the one n8n calls. We gate it with
* a shared secret so a stray POST from the open internet can't trigger an
* upstream fan-out.
*/
const express = require('express');
const provider = require('../services/UnifiedOddsProvider');
const { isActiveSport, shouldCollect, SPORTS } = require('../config/sports');
const router = express.Router();
const SUPPORTED = Object.keys(SPORTS);
function requirePipelineSecret(req, res, next) {
const expected = process.env.PIPELINE_SECRET;
if (!expected) return res.status(503).json({ error: 'PIPELINE_SECRET not configured' });
const got = req.get('X-Pipeline-Secret') || req.body?.secret;
if (!got || got !== expected) {
return res.status(401).json({ error: 'invalid pipeline secret' });
}
return next();
}
router.post('/refresh', requirePipelineSecret, async (req, res) => {
const sport = String(req.body?.sport || '').toLowerCase();
if (!sport || !SUPPORTED.includes(sport)) {
return res.status(400).json({ error: 'invalid or missing sport', supported: SUPPORTED });
}
try {
const out = await provider.fullRefresh(sport, {
gradedProps: Array.isArray(req.body?.graded) ? req.body.graded : [],
});
return res.json(out);
} catch (err) {
return res.status(502).json({ error: 'refresh failed', detail: err?.message || 'unknown' });
}
});
router.get('/status', async (_req, res) => {
const sports = Object.values(SPORTS).map((s) => ({
key: s.key,
label: s.label,
active: s.active,
collect: s.collectData,
}));
return res.json({
sports,
runtime: provider.status(),
ts: new Date().toISOString(),
});
});
module.exports = router;