Sessions 5-7a: 955 tests, deployment ready
This commit is contained in:
@@ -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;
|
||||
Reference in New Issue
Block a user