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.
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_LANGau démarrage via@Value - Frontend React — utilise
VITE_LANG(alias injecté parenv-inject.shau runtime dans l'image Docker) - chaos-admin / monitoring —
config.jsexposewindow.__CONFIG__.LANG, lu pari18n.js - welcome — le script
entrypoint.shlitPERFSHOP_LANGet injecte le dictionnaire danswelcome.jsen 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}.jsonmonitoring/public/i18n/{fr,en}.jsonscripts-ui/public/i18n/{fr,en}.jsonjmeter-ui/public/i18n/{fr,en}.jsonwelcome/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 :
- Backend — créer
messages_<lang>.propertiesen copiantmessages_fr.propertieset en traduisant les valeurs - Frontend — créer
frontend/src/i18n/<lang>.json, l'importer dansI18nContext.jsxet l'ajouter au dictionnaire - Outils annexes — créer
public/i18n/<lang>.jsonpour chaque outil (chaos-admin, monitoring, scripts-ui, jmeter-ui, welcome) - Énigmes pédagogiques — créer
i18n/enigmes/bacN/enigmes_<lang>.jsonpour chaque niveau, plusi18n/logique/logique_<lang>.json - Documentation MkDocs — le plugin
mkdocs-static-i18nest 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.sh → window.__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 dansen.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()oudata-i18nselon 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