/** * Grade of the Day selector — runs daily ~5:15 PM ET. * * Rules: * 1. Use an A+ if one exists tonight. * 2. Otherwise the single highest-confidence A or A-. * 3. Otherwise fall back to the top grade overall. */ const axios = require('axios'); const { buildCard, publicCardUrl } = require('./_shareCardClient'); const API_BASE = process.env.API_BASE_URL || 'http://localhost:4000'; const GRADE_RANK = { 'A+': 0, 'A': 1, 'A-': 2, 'B+': 3, 'B': 4, 'B-': 5, 'C+': 6, 'C': 7, 'C-': 8, 'D': 9, 'F': 10 }; async function fetchTop(limit = 8) { const res = await axios.get(`${API_BASE}/api/props/top-graded?limit=${limit}`, { timeout: 10_000 }).catch(() => null); return Array.isArray(res?.data?.props) ? res.data.props : []; } function pickGOTD(props) { if (!props.length) return null; const sorted = [...props].sort((a, b) => { const ra = GRADE_RANK[a.grade] ?? 99; const rb = GRADE_RANK[b.grade] ?? 99; if (ra !== rb) return ra - rb; return (b.confidence ?? 0) - (a.confidence ?? 0); }); return sorted[0]; } async function generate({ format = 'square' } = {}) { const props = await fetchTop(8); const winner = pickGOTD(props); if (!winner) { return { data: null, imageBuffer: null, imageUrl: null, note: 'no grades available' }; } const payload = { player: winner.player_name || winner.player, sport: winner.sport, stat: winner.stat_type || winner.stat, line: winner.line, direction: winner.direction, grade: winner.grade, projection: winner.projection, summary: winner.one_line_reason || winner.reasoning?.summary || null, }; let card = null; try { card = await buildCard({ type: 'gotd', format, payload }); } catch (err) { console.error('[gradeOfTheDay] card build failed:', err.message); } return { data: payload, imageBuffer: card?.buffer || null, imageContentType: card?.contentType || null, imageUrl: publicCardUrl({ type: 'gotd', format, payload }), }; } module.exports = { generate, pickGOTD };