Files
wm-projekt/app/api/matches/route.ts
2026-07-03 15:55:10 -05:00

68 lines
2.5 KiB
TypeScript

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { fetchMatchesAndTeamsFifa, fetchOdds, attachOdds, attachKOOdds, attachFifaLiveData } from "@/lib/feeds";
import { computeGroupTables, computeThirdPlaceTable } from "@/lib/standings";
import { qualifiedThirdGroups, resolveAnnexC } from "@/lib/bracket";
import { securelyQualifiedThirdTeams } from "@/lib/third-place-security";
// Diese Route wird vom Frontend gepollt. FIFA-API als Primärquelle.
export const dynamic = "force-dynamic";
export async function GET(request: NextRequest) {
const locale = request.nextUrl.searchParams.get("locale") || "de";
try {
const { matches: rawMatches, teams } = await fetchMatchesAndTeamsFifa(locale);
// Odds sind optional: fällt der Polymarket-Call aus, liefern wir trotzdem.
let matches = rawMatches;
let odds: Awaited<ReturnType<typeof fetchOdds>> | null = null;
try {
odds = await fetchOdds();
matches = attachOdds(rawMatches, teams, odds);
} catch (err) {
console.error("[polymarket] fetchOdds fehlgeschlagen:", err);
}
if (odds) {
matches = attachKOOdds(matches, teams, odds);
}
// FIFA-Live-Scores als häufiger gecachtes Overlay (Pipeline: Scores → Goals)
try {
matches = await attachFifaLiveData(matches, teams, locale);
} catch (err) {
console.warn("[fifa] Live-Overlay fehlgeschlagen:", err instanceof Error ? err.message : err);
}
const groupTables = computeGroupTables(teams, matches);
const groupTablesLive = computeGroupTables(teams, matches, true);
const normalizedMatches = matches.map((m) => ({ ...m, prob: m.prob ?? null }));
const thirdTable = computeThirdPlaceTable(groupTablesLive);
const qGroups = qualifiedThirdGroups(thirdTable);
const annex = qGroups.length === 8 ? resolveAnnexC(qGroups) : null;
// Sichere Drittplatzierte (Team-IDs, deren Top-8-Platz mathematisch feststeht)
const secureThirdTeams = securelyQualifiedThirdTeams(matches, teams);
return NextResponse.json({
updatedAt: new Date().toISOString(),
teams,
matches: normalizedMatches,
groupTables,
groupTablesLive,
thirdTable,
secureThirdTeams: [...secureThirdTeams],
annexAssignment: annex,
annexResolved: annex != null,
});
} catch (err) {
const message = err instanceof Error ? err.message : "unbekannter Fehler";
return NextResponse.json(
{ error: "Feed nicht erreichbar", detail: message },
{ status: 502 },
);
}
}