diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..45bb945 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,157 @@ +# ROADMAP — CI (Gitea Actions Synology) + Ancrages (aliases build-time) + +But : permettre à un successeur de reprendre sans rien deviner. +Ce document décrit : +- l’état stable actuel (baseline) +- les invariants à ne pas casser +- les prochaines étapes “mission principale” (ancrages primaires robustes + CI durable) +- la méthode de debug rapide + +--- + +## 0) État actuel (baseline VALIDÉE) + +### CI (Gitea Actions) +- ✅ Job dans un container Node 22 (conforme `engines`) +- ✅ Checkout **sans actions GitHub**, depuis `workflow/event.json` +- ✅ Zéro `apt-get` dans le workflow +- ✅ `npm ci` + build + tests anchors + validation schema aliases +- ✅ Injection d’aliases au postbuild confirmée en logs + +### Runner (DS220+) +- ✅ `container.network: host` dans `/data/config.yaml` du runner +- ✅ `NODE_OPTIONS=--dns-result-order=ipv4first` passé aux containers de job +- ✅ `--add-host=gitea.archicratie.trans-hands.synology.me:192.168.1.20` + +Raison : le DNS du bridge Docker (127.0.0.11) est instable sur cette infra → EAI_AGAIN / ESERVFAIL (npm, debian). + +Référence : `docs/CI-BASELINE.md` + `docs/CI-WORKFLOW.md` + `docs/HANDOFF-SESSION.md`. + +--- + +## 1) Invariants (NE PAS “optimiser”) + +Ces points sont des garde-fous. Si on les retire, on revient aux mêmes pannes. + +1) Runner : +- garder `container.network: host` (tant que l’infra DNS bridge n’est pas corrigée) +- garder `-e NODE_OPTIONS=--dns-result-order=ipv4first` + +2) Workflow : +- ne pas réintroduire `apt-get` +- ne pas dépendre de `actions/checkout@...` +- garder un container Node 22 tant que `package.json engines` impose `>=22 <23` + +3) Ancrages : +- le fichier canonique : `src/anchors/anchor-aliases.json` +- injection build-time : `scripts/inject-anchor-aliases.mjs` +- test anchors : `scripts/check-anchors.mjs` +- validation schema aliases : `scripts/check-anchor-aliases.mjs` + +--- + +## 2) Mission principale (raccrochage) + +Objectif “métier” : +- préserver les liens profonds (ancrages) malgré l’édition (déplacements, insertions, corrections) +- éviter les résolutions “par index” (fragiles) +- rendre la migration d’ancrages **déterministe, versionnée, testée** + +Traduction technique : +- quand un `newId` remplace un `oldId`, on versionne `oldId -> newId` **par page** +- au build, on injecte un alias DOM invisible portant l’ancien `id` avant l’élément ciblé + +--- + +## 3) Prochains jalons (ordre recommandé) + +### Jalons A — Verrouillage qualité (court terme, “béton”) +A1) CI : prouver l’injection (pas seulement “build ok”) +- ajouter un test qui parcourt `src/anchors/anchor-aliases.json` et vérifie dans `dist//index.html` : + - présence de `` + - présence de l’élément `id="newId"` + - et idéalement : alias placé “juste avant” la cible (proximité) + +A2) CI : interdire les IDs en double (risque SEO/DOM) +- dans les pages `dist`, détecter les doublons d’attribut `id="..."` + +A3) CI : artefacts / logs actionnables +- quand un test échoue : afficher `route`, `oldId`, `newId`, extrait HTML et ligne + +### Jalons B — Ergonomie éditeur (moyen terme) +B1) `apply-ticket.mjs` : renforcer le mode `--alias` +- si un paragraphe est remplacé : écrire l’alias automatiquement +- si conflit : message clair “oldId déjà mappé / newId introuvable” + +B2) `check-anchors.mjs` : suggestion d’aliases +- lorsqu’il détecte “removed X / added Y” avec même préfixe `p-8-...` +- générer une proposition, option `--write-aliases` (ou sortie patch) + +### Jalons C — Robustesse long terme (ops) +C1) Runner : réduire le risque “host network” +- isoler le runner sur LAN (réseau dédié/pare-feu) +- limiter les labels/queues aux repos nécessaires +- documenter comment restaurer `/data/config.yaml` + +C2) Versionner les décisions +- tout changement CI/runner : documenté dans `docs/` + commit (pas de “magic fix” non tracé) + +--- + +## 4) Procédure standard (dev -> PR -> merge) + +### Ajouter/modifier du contenu +1) modifier les sources (docx/import etc.) +2) si des IDs de paragraphes changent : + - appliquer `scripts/apply-ticket.mjs --alias` si possible + - sinon éditer `src/anchors/anchor-aliases.json` (par route) + +### Vérifier en local +- `npm test` +- ou au minimum : + - `npm run build` + - vérifier injection : `grep -n "para-alias" dist//index.html` + +### PR & merge +- une PR = un ticket logique +- CI doit passer +- merge seulement quand anchors + aliases sont cohérents + +--- + +## 5) Debug express (quand ça casse) + +### CI échoue “DNS / npm” +Symptômes typiques : +- `EAI_AGAIN`, `ESERVFAIL`, `Temporary failure resolving` +Actions : +1) vérifier runner config : `/data/config.yaml` contient bien `network: host` +2) vérifier job container : logs montrent `network="host"` +3) smoke test NAS : + - `docker run --rm --network host mcr.microsoft.com/devcontainers/javascript-node:22-bookworm bash -lc "npm ping --registry=https://registry.npmjs.org"` + +### CI échoue “EBADENGINE” +- Node pas 22 → corriger l’image du job (Node 22) + +### CI échoue “MODULE_NOT_FOUND scripts/...” +- fichier non commité +- `git status --porcelain` puis `git add/commit/push` + +### Injection d’alias absente +- vérifier que `postbuild` appelle bien `inject-anchor-aliases.mjs` +- vérifier que `src/anchors/anchor-aliases.json` respecte le schéma (par route) + +--- + +## 6) Définition de “DONE” (quand on peut dire “mission accomplie”) + +1) CI stable sur 30+ runs consécutifs (push + PR + merge) +2) Toute modification de paragraphes qui casse des anchors produit : + - soit un alias automatique via tooling + - soit un échec CI explicite (avec patch proposé) +3) Aliases injectés testés (preuve dans dist) + pas de doublons d’IDs +4) Documentation à jour (baseline + décisions + procédures) + +--- + +Fin.