Python 51.6%
TypeScript 46.7%
CSS 1.7%
1import type { Metadata } from "next";2import Link from "next/link";3import { apiSafe } from "@/lib/api";4import { Badge, Card, Empty, SectionHeader } from "@/components/ui";5import { dateFr, dateTimeFr } from "@/lib/format";67export const metadata: Metadata = { title: "Changelog du modèle", description: "Historique public des versions du modèle QC26 et des runs de prévision." };8export const revalidate = 300;910interface CL { changelog: { version: string; date: string; title: string; notes: string[] }[]; runs: { id: number; modelVersion: string; completedAt: string | null; trigger: string | null; pollCount: number; codeCommit: string | null; published: boolean }[] }1112export default async function Page() {13 const d = await apiSafe<CL>("/api/changelog");14 if (!d) return <Empty title="Indisponible" />;15 return (16 <div className="space-y-10 max-w-3xl">17 <div><Link href="/methodologie" className="text-[12.5px] text-ink-3 hover:text-ink">← Méthodologie</Link><h1 className="display text-[40px] md:text-[56px] mt-3">Changelog</h1><p className="text-ink-2 mt-3 text-[15px]">La transparence est une caractéristique du produit : chaque changement de méthode est daté et expliqué ; chaque run est conservé.</p></div>18 <section><SectionHeader eyebrow="Versions du modèle" title="Changements de méthode" />19 <div className="space-y-3">{d.changelog.map((c) => (<Card key={c.version}><div className="flex items-center gap-3"><Badge tone="ink">v{c.version}</Badge><b>{c.title}</b><span className="text-ink-3 text-[12.5px] ml-auto num">{dateFr(c.date)}</span></div><ul className="list-disc pl-5 mt-3 space-y-1 text-[14px] text-ink-2">{c.notes.map((n, i) => <li key={i}>{n}</li>)}</ul></Card>))}</div>20 </section>21 <section><SectionHeader eyebrow="Runs" title="Derniers recalculs" description="Un run = un jeu de données arrêté, une graine, un commit." />22 <Card pad={false}><table className="data-table"><thead><tr><th>Run</th><th>Modèle</th><th>Terminé</th><th>Déclencheur</th><th className="r">Sondages</th><th>Commit</th><th></th></tr></thead><tbody>{d.runs.map((r) => <tr key={r.id}><td className="num">#{r.id}</td><td>{r.modelVersion}</td><td className="num">{dateTimeFr(r.completedAt)}</td><td className="text-ink-2 text-[12.5px]">{r.trigger}</td><td className="r num">{r.pollCount}</td><td className="mono text-[12px]">{r.codeCommit ?? "—"}</td><td>{r.published && <Badge tone="accent">publié</Badge>}</td></tr>)}</tbody></table></Card>23 </section>24 </div>25 );26}27