// fifa-eval.ts β€” Analyse-Skript: IdGroup, MatchNumber, Attendance, MatchStatus // AusfΓΌhrung: npx ts-node --compiler-options '{"module":"commonjs","target":"es2020"}' scripts/fifa-eval.ts // Oder mit Deno, Bun: bun run scripts/fifa-eval.ts const FIFA_BASE = "https://api.fifa.com/api/v3"; const FIFA_SEASON = "285023"; interface RawMatch { MatchNumber: number; MatchStatus: number; IdGroup: string | null; IdStage: string; StageName: Array<{ Locale: string; Description: string }>; GroupName?: Array<{ Locale: string; Description: string }>; Home: { IdTeam: string; Abbreviation: string; TeamName?: Array<{ Locale: string; Description: string }> } | null; Away: { IdTeam: string; Abbreviation: string; TeamName?: Array<{ Locale: string; Description: string }> } | null; HomeTeamScore: number | null; AwayTeamScore: number | null; Attendance: string | null; Date: string; LocalDate: string; } async function main() { console.log("πŸ“‘ Rufe FIFA Calendar-Endpoint ab..."); const res = await fetch( `${FIFA_BASE}/calendar/matches?language=de&count=500&idSeason=${FIFA_SEASON}`, { headers: { "User-Agent": "fifa-eval/1.0" } }, ); if (!res.ok) { console.error("Fehler:", res.status, res.statusText); process.exit(1); } const data = (await res.json()) as { Results: RawMatch[] }; const matches = data.Results ?? []; console.log(`βœ… ${matches.length} Matches geladen\n`); // ── A) IdGroup β†’ GroupName Mapping ── console.log("═══ A) IdGroup β†’ Gruppe (A-L) ═══"); const groupMap = new Map(); for (const m of matches) { if (!m.IdGroup || !m.GroupName) continue; const desc = m.GroupName.find(g => g.Locale === "de-DE")?.Description ?? m.GroupName[0]?.Description ?? `ID:${m.IdGroup}`; if (!groupMap.has(m.IdGroup)) groupMap.set(m.IdGroup, desc); } console.log(`Anzahl distinct IdGroup-Werte: ${groupMap.size}`); const sorted = [...groupMap.entries()].sort((a, b) => parseInt(a[0]) - parseInt(b[0])); for (const [id, name] of sorted) { console.log(` ${id} β†’ "${name}"`); } // Als kopierbare Konstante console.log("\n// Kopierbare Konstante:"); console.log("const FIFA_IDGROUP_TO_GROUP: Record = {"); for (const [id, name] of sorted) { const letter = name.replace(/^Gruppe\s+/, ""); console.log(` "${id}": "${letter}", // ${name}`); } console.log("};"); // ── B) MatchNumber-Konsistenz ── console.log("\n═══ B) MatchNumber-Konsistenz ═══"); const groupMatches = matches.filter(m => m.IdGroup != null).sort((a, b) => a.MatchNumber - b.MatchNumber); const koMatches = matches.filter(m => m.IdGroup == null).sort((a, b) => a.MatchNumber - b.MatchNumber); console.log(`Gruppenspiele: ${groupMatches.length} (MatchNumber ${groupMatches[0]?.MatchNumber}–${groupMatches[groupMatches.length-1]?.MatchNumber})`); console.log(`K.o.-Spiele: ${koMatches.length} (MatchNumber ${koMatches[0]?.MatchNumber}–${koMatches[koMatches.length-1]?.MatchNumber})`); // Stichproben fΓΌr K.o.-Slots const checkNums = [73, 74, 76, 89, 104]; for (const n of checkNums) { const m = matches.find(x => x.MatchNumber === n); if (m) { const home = m.Home?.Abbreviation ?? "?"; const away = m.Away?.Abbreviation ?? "?"; console.log(` #${n}: ${home} vs ${away} | Stage=${m.StageName?.[0]?.Description ?? "?"} | Status=${m.MatchStatus}`); } else { console.log(` #${n}: NICHT GEFUNDEN`); } } // ── C) Attendance + Scheduled ── console.log("\n═══ C) Attendance + Scheduled-Matches ═══"); const withAttendance = matches.filter(m => m.Attendance != null); console.log(`Matches mit Attendance: ${withAttendance.length}`); if (withAttendance.length > 0) { const ex = withAttendance[0]; console.log(` Beispiel: #${ex.MatchNumber} β†’ ${ex.Attendance}`); } const scheduled = matches.filter(m => m.MatchStatus === 1); console.log(`Scheduled-Matches (Status=1): ${scheduled.length}`); if (scheduled.length > 0) { const ex = scheduled[0]; console.log(` Beispiel: #${ex.MatchNumber} ${ex.Home?.Abbreviation ?? "?"} vs ${ex.Away?.Abbreviation ?? "?"} | Date=${ex.Date}`); } // ── D) MatchStatus-Werte ── console.log("\n═══ D) Distinct MatchStatus-Werte ═══"); const statuses = new Map(); for (const m of matches) { statuses.set(m.MatchStatus, (statuses.get(m.MatchStatus) ?? 0) + 1); } const statusLabels: Record = { 0: "finished", 1: "scheduled", 10: "postponed", 3: "live?" }; for (const [s, c] of [...statuses.entries()].sort((a, b) => a[0] - b[0])) { console.log(` MatchStatus ${s}: ${c} Matches ${statusLabels[s] ? `(${statusLabels[s]})` : ""}`); } // ── E) Stage-Werte ── console.log("\n═══ E) Distinct Stages ═══"); const stages = new Map(); for (const m of matches) { const sn = m.StageName?.[0]?.Description ?? String(m.IdStage); stages.set(sn, (stages.get(sn) ?? 0) + 1); } for (const [s, c] of stages.entries()) { console.log(` "${s}" (IdStage=${matches.find(m => (m.StageName?.[0]?.Description ?? "") === s)?.IdStage}): ${c}`); } console.log("\nβœ… Analyse abgeschlossen."); } main().catch(console.error);