Aller au contenu

Vue d'ensemble de l'internationalisation

PerfShop est conçu pour être multilingue dès la racine. Deux langues sont actuellement fournies (français et anglais) et la documentation MkDocs est configurée pour cinq langues (français, anglais, espagnol, allemand, italien). L'ajout d'une nouvelle langue ne nécessite aucune modification de code — c'est une conséquence directe du design des dictionnaires.

Cette page décrit la stratégie globale. Les pages suivantes détaillent chaque sous-système : backend Spring, frontend React, énigmes pédagogiques et outils annexes.

Langues supportées

Langue Code État Dictionnaires
Français fr ✅ Langue source, complète Backend + Frontend + chaos-admin + scripts-ui + jmeter-ui + monitoring + welcome + enigmes BAC1-BAC5 + logique
Anglais en ✅ Traduction complète Backend + Frontend + chaos-admin + scripts-ui + jmeter-ui + monitoring + welcome + enigmes BAC1-BAC5 + logique
Espagnol es ⏳ Prévu
Allemand de ⏳ Prévu
Italien it ⏳ Prévu

La documentation MkDocs est déjà configurée pour les cinq langues via le plugin mkdocs-static-i18n. Les traductions FR/EN sont prioritaires ; les trois autres langues seront ajoutées au fur et à mesure.

Le français est la langue source — tous les textes sont d'abord écrits en français, puis traduits. En cas d'incohérence ou de clé manquante, les dictionnaires français servent de fallback.

Variable unique : PERFSHOP_LANG

PerfShop n'utilise pas l'en-tête HTTP Accept-Language. Toutes les interfaces respectent une seule variable d'environnement commune : PERFSHOP_LANG.

PERFSHOP_LANG=fr   # ou en, es, de, it

Pourquoi pas Accept-Language ?

Plusieurs raisons concrètes :

  • Cohérence pédagogique — en salle de classe, tous les étudiants doivent voir la même interface dans la même langue pour que les instructions du formateur soient compréhensibles par tout le monde. Si chaque étudiant avait la langue de son navigateur, l'instructeur francophone se retrouverait à désigner un bouton qui s'affiche différemment sur certains postes.
  • Reproductibilité des tests — un script JMeter ou Selenium écrit contre un libellé français doit continuer à fonctionner quelle que soit la langue du navigateur qui exécute la requête. En figeant la langue au déploiement, on élimine toute dérive.
  • Simplicité du code — une seule variable, résolue au démarrage, propagée à tous les composants. Pas de négociation de contenu, pas de middleware de détection, pas de fallback runtime par header.
  • Rejeu des logs — si le backend log des messages d'erreur, ils sont toujours dans la même langue. Un log d'erreur en français sur un poste et en anglais sur un autre serait une source de confusion.

Propagation

La variable est définie au niveau du fichier .env de la stack et propagée à chaque service via Docker Compose :

flowchart TD
  Env[.env<br/>PERFSHOP_LANG=fr]
  Env --> BA[perfshop-app<br/>I18nService]
  Env --> FE[perfshop-frontend<br/>VITE_LANG injecté]
  Env --> CA[perfshop-chaos-admin<br/>window.__CONFIG__.LANG]
  Env --> MO[perfshop-monitoring<br/>window.__CONFIG__.LANG]
  Env --> WE[perfshop-welcome<br/>entrypoint.sh → i18n/<lang>.json]
  Env --> SC[perfshop-scripts-ui<br/>public/i18n/<lang>.json]
  Env --> JM[perfshop-jmeter-ui<br/>public/i18n/<lang>.json]

Le mécanisme de propagation diffère selon le composant :

  • Backend Spring Boot — lit PERFSHOP_LANG au démarrage via @Value
  • Frontend React — utilise VITE_LANG (alias injecté par env-inject.sh au runtime dans l'image Docker)
  • chaos-admin / monitoringconfig.js expose window.__CONFIG__.LANG, lu par i18n.js
  • welcome — le script entrypoint.sh lit PERFSHOP_LANG et injecte le dictionnaire dans welcome.js en tête du fichier
  • scripts-ui / jmeter-ui — même pattern que chaos-admin

Toutes ces voies convergent vers une même valeur effective. Un déploiement avec PERFSHOP_LANG=en affichera toute la stack en anglais, sans exception.

Quatre familles de dictionnaires

PerfShop maintient quatre familles de dictionnaires :

1. Backend Spring — messages_*.properties

Emplacement : backend/src/main/resources/messages_fr.properties et messages_en.properties.

Environ 430 clés. Format clé=valeur style Java Properties. Utilisées par I18nService pour les messages d'erreur API, les logs utilisateur, les labels retournés dans les payloads JSON. Voir Internationalisation backend.

2. Frontend React — src/i18n/*.json

Emplacement : frontend/src/i18n/fr.json et en.json.

Environ 400 clés. Format JSON plat. Consommées par I18nContext.jsx et le hook useT(). Voir Internationalisation frontend.

3. Outils annexes — public/i18n/*.json

Emplacements :

  • chaos-admin/public/i18n/{fr,en}.json
  • monitoring/public/i18n/{fr,en}.json
  • scripts-ui/public/i18n/{fr,en}.json
  • jmeter-ui/public/i18n/{fr,en}.json
  • welcome/i18n/{fr,en}.json

Format JSON plat, chargés en async par le loader i18n.js commun ou par entrypoint.sh pour welcome. Voir Internationalisation outils annexes.

4. Contenu pédagogique — i18n/enigmes/ et i18n/logique/

Emplacement : backend/src/main/resources/i18n/enigmes/bac1/ à bac5/, et backend/src/main/resources/i18n/logique/.

Un JSON par niveau et par langue. Contient les énoncés des énigmes, les indices, les messages de succès / d'échec. Les réponses sont universelles (numériques ou chaînes fixes) et ne changent pas entre langues. Voir Internationalisation des énigmes.

Symétrie FR/EN

La règle absolue : si une clé existe en français, elle doit exister en anglais (et réciproquement). Cette symétrie est vérifiée manuellement lors de chaque mise à jour et est assurée par des audits « 3 amigos » à chaque commit significatif.

Au moment de cette rédaction, la symétrie FR/EN est totale sur les quatre familles de dictionnaires.

Les clés manquantes provoquent des fallbacks vers le français (pour le backend et le frontend) ou l'affichage de la clé brute (pour les outils annexes et welcome). Aucun message de production ne doit jamais afficher une clé brute à l'utilisateur final.

Ajouter une nouvelle langue

Le processus est le même pour chaque famille de dictionnaires — et il se fait sans modification de code :

  1. Backend — créer messages_<lang>.properties en copiant messages_fr.properties et en traduisant les valeurs
  2. Frontend — créer frontend/src/i18n/<lang>.json, l'importer dans I18nContext.jsx et l'ajouter au dictionnaire
  3. Outils annexes — créer public/i18n/<lang>.json pour chaque outil (chaos-admin, monitoring, scripts-ui, jmeter-ui, welcome)
  4. Énigmes pédagogiques — créer i18n/enigmes/bacN/enigmes_<lang>.json pour chaque niveau, plus i18n/logique/logique_<lang>.json
  5. Documentation MkDocs — le plugin mkdocs-static-i18n est déjà configuré pour 5 langues ; il suffit de créer les fichiers .<lang>.md à côté des fichiers français

Et voilà — déployer avec PERFSHOP_LANG=<lang> suffit. Aucun rebuild d'image, aucun redémarrage, aucun changement de code Java ou JavaScript.

Tableau récapitulatif

Composant Fichiers i18n Nombre de clés (approximatif) Loader
Backend Spring messages_{fr,en}.properties ~430 I18nService
Frontend React src/i18n/{fr,en}.json ~400 I18nContext.jsx + hook useT()
chaos-admin public/i18n/{fr,en}.json ~400 js/i18n.js (vanilla async)
monitoring public/i18n/{fr,en}.json ~150 idem
scripts-ui public/i18n/{fr,en}.json ~200 idem
jmeter-ui public/i18n/{fr,en}.json ~180 idem
welcome i18n/{fr,en}.json ~30 entrypoint.shwindow.__I18N__
Énigmes BAC1 i18n/enigmes/bac1/enigmes_{fr,en}.json ~200 clés par langue PedagogiqueEnigme.loadTranslations()
Énigmes BAC2 i18n/enigmes/bac2/enigmes_{fr,en}.json ~200 idem
Énigmes BAC3 i18n/enigmes/bac3/enigmes_{fr,en}.json ~200 idem
Énigmes BAC4 i18n/enigmes/bac4/enigmes_{fr,en}.json ~200 idem
Énigmes BAC5 i18n/enigmes/bac5/enigmes_{fr,en}.json ~200 idem
Logique i18n/logique/logique_{fr,en}.json 25 questions par langue ThemeLogique

Le volume total dépasse 2 500 clés par langue. Cela représente un investissement significatif mais rend PerfShop réellement utilisable par des formations non francophones.

Bonnes pratiques

  • Toujours traduire en paire — quand vous ajoutez une clé dans fr.json, ajoutez-la simultanément dans en.json (et réciproquement)
  • Noms de clé en anglais — les clés sont toujours en anglais : admin.login.success, error.payment.failed. Les valeurs sont dans la langue cible. Cette convention facilite la recherche et la maintenance quand on collabore avec des développeurs non-francophones.
  • Éviter les clés en dur dans les templates — passer systématiquement par t(), _t() ou data-i18n selon le contexte
  • Audit de symétrie avant chaque release — un script simple qui compare les ensembles de clés FR et EN suffit à détecter toute dérive