Patrick Schurig 95a9edda5a fix(rgpd): polices auto-hébergées — la doc ne transmet plus l'IP du visiteur à Google
`theme.font: {text, code}` faisait injecter par Material, dans le <head> de
chacune des 316 pages, un preconnect vers fonts.gstatic.com et une feuille
depuis fonts.googleapis.com (Sans 300/300i/400/400i/700/700i + Mono
400/400i/700/700i). Chaque visite transmettait donc l'IP du visiteur à Google
AVANT tout consentement.

Ce qui rendait ça gênant n'est pas la règle en soi, c'est l'asymétrie : le site
vitrine a fait exactement l'inverse en T10, délibérément, pour cette raison
(jurisprudence LG München 2022, doctrine CNIL) et pour ne pas contredire « vos
données ne sortent pas de chez vous ». La doc affichait donc le contraire de
l'engagement que le produit met en avant, sur le même nom de domaine.

Correctif : `theme.font: false` retire les deux balises ; les 16 woff2 viennent
du dépôt du site — mêmes fichiers, mêmes unicode-range (latin + latin-ext pour
les accents), déjà éprouvés en production depuis juin. Les 16 blocs @font-face
sont repris tels quels plutôt que réécrits, avec les chemins adaptés. Material
lit `--md-text-font` / `--md-code-font`, qu'extra.css définit.

312 Ko d'actifs, servis localement.

⚠️ LES ITALIQUES SONT DÉSORMAIS SYNTHÉTISÉES, et c'est la contrepartie à
connaître. Google servait 4 fontes italiques que nous n'avons pas (aucun fichier
italique dans le dépôt du site, aucune IBM Plex installée sur la machine de
build) : le navigateur incline donc la romaine. Visible sur les intertitres en
italique des blocs générés — `_Einstellungen:_`, `_Gemessene Größen:_`. Pour y
remédier : récupérer les woff2 italiques depuis le dépôt officiel IBM/plex (OFL)
et ajouter les @font-face correspondants. La méthode est celle déjà documentée
au T10 du site, et je ne l'ai pas prise d'office — c'est un ajout de binaires
depuis Internet.

Vérifié sur le site construit, et pas seulement sur le <head> :
  · 0 url() externe dans toute la CSS
  · 0 preconnect
  · 0 ressource (link/script/img/iframe) chargée depuis un tiers — le seul hôte
    cité est docs.etm-powersync.fr lui-même, par les <link rel="canonical">
  · les 16 woff2 présents dans le build, 16 références, 0 chemin cassé
  · build --strict sans avertissement

La seule mention restante de Google dans le dépôt est le commentaire d'extra.css
qui explique pourquoi elle n'y est plus.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-13 09:14:26 +02:00
2026-06-06 09:51:43 +02:00
2026-05-28 17:26:17 +02:00

powersync-docs

Documentation ETM PowerSync — 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

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.
  • 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

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

# 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

⚠️ 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 → génération appareils → génération API → 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.

Description
Documentaion etm-powersync
Readme 1 MiB
Languages
Python 100%