package model // Standings is a league table, fetched from ESPN's standings endpoint. Leagues // split into one or more groups (soccer = groups, MLB = leagues, NBA/NHL/NFL = // conferences); each group is an independent ranked table. type Standings struct { League LeagueID Groups []StandingsGroup } // StandingsGroup is one ranked table within a league's standings. type StandingsGroup struct { Name string // "Group A", "American League", "Eastern Conference", or "" Columns []string // stat column headers, parallel to each row's Values Rows []StandingsRow } // StandingsRow is one team's line in a group, ranked by ESPN's own ordering. type StandingsRow struct { Rank int Team Team Values []string // stat values, parallel to the group's Columns } // RowCount is the total number of team rows across all groups — the size of the // flattened selection space the standings cursor walks. func (s Standings) RowCount() int { n := 0 for _, g := range s.Groups { n += len(g.Rows) } return n } // RowAt returns the team row at flattened index i (across groups, in order), // ok=false if i is out of range. func (s Standings) RowAt(i int) (StandingsRow, bool) { for _, g := range s.Groups { if i < len(g.Rows) { return g.Rows[i], true } i -= len(g.Rows) } return StandingsRow{}, false } // TeamSchedule is a team's full season schedule (past results + upcoming // fixtures) from ESPN's team-schedule endpoint, beyond the polled fetch window. type TeamSchedule struct { Team Team Season string // e.g. "2026 Regular Season" Games []Game // chronological; finals carry scores, pre-games are upcoming }