import type { FetchedStandingsRecord, StandingsSyncAdapter } from "./types"; const AFL_STANDINGS_URL = "https://api.squiggle.com.au/?q=standings;year=2026;format=json"; /** * Squiggle API response shape for a single team's ladder entry. * Docs: https://api.squiggle.com.au/ */ interface SquiggleStandingsEntry { id: number; // Squiggle team ID (1–18) name: string; // Full team name, e.g. "Western Bulldogs" wins: number; losses: number; draws: number; played: number; // Games played for: number; // Points scored for against: number; // Points scored against percentage: number;// (for / (for + against)) * 100 pts: number; // Ladder points (4=win, 2=draw, 0=loss) rank: number; // Current ladder position (1-based) } interface SquiggleStandingsResponse { standings: SquiggleStandingsEntry[]; } export class AflStandingsAdapter implements StandingsSyncAdapter { async fetchStandings(): Promise { const response = await fetch(AFL_STANDINGS_URL, { headers: { // Squiggle asks all clients to identify themselves for rate-limit contact. // Set SQUIGGLE_CONTACT_EMAIL in your environment to identify this client. "User-Agent": `Brackt.com AFL standings sync - ${process.env.SQUIGGLE_CONTACT_EMAIL ?? "admin@brackt.com"}`, }, }); if (!response.ok) { throw new Error( `AFL Squiggle standings API returned ${response.status}: ${response.statusText}` ); } const json = (await response.json()) as SquiggleStandingsResponse; const entries = json.standings; if (!entries || entries.length === 0) { throw new Error( "AFL Squiggle standings API returned no entries — response shape may have changed" ); } // Squiggle already includes `rank` (ladder position), sorted by ladder position. // Sort ascending by rank so leagueRank matches the AFL ladder order. const sorted = entries.toSorted((a, b) => a.rank - b.rank); return sorted.map((entry): FetchedStandingsRecord => ({ teamName: entry.name, externalTeamId: String(entry.id), wins: entry.wins, losses: entry.losses, ties: entry.draws, // AFL draws are stored in the `ties` column winPct: entry.percentage / 100, // Squiggle returns e.g. 62.5; store as 0.625 gamesPlayed: entry.played, leagueRank: entry.rank, })); } }