Session 21: All adapters through gateway, ntfy alerts, provider registry correction (1486 tests)

This commit is contained in:
Kev
2026-06-12 02:06:22 -04:00
parent 9b10bb4138
commit ea848e327e
14 changed files with 614 additions and 46 deletions
+15 -5
View File
@@ -15,6 +15,12 @@ const axios = require('axios');
const { createLimiter, createCircuitBreaker, API_BUDGETS } = require('../../utils/rateLimiter');
const { devig } = require('../../utils/odds');
const { getSupabaseServiceClient } = require('../../utils/supabase');
// Session 21 — gateway wrap. ODDSPAPI is the Pinnacle-close
// provider, not a live-odds source. Each call hits ONCE per game
// at tip-off, so traffic is bounded — the gateway counter mostly
// gives the admin dashboard visibility rather than acting as
// hot-path throttle (the in-process limiter does that).
const gateway = require('../providerGateway');
const HTTP_TIMEOUT_MS = 10_000;
const BASE_URL = process.env.ODDSPAPI_BASE_URL || 'https://api.oddspapi.io/v1';
@@ -47,11 +53,15 @@ async function fetchPinnacleProp(sport, gameId, playerName, statType) {
await limiter.waitForToken();
try {
return await breaker.call(async () => {
const res = await axios.get(`${BASE_URL}/sports/${sportKey(sport)}/events/${gameId}/odds`, {
params: { bookmaker: 'pinnacle', market: 'player_props' },
headers: { 'X-Api-Key': process.env.ODDSPAPI_KEY },
timeout: HTTP_TIMEOUT_MS,
});
const res = await gateway.fetch(
'oddspapi',
() => axios.get(`${BASE_URL}/sports/${sportKey(sport)}/events/${gameId}/odds`, {
params: { bookmaker: 'pinnacle', market: 'player_props' },
headers: { 'X-Api-Key': process.env.ODDSPAPI_KEY },
timeout: HTTP_TIMEOUT_MS,
}),
{ capability: 'closing_lines', sport },
);
const props = res.data?.props || res.data?.data || [];
return Array.isArray(props)
? props.find(