v2 Phase 2: match previews + team profiles
- buildPreviewData.ts: precomputes from 150y of results → h2h.json (825 WC-team pairings, full records + recent meetings) + scorers.json (top-10 all-time scorers per team). Committed goalscorers.csv. - server/src/preview.ts: assembles MatchPreview / TeamProfile from three layers — historical (h2h, scorers), DB enrichment (ESPN form/lineups/venue), live model (W/D/L, xG, odds, Elo). /api/preview/:num + /api/team/:name. - Client: rich /match/:num page (model expectation, recent form chips, H2H record + recent meetings, lineups-or-key-players) and /team/:name profile (Elo, odds, standing, fixtures, all-time scorers). Match cards now link to previews; cross-linking between matches and teams. - Verified: Mexico-SA preview (81% W, 2-0, form, H2H 2-1-1, Borgetti 37) and Argentina profile (Messi 63) render; 22 tests pass; build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -117,6 +117,49 @@ export interface ModelSnapshot {
|
||||
history: OddsHistoryPoint[];
|
||||
}
|
||||
|
||||
// ---- match previews / team profiles ----
|
||||
|
||||
export interface H2HMeeting { date: string; home: string; away: string; homeScore: number; awayScore: number }
|
||||
export interface H2HSummary {
|
||||
games: number;
|
||||
/** From THIS fixture's home/away perspective. */
|
||||
homeWins: number;
|
||||
awayWins: number;
|
||||
draws: number;
|
||||
homeGoals: number;
|
||||
awayGoals: number;
|
||||
last: H2HMeeting[];
|
||||
}
|
||||
|
||||
export interface KeyPlayer { name: string; goals: number; pens: number }
|
||||
export interface LineupPlayer { name: string; position: string | null; starter: boolean; number: number | null }
|
||||
|
||||
export interface MatchPreview {
|
||||
num: number;
|
||||
fixture: Fixture;
|
||||
venue: string | null;
|
||||
prediction: MatchPrediction | null;
|
||||
/** Recent results per side, most recent first ('W'|'D'|'L'). */
|
||||
form: { home: string[]; away: string[] };
|
||||
h2h: H2HSummary | null;
|
||||
lineups: { home: LineupPlayer[]; away: LineupPlayer[] } | null;
|
||||
keyPlayers: { home: KeyPlayer[]; away: KeyPlayer[] };
|
||||
/** Honest note on which data layers are populated yet. */
|
||||
dataNote: string;
|
||||
updatedAt: number | null;
|
||||
}
|
||||
|
||||
export interface TeamProfile {
|
||||
team: string;
|
||||
elo: number;
|
||||
group: string | null;
|
||||
standing: StandingRow | null;
|
||||
fixtures: Fixture[];
|
||||
keyPlayers: KeyPlayer[];
|
||||
championOdds: number | null;
|
||||
qualifyOdds: number | null;
|
||||
}
|
||||
|
||||
// ---- data-story viz (StatsBomb open data, a fixed historical match) ----
|
||||
|
||||
export interface VizShot {
|
||||
|
||||
Reference in New Issue
Block a user