Nouvelle étape : clone --depth 1 de la branche par défaut du moteur (même jeton, branche lue par l'API Gitea, comme pour les plugins) dans .engine-src/ ; un échec de clone fait échouer le build, faute de quoi la référence serait générée sans source. Génération avant mkdocs build, --check avec les autres contrôles d'idempotence. README : ligne du tableau des générateurs, commandes locales, pipeline, et la règle de langue de ce bloc (cadre anglais, descriptions du contrat en français, non traduites). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
6.5 KiB
Markdown
121 lines
6.5 KiB
Markdown
# powersync-docs
|
|
|
|
Documentation ETM PowerSync — [docs.etm-powersync.fr](https://docs.etm-powersync.fr)
|
|
|
|
MkDocs Material, **docs-as-code**, trois langues : `fr` (défaut) · `de` · `en`.
|
|
Licence : CC-BY-4.0 pour la documentation, GPL-3.0 pour les exemples de code.
|
|
|
|
---
|
|
|
|
## La règle qui explique tout le reste
|
|
|
|
**95 % du volume est GÉNÉRÉ, pas rédigé.** Mesure du 2026-10-12 : 74 013 mots générés
|
|
contre 3 506 mots de prose, sur 107 pages. Tout ce qui est entre
|
|
|
|
```
|
|
<!-- BEGIN GENERATED: <clé> --> … <!-- END GENERATED -->
|
|
```
|
|
|
|
est produit par un script depuis une source de vérité, et **écrasé à chaque passage**.
|
|
Éditer à l'intérieur de ces marqueurs, c'est écrire quelque chose qui disparaîtra.
|
|
|
|
| Générateur | Source de vérité | Produit |
|
|
|---|---|---|
|
|
| `scripts/gen_device_reference.py` | `PORTING_STATUS.yaml` + les `integrationplugin*.json` et `meta.json` des 5 dépôts de plugins | fiches appareils, index de catégorie, matrice de compatibilité, `appareils/SUMMARY.md` |
|
|
| `scripts/gen_api_reference.py` | `introspect.json` (introspection nymea) | référence JSON-RPC (23 pages), `api/SUMMARY.md` |
|
|
| `scripts/gen_optimizer_reference.py` | `docs/etm-powersync-optimizer-protocol.openrpc.json` du moteur (`etm-powersync-energy-plugin-etm`, branche par défaut) | tableaux de messages, listes fermées, règles nommées et machine de repli de `optimiseur/protocole*.md`, fiche de `optimiseur/contrat*.md`, copie servie du contrat ; garde-fou de contenu (IP privées, « cloud », « Héos ») |
|
|
|
|
## Multi-langue — où passe la frontière
|
|
|
|
Deux régimes, et ils ne se traitent pas pareil :
|
|
|
|
- **Le bloc de référence est en ANGLAIS, une seule fois, servi identique dans les trois
|
|
langues.** Décision du 2026-10-12. La raison est une mesure, pas un goût : nymea ne sert
|
|
**aucune** traduction sur notre parc — vérifié sur le banc `hems`, où
|
|
`Integrations.GetThingClasses` rend la **même charge utile au sha256 près** (243 340 octets)
|
|
pour `fr_FR`, `de_DE` et `en_US`. Les noms de modèles, de registres et d'unités sont donc
|
|
déjà en anglais ; traduire les seuls en-têtes de colonnes autour aurait fabriqué des pages
|
|
bilingues sans rien gagner. Le vocabulaire vit dans le dict `REF` de chaque générateur.
|
|
**Cas particulier, la référence optimiseur** (2026-10-18) : le cadre est en anglais
|
|
comme partout, mais les descriptions viennent du contrat du moteur, écrit en
|
|
français. Les traduire ici ferait une seconde vérité : elles sont reprises telles
|
|
quelles, et l'en-tête de colonne le dit (« from the contract, French »).
|
|
- **La prose et la navigation se TRADUISENT.** Fichiers suffixés (`page.md` = fr,
|
|
`page.de.md`, `page.en.md`), libellés de nav par `nav_translations` dans `mkdocs.yml`,
|
|
échafaudage des pages créées par le dict `SCAFFOLD` du générateur appareils.
|
|
|
|
> **Pourquoi `SCAFFOLD` existe.** Sans lui, chaque nouvel appareil ajouté créerait sa fiche
|
|
> dans la seule langue par défaut, et `fallback_to_default` la servirait **en français** sous
|
|
> `/de/` et `/en/`. Le générateur crée donc les trois variantes — et **ne réécrit jamais** une
|
|
> page existante, pour que la prose traduite à la main survive aux régénérations.
|
|
|
|
### Localisation ≠ traduction
|
|
|
|
`docs/tarifs.md` est l'exemple à connaître : la version FR parle de Tempo et du signal RTE,
|
|
la DE de `§14a EnWG` et de SMARD, l'EN des deux. Ce ne sont **pas** des traductions l'une de
|
|
l'autre, et c'est volontaire — les signaux tarifaires sont nationaux. Même traitement pour la
|
|
ligne correspondante de `docs/fonctionnalites/index.md`.
|
|
|
|
---
|
|
|
|
## Travailler dessus
|
|
|
|
```bash
|
|
python3 -m venv .venv && . .venv/bin/activate
|
|
pip install -r requirements.txt
|
|
|
|
# Prévisualiser (les trois langues sont construites ensemble)
|
|
mkdocs serve
|
|
|
|
# Régénérer la référence appareils — exige les JSON des 5 dépôts de plugins
|
|
# dans .plugins-src/ (la CI les clone ; en local, copiez-les depuis le workspace)
|
|
python3 scripts/gen_device_reference.py --src .plugins-src --docs docs \
|
|
--lang fr --locales fr,de,en
|
|
|
|
# Régénérer la référence API
|
|
python3 scripts/gen_api_reference.py --src introspect.json --docs docs
|
|
|
|
# Régénérer la référence du protocole optimiseur — exige le contrat OpenRPC du moteur
|
|
# (la CI clone le moteur dans .engine-src/ ; en local, --src accepte le clone,
|
|
# un dossier qui contient le fichier, ou le fichier lui-même)
|
|
python3 scripts/gen_optimizer_reference.py --src .engine-src/etm-powersync-energy-plugin-etm --docs docs
|
|
|
|
# Ce que vérifie la CI : rien ne doit changer après régénération
|
|
mkdocs build --strict
|
|
python3 scripts/gen_device_reference.py --src .plugins-src --docs docs \
|
|
--lang fr --locales fr,de,en --check
|
|
python3 scripts/gen_optimizer_reference.py --src .engine-src/etm-powersync-energy-plugin-etm \
|
|
--docs docs --check
|
|
```
|
|
|
|
### Le sélecteur de langue
|
|
|
|
Material affiche son icône `translate` — l'idéogramme 文 collé à un A. Elle dit
|
|
« traduire », pas « vous êtes en français », et à la taille du bandeau on y voit un
|
|
symbole asiatique plutôt qu'une langue. Depuis le 2026-10-15, `stylesheets/extra.css`
|
|
la masque et affiche à la place **le drapeau de la langue courante plus son code**,
|
|
comme sur etm-powersync.fr. La langue courante est aussi mise en évidence dans la
|
|
liste déroulante, où les trois lignes étaient jusque-là identiques.
|
|
|
|
Le drapeau se choisit sur `html[lang]`, que `mkdocs-static-i18n` pose déjà par locale.
|
|
**Aucun gabarit du thème n'est surchargé** — rien à reprendre à chaque mise à jour de
|
|
Material. Les drapeaux sont des SVG en `data:` (les emojis drapeaux ne se rendent pas
|
|
sous Windows) et le `aria-label` du bouton est inchangé : c'est lui qui porte le sens
|
|
pour les lecteurs d'écran, le code « FR » du `::after` restant décoratif.
|
|
|
|
⚠️ `mkdocs build --strict` **échoue sur un simple avertissement**. C'est pour cela que
|
|
`navigation.instant` est retiré de `theme.features` : il est incompatible avec le lien
|
|
contextuel du sélecteur de langue de `mkdocs-static-i18n`. Le commentaire est dans
|
|
`mkdocs.yml`, à l'endroit du retrait.
|
|
|
|
## Déploiement
|
|
|
|
CI Gitea (`.gitea/workflows/docs.yml`) sur push vers `main`, plus un passage nocturne à 3 h
|
|
(les `meta.json` des dépôts de plugins bougent sans que ce dépôt-ci bouge). Pipeline :
|
|
clone des 5 dépôts de plugins et du moteur → génération appareils → génération API →
|
|
génération optimiseur → `mkdocs build --strict` → contrôle d'idempotence → `rsync` vers
|
|
le serveur.
|
|
|
|
Le build produit `site/` (fr), `site/de/` et `site/en/` en une passe ; le `rsync --delete`
|
|
pousse l'ensemble.
|