feat: LiveOddsTicker + GitHub Actions CI + issue templates + CONTRIBUTING#18
feat: LiveOddsTicker + GitHub Actions CI + issue templates + CONTRIBUTING#18ianalloway merged 4 commits intomainfrom
Conversation
- New /picks route with DailyPicks.tsx — shows today's NBA/NFL games with free vs premium tiers, confidence badges, and reveal-on-click AI pick cards that surface model probability, edge, and reasoning - App.tsx: register /picks route - Index.tsx: add "View Today's Picks" CTA button to hero section and import Star icon + useNavigate hook https://claude.ai/code/session_011CZSXE3cxykM7wtDY28nTU
- Leaderboard.tsx: full season standings with podium (top 3), stat table (units/win%/ROI/streak/bets/badge), weekly movers panel, hottest streaks panel, all-time vs this-week tab toggle, sport filter - App.tsx: register /leaderboard route - Index.tsx: add Leaderboard button alongside Picks CTA in hero https://claude.ai/code/session_011CZSXE3cxykM7wtDY28nTU
✅ Deploy Preview for aiadvantagea ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| const fakeInput = `${awayTeam} at ${homeTeam}`; | ||
| return analyzeGame(fakeInput, pick.sport); |
There was a problem hiding this comment.
🔴 analyzeGame called with wrong arguments: combined string passed as homeTeam instead of separate team names
In DailyPicks.tsx:73, analyzeGame is called as analyzeGame(fakeInput, pick.sport) where fakeInput is a combined string like "Denver Nuggets at Boston Celtics". However, analyzeGame expects (homeTeam: string, awayTeam: string, sport: Sport, ...) — two separate team name strings as the first two parameters.
Root Cause and Impact
The call passes the full sentence as homeTeam, and pick.sport (e.g., "nba") as awayTeam. The sport parameter then defaults to 'nba'. At src/lib/predictions.ts:386-387, both team lookups (teamStats[homeTeam] and teamStats[awayTeam]) will fail to find matching entries, so both teams fall back to getDefaultStats() (50% win rate, 0 point diff). This means even if the array-indexing bug (BUG-0002) were fixed, all predictions would be based on generic 50/50 stats rather than actual team data.
The correct call should be analyzeGame(pick.home, pick.away, pick.sport) to pass the home and away team names as separate arguments.
| const fakeInput = `${awayTeam} at ${homeTeam}`; | |
| return analyzeGame(fakeInput, pick.sport); | |
| // Use analyzeGame with home and away teams | |
| return analyzeGame(pick.home, pick.away, pick.sport); |
Was this helpful? React with 👍 or 👎 to provide feedback.
| return analyzeGame(fakeInput, pick.sport); | ||
| }, [pick, idx]); | ||
|
|
||
| const topPick = prediction[0]; |
There was a problem hiding this comment.
🔴 prediction[0] indexes into a GamePrediction object (not an array), always returning undefined
At DailyPicks.tsx:76, const topPick = prediction[0] treats the return value of analyzeGame as an array. However, analyzeGame returns a single GamePrediction object (see src/lib/predictions.ts:384). Indexing a plain object with [0] returns undefined in JavaScript.
Impact — Predictions never display
Since topPick is always undefined (falsy), the ternary at line 121 (topPick ? ... : ...) always falls through to the else branch, rendering:
No strong edge detected — skip this game.
for every single pick card after the user clicks "Reveal AI Pick". The actual prediction data (pick name, odds, win probability, edge, reasoning) is never shown to the user. The entire "Reveal AI Pick" feature is broken.
The fix should use the GamePrediction object directly, and access its properties (predictedWinner, homeOdds, homeProb, homeEdge, etc.) instead of non-existent array element properties like topPick.pick, topPick.odds, topPick.model_prob, topPick.edge, and topPick.reasoning.
Prompt for agents
In src/pages/DailyPicks.tsx, line 76 does `const topPick = prediction[0]` but `prediction` is a GamePrediction object, not an array. This causes topPick to always be undefined.
The fix requires two changes:
1. Line 76: Remove the array indexing. Use the prediction object directly, e.g.:
const topPick = prediction;
2. Lines 121-141: The template references properties that don't exist on GamePrediction (topPick.pick, topPick.odds, topPick.model_prob, topPick.edge, topPick.reasoning). These need to be mapped to actual GamePrediction properties:
- topPick.pick → topPick.predictedWinner
- topPick.odds → topPick.homeOdds or topPick.awayOdds (depending on predicted winner)
- topPick.model_prob → topPick.confidence
- topPick.edge → topPick.homeEdge or topPick.awayEdge (depending on predicted winner)
- topPick.reasoning → remove or replace with a generated string (GamePrediction has no reasoning field)
Alternatively, use the valueBet property if available:
- topPick.valueBet?.team for the pick
- topPick.valueBet?.odds for odds
- topPick.valueBet?.modelProb for probability
- topPick.valueBet?.edge for edge
The truthiness check on line 121 should also be updated since the prediction object is always truthy. Consider checking for a value bet or meaningful edge instead.
Was this helpful? React with 👍 or 👎 to provide feedback.
Runs on push to main and claude/** branches + PRs: - npm ci - tsc --noEmit (type check) - eslint (lint with max-warnings 0) - npm run build - Uploads dist/ artifact (7-day retention) https://claude.ai/code/session_011CZSXE3cxykM7wtDY28nTU
LiveOddsTicker: - Horizontal scrolling strip showing live ML/spread lines for all games - Highlights significant line movement (>8 pts) with yellow glow + ⚡ icon - Shows TrendingUp/Down arrows vs opening line to reveal steam moves - Pauses on hover, resumes on leave — zero JS deps beyond React - Auto-refreshes every 60s (shows last-updated time in header) - Integrated at top of Index page above the hero section Also adds CONTRIBUTING.md with dev setup, code style, and PR guidelines. https://claude.ai/code/session_011CZSXE3cxykM7wtDY28nTU
🤖 Claude Session SummaryHere's everything shipped in this session across the entire ianalloway GitHub org: 3 new repos created and shipped:
On this repo (ai-advantage):
On ian-web-forge:
API enhancements across all repos:
|
What's in this PR
🎰 LiveOddsTicker
Real-time horizontal scrolling odds strip at the top of every page:
⚙️ GitHub Actions CI
Runs on every push to
mainandclaude/**branches:npm ci→tsc --noEmit→eslint→npm run builddist/as artifact (7-day retention)📋 Issue Templates + CONTRIBUTING
.github/ISSUE_TEMPLATE/CONTRIBUTING.mdwith full dev setup, code style, and PR workflowTest plan
https://claude.ai/code/session_011CZSXE3cxykM7wtDY28nTU