Aller au contenu

Système de documentation (MkDocs)

Comment la doc est assemblée à partir de fichiers dispersés dans le monorepo, et comment l'arborescence de navigation est construite.


Pourquoi ce système

La doc est co-localisée avec le code : chaque module, contrôleur, ou composant peut maintenir son propre .md à côté de son source. Une seule règle : la doc vit là où vit le code qu'elle décrit, pour qu'elle reste à jour quand le code change.

MkDocs agrège ensuite ces fichiers éparpillés en un site statique unique.


Stack

Outil Rôle
MkDocs Material 9.5.49 Générateur + thème
awesome-pages 2.9.3 Navigation distribuée via fichiers .pages
macros 1.3.7 Variables (ex: URL GitHub) injectées dans le markdown
scripts/sync_docs.py Aggrégateur incrémental des .md dispersés vers .docs-build/
Dockerfile.docs Runtime reproductible (squidfunk/mkdocs-material, stdlib Python uniquement)

Le tout est piloté par mkdocs.yml à la racine.


Flux de build

projects/api/src/**/*.md       ─┐
projects/front-mobile-app/**.md ├─▶ sync_docs.py ─▶ .docs-build/ ─▶ mkdocs ─▶ site/
projects/front-app/**/*.md     ─┤                  (miroir filtré)
docs/**/*.md, .cursor/**       ─┘

1. sync_docs.py — agrégation

Lancé automatiquement par Dockerfile.docs avant chaque mkdocs serve / mkdocs build. Il fait trois choses :

  1. Copie intégrale de /docs/ vers .docs-build/ (doc transverse), et transforme le Readme.md du monorepo en index.md (page d'accueil).
  2. Miroir filtré des sub-projets (projects/api/, projects/front-mobile-app/, projects/front-app/) en ne conservant que :
    • *.md (sauf CHANGELOG.md, LICENSE.md, *.test.md, et le README.md à la racine du sub-projet)
    • .pages (fichiers de navigation)
    • Assets visuels : *.png, *.svg, *.jpg, *.jpeg, *.gif, *.webp
  3. Délègue les docs d'agents (rules, skills, commandes de .cursor/ & co) à scripts/sync-agents-docs.py, qui les transforme vers .docs-build/agents/.

Tout le reste (.ts, .json, node_modules/, dist/, etc.) est exclu, et les dossiers vides sont supprimés.

Résultat : .docs-build/ est un miroir filtré du repo, qui ne contient que de la doc — sans code source. Le dossier est gitignoré et mis à jour incrémentalement : seuls les fichiers réellement modifiés sont réécrits, les orphelins supprimés. C'est ce qui permet à mkdocs serve (qui surveille .docs-build/ par polling) de ne rebuilder que sur de vrais changements.

2. mkdocs build — rendu

mkdocs.yml pointe docs_dir: .docs-build, donc MkDocs voit uniquement le miroir filtré (pas le repo entier). Il génère le site HTML dans site/.

strict: true fait échouer le build sur toute référence cassée (lien mort, ancre invalide, fichier manquant). Pas de doc à moitié cassée en production.


Construction de l'arborescence (awesome-pages)

Sans aucun fichier .pages, MkDocs produirait une nav alphabétique basée sur les noms de fichiers/dossiers. Pour reprendre le contrôle, on utilise awesome-pages : chaque dossier peut contenir un fichier .pages qui surcharge le comportement par défaut.

Forme d'un .pages

title: Général                          # Renomme le dossier dans la nav
nav:
  - "Bricks Intel": bricks-intel-presentation.md
  - "Doppler": doppler-environment-variables.md
  - ...                                 # `...` insère ici tout ce qui n'est pas listé
  - hidden-page.md                      # Listé : visible. Absent + pas de `...` : caché

Trois leviers principaux :

Clé Effet
title: Renomme le dossier dans la nav (ex: general/ → "Général")
nav: avec entrées explicites Définit l'ordre exact. "Label": fichier.md permet aussi de renommer une page.
... dans nav: Glob pour "tout le reste, ordre par défaut" — utile pour mixer ordre figé + auto-discovery

L'absence de nav: = ordre alphabétique avec titres dérivés du H1 de chaque .md (ou du nom de fichier en fallback).

Exemple : la nav racine

/docs/.pages :

nav:
  - "Accueil": index.md
  - general
  - postmortems
  - agents
  - api
  - mobile
  - web

Cette racine référence des dossiers (api, mobile, web) qui n'existent pas dans /docs/ — ils sont matérialisés par sync_docs.py quand il copie projects/api/.docs-build/api/, etc. Chaque sous-arbre porte ses propres .pages.

Cascade

awesome-pages descend récursivement. Pour customiser la nav d'un module API précis, il suffit d'ajouter un .pages à côté de ses .md :

projects/api/src/modules/auth/
├── auth.controller.ts
├── auth.module.ts
├── docs/
│   ├── .pages          ← nav locale du module auth
│   ├── overview.md
│   └── flows.md

Aucune config centrale à modifier, aucun import à ajouter — le fichier est ramassé par sync_docs.py puis interprété par awesome-pages.


Ajouter une page / lancer en local

Voir Contribuer à la doc pour le mode d'emploi côté contributeur (où poser le .md, comment lancer le hot-reload).

Hot-reload : en mode serve, une boucle re-synchronise les sources toutes les 3 s (sync_docs.py --loop), et mkdocs serve surveille .docs-build/ par polling. Modifier, créer ou supprimer un .md (y compris une rule/skill .cursor/) est visible dans le navigateur en moins de ~10 s, rebuild MkDocs compris — sans relancer le conteneur.


CI

Le workflow .github/workflows/docs-validate.yml lance mkdocs build --strict via Dockerfile.docs sur chaque push (hors branche develop) lorsqu'un fichier doc ou sa config change (.md, .mdc, .pages, mkdocs.yml, scripts/sync_docs.py, etc.).

En local, équivalent : pnpm build:docs.


Déploiement

mkdocs build produit site/ (statique), consommé par le pipeline Cloudflare Pages (BRI-682).


Références

  • Plugin awesome-pages — syntaxe complète des .pages
  • MkDocs Material — features du thème (admonitions, code blocks, mermaid, tabs)
  • mkdocs.yml — config racine (plugins, theme, extensions markdown)
  • scripts/sync_docs.py — règles d'inclusion/exclusion