docs: add roadmap for CI + anchor aliases
All checks were successful
CI / build-and-anchors (push) Successful in 50s

This commit is contained in:
2026-01-23 13:41:10 +01:00
parent 12d73fc26e
commit 44974a676d

157
docs/ROADMAP.md Normal file
View File

@@ -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 daliases 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 linfra DNS bridge nest 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 dancrages **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 lancien `id` avant lélément ciblé
---
## 3) Prochains jalons (ordre recommandé)
### Jalons A — Verrouillage qualité (court terme, “béton”)
A1) CI : prouver linjection (pas seulement “build ok”)
- ajouter un test qui parcourt `src/anchors/anchor-aliases.json` et vérifie dans `dist/<route>/index.html` :
- présence de `<span id="oldId" ...>`
- 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 dattribut `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 lalias automatiquement
- si conflit : message clair “oldId déjà mappé / newId introuvable”
B2) `check-anchors.mjs` : suggestion daliases
- lorsquil 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/<route>/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 limage du job (Node 22)
### CI échoue “MODULE_NOT_FOUND scripts/...”
- fichier non commité
- `git status --porcelain` puis `git add/commit/push`
### Injection dalias 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 dIDs
4) Documentation à jour (baseline + décisions + procédures)
---
Fin.