# Clone complet du contenu specification.website (pages internes, pas de redirection)

**Date :** 2026-06-11 · **Epic :** ELEVA-93 (sous-projet A enrichi). Demande : « copier toutes les pages de specification.website chez nous, on ne redirige pas ».

## Objectif
Héberger **le contenu complet** des 135 topics de specification.website dans l'app (corps markdown détaillé : what/why/how-to/common-mistakes/verification + sources + related), avec des **pages internes**. Le lien « guide » de la checklist pointe vers **nos** pages, plus vers le site externe. Contenu **statique committé**, aucun appel externe au runtime.

## Source
Chaque topic expose son markdown brut en `.md` (public) : `https://specification.website/spec/<category>/<slug>.md` (frontmatter YAML : title, slug, category, status, url, sources[], relatedSlugs[] + corps). Vérifié : fetch HTTP 200, ~6 Ko/page. Les 135 (id `category/slug`) sont déjà dans `CHECKLIST` (`src/lib/spec/checklist-data.ts`, champ `url`).

## Génération — `scripts/generate-spec-content.ts`
- Itère les items de `CHECKLIST`, dérive l'URL `.md` (`item.url` sans `/` final + `.md`).
- Fetch chaque page (concurrence bornée ~5, politesse ; skip si le fichier local existe déjà sauf `--force`).
- Écrit chaque corps dans `src/content/spec/<category>/<slug>.md` (markdown brut **avec** son frontmatter, committé).
- Idempotent, re-runnable (sous-projet A : re-sync périodique).
- Lancer une fois pour peupler les 135 fichiers (committer le contenu).

## Rendu — route interne
`src/app/(app)/flight-checker/spec/[category]/[slug]/page.tsx` (Server Component) :
- `generateStaticParams` depuis les 135 items → pages statiques.
- Lit le `.md` local, parse le frontmatter (petit parseur maison ou `gray-matter` si déjà présent ; sinon split `---`), rend : fil d'ariane (Checklist › catégorie › titre), titre, badge statut (required/recommended/optional/avoid, mêmes couleurs que la checklist), résumé, **corps markdown rendu** (réutiliser un renderer existant — chercher `react-markdown`/`marked`/`markdown-it` dans package.json ; sinon `sfw bun add react-markdown remark-gfm`, RSC-compatible), bloc « Sources » (liens externes en référence — autorisé, ce sont les sources citées, pas le contenu), bloc « Voir aussi » (relatedSlugs → liens **internes** vers nos pages).
- `notFound()` si slug inconnu. Largeur de lecture contrainte (prose, ~70ch), thème clair+dark via tokens.

## Repointage des liens
- `checklist.tsx` : le lien « guide » de chaque item passe de `item.url` (externe) à la route interne `/flight-checker/spec/<category>/<slug>` (target interne, navigation Next). On ne redirige plus vers specification.website.
- Les `SpecItem.url` (externe) restent dans les données comme référence/source, mais l'UI lie en interne.

## Tests
- Script : test unitaire de la dérivation d'URL `.md` + du parsing frontmatter (sans réseau ; fixture).
- Route : `generateStaticParams` retourne 135 entrées ; une page rend titre+corps pour un slug fixture (fichier .md de test) ; slug inconnu → notFound.
- Pas de test réseau (le fetch est offline, au moment de la génération).

## Notes
- Attribution : garder la mention de source (specification.website) en pied de page interne — c'est leur contenu, on le clone avec attribution.
- Le `.md` committé = ~135 fichiers × ~6 Ko ≈ 800 Ko de contenu statique. Acceptable.
- Plus tard (sous-projet A) : cron/re-run du script pour rester à jour.
