teecup/frontend/app/order-of-merit/[id]/page.tsx
Erol Haagenrud f740814833 Order of Merit: offentlig/delt visning (ADR-076)
Siste av de tre gjenstående OOM-punktene fra ADR-043 (lag-OOM ADR-074,
eclectic på tvers av turneringer ADR-075, offentlig visning her).

Migrasjon 076: SECURITY DEFINER-bro public_order_of_merit_by_id, samme
anti-enumerering som public_org_by_slug/public_tournament_by_code. Ny
/public/order-of-merits/{id}-endepunkt (gjenbruker den eksisterende
leaderboard-beregningen direkte). Ny uautentisert frontend-side
modellert på public-club.tsx, "Del offentlig lenke" i innstillinger.

83/83 backend-tester, 45/45 vitest, scratch-verifisert i egen inkognito-
nettleserkontekst (ingen session-cookie). Migrasjon vist og bekreftet
før kjøring mot ekte teecup_db. Rullet ut.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 21:20:23 +02:00

44 lines
1.3 KiB
TypeScript

import type { Metadata } from "next"
import { PublicOrderOfMerit } from "@/components/public-order-of-merit"
// Server-side -- går IKKE gjennom next.config.mjs sin rewrites() (kun for
// nettleser-trafikk inn til Next.js-serveren). Peker direkte på API-et.
const API_ORIGIN = process.env.TEECUP_API_ORIGIN || "http://localhost:8000"
type PublicOomInfo = {
name: string
}
export async function generateMetadata({
params,
}: {
params: Promise<{ id: string }>
}): Promise<Metadata> {
const { id } = await params
try {
const res = await fetch(`${API_ORIGIN}/public/order-of-merits/${id}`, { cache: "no-store" })
if (!res.ok) {
return { title: "Order of Merit | TeeCup" }
}
const data: PublicOomInfo = await res.json()
const title = `${data.name} | TeeCup`
const description = `Se resultatlisten for ${data.name} på TeeCup.`
return {
title,
description,
openGraph: { title, description, siteName: "TeeCup", type: "website" },
twitter: { card: "summary", title, description },
}
} catch {
return { title: "TeeCup" }
}
}
export default async function PublicOrderOfMeritPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
return <PublicOrderOfMerit oomId={id} />
}