export interface RaceTimerSummary { rank: number; level: number; // PlayerPoints / 1000, per how the server defines "level" profileUrl: string; } const RACETIMER_API_BASE = 'https://racebackend.unloze.com/racetimer_endpoints-1.0/api/timers/player'; const RACETIMER_PROFILE_BASE = 'https://racetimerweb.unloze.com/#/player'; /** * Fetches a player's RaceTimer rank/points from the RaceTimer backend. * Returns null if the player has no RaceTimer record (e.g. never played a * timed map) or the request fails for any reason — this is a secondary, * best-effort enrichment, not something that should ever break the page. * * Cached for an hour via Next's extended fetch() — same reasoning as the * Steam avatar lookup. */ export async function getRaceTimerSummary(steamId2: string): Promise { try { const res = await fetch(`${RACETIMER_API_BASE}/${encodeURIComponent(steamId2)}`, { next: { revalidate: 3600 }, }); if (!res.ok) return null; const data = await res.json(); if (typeof data?.PlayerPoints !== 'number' || typeof data?.Rank !== 'number') { return null; } return { rank: data.Rank, level: Math.floor(data.PlayerPoints / 1000), profileUrl: `${RACETIMER_PROFILE_BASE}/${encodeURIComponent(steamId2)}`, }; } catch { return null; } }