Page chaos étudiant¶
La page chaos étudiant (chaos-admin/public/index.html) est l'interface que les étudiants utilisent pour activer eux-mêmes les chaos et suivre leur parcours pédagogique. Elle est servie par le conteneur perfshop-chaos-admin mais exposée à une URL dédiée (PUBLIC_CHAOS_URL, par défaut port 3003). Contrairement au panneau formateur, elle ne nécessite aucune authentification : un étudiant y accède librement depuis son poste.
Sources
chaos-admin/public/index.html, chaos-admin/public/student/student-main.js, student-tabs.js, student-performance.js, student-pedagogique.js, student-scenarios.js
Architecture¶
La page étudiant est une application vanilla HTML/CSS/JS — aucun framework, aucun bundler. Les scripts sont chargés en balises <script> ordonnées dans index.html et communiquent par variables globales protégées (typeof X === 'undefined').
public/
├── index.html ← page principale, 6 onglets
├── js/i18n.js ← loader i18n async (commun admin + student)
├── i18n/{fr,en}.json ← dictionnaires
└── student/
├── student.css
├── student-tabs.css
├── student-performance.css
├── student-main.js ← bootstrap, polling, chaos classiques
├── student-tabs.js ← module autonome `Tabs` (init, switchTo)
├── student-performance.js ← onglet Performance (20 scénarios)
├── student-scenarios.js ← métadonnées des scénarios météo
└── student-pedagogique.js ← onglet Pédagogique (slider BAC1-BAC5)
Les scripts sont chargés dans cet ordre strict depuis index.html :
<script src="/config.js"></script>
<script src="/js/i18n.js"></script>
<script src="/student/student-scenarios.js"></script>
<script src="/student/student-tabs.js"></script>
<script src="/student/student-performance.js"></script>
<script src="/student/student-pedagogique.js"></script>
<script src="/student/student-main.js"></script>
config.js expose window.__CONFIG__ (API_URL, LANG…) injecté par le conteneur au démarrage. i18n.js expose window._i18nReady (une Promise résolue quand le dictionnaire JSON est chargé). student-main.js attend window._i18nReady.then(...) avant d'initialiser quoi que ce soit.
Les six onglets¶
L'en-tête de la page étudiante affiche six boutons d'onglet, gérés par le module Tabs (dans student-tabs.js). Un seul onglet est actif à la fois ; la sélection est purement côté client, sans rechargement.
flowchart LR
subgraph Tabs[Barre d'onglets]
T1[⚡ Performance]
T2[📜 Scripting]
T3[🏪 Métier]
T4[⚙️ Fonctionnel]
T5[🛡️ Sécurité]
T6[🎓 Pédagogique]
end
T1 -.-> S1[section-performance]
T2 -.-> S2[section-scripting]
T3 -.-> S3[section-business]
T4 -.-> S4[section-functional]
T5 -.-> S5[section-security]
T6 -.-> S6[section-pedagogy]
Onglet Performance¶
C'est le seul onglet avec un contenu riche affiché directement. Il présente jusqu'à 20 scénarios météo (N1-01 à N4-05) générés dynamiquement depuis l'API backend. Les scénarios sont rendus sous forme de cartes cliquables dans une grille (perf-grid). Une seule bannière perf-active-bar affiche le scénario actuellement actif (au maximum un seul à la fois — c'est une exigence fonctionnelle du mode étudiant).
Le module student-performance.js se charge de récupérer la liste via l'endpoint /api/chaos/student/performance/scenarios, de construire les cartes en respectant le niveau de licence (les scénarios N3-N4 sont verrouillés sans licence), et de les afficher avec leur nom traduit (pris dans le dictionnaire i18n backend via la propriété scenario.<id>.name).
Quand l'étudiant clique sur une carte, le module envoie POST /api/chaos/student/performance/scenario avec l'id du scénario. Le backend applique le preset (combinaison de plusieurs chaos simultanés) puis répond par un nouveau status que le polling de 15 secondes mettra à jour à l'écran.
Onglets Scripting, Métier, Fonctionnel, Sécurité¶
Ces quatre onglets partagent le même composant visuel — la classic-card — qui présente :
- Un label de famille et un titre
- Un badge d'état (
Désactivé,Junior,Confirmé,Expert,MaestroouN1–N4) - Un slider
<input type="range">à 5 positions (0 à 4) - Un statut texte et un message « verrou licence » (
.lock-msg)
Le Chaos Scripting est le seul qui dispose d'un niveau 1 freemium accessible sans licence. Les trois autres (Métier, Fonctionnel, Sécurité) sont entièrement verrouillés tant qu'aucune licence valide n'est active : leur slider est disabled et la carte porte la classe CSS locked. Voir Freemium vs Pro pour le détail des limites.
Onglet Pédagogique¶
L'onglet Pédagogique affiche une carte dédiée avec un slider à 6 positions : Désactivé, Bac+1, Bac+2, Bac+3, Bac+4, Bac+5. Le module student-pedagogique.js (exposé via le namespace PedagogyTab) prend en charge toute la logique :
PedagogyTab.initSlider()— initialise les événements du sliderPedagogyTab.applyStatus(ped, licensed, studentMode)— met à jour l'affichage à partir du payload/status
La règle d'accès est la suivante : les niveaux BAC1 et BAC2 sont gratuits (freemium), les niveaux BAC3 à BAC5 nécessitent une licence. Le slider est également verrouillé intégralement quand studentMode === false — c'est-à-dire quand le formateur a désactivé la page étudiant depuis son panneau d'administration.
Le choix d'un niveau ne lance pas le parcours pour l'étudiant lui-même : le slider configure le niveau par défaut que verra le frontend e-commerce si l'étudiant y navigue ensuite. L'étudiant bascule alors sur le shop et démarre l'aventure via l'overlay d'accueil.
Cycle de polling et état global¶
Toutes les 15 secondes, student-main.js appelle GET /api/chaos/student/status avec le header X-Student-Token s'il est présent dans localStorage :
async function loadStatus() {
const headers = {};
const pedToken = localStorage.getItem('ped_student_token');
if (pedToken) headers['X-Student-Token'] = pedToken;
const r = await fetch(`${API}/api/chaos/student/status`, { headers });
if (!r.ok) return;
applyStatus(await r.json());
}
La raison de la présence du X-Student-Token dans ce call est subtile : sans ce header, le serveur répond needsJoin:true à chaque poll, ce qui provoquerait un flood d'appels /join. Avec le token, le serveur reconnaît la session et renvoie directement l'état.
Le payload status contient les clés suivantes :
| Clé | Contenu |
|---|---|
licensed |
Booléen — une licence valide est-elle active ? |
studentModeEnabled |
Booléen — le formateur a-t-il autorisé la page étudiant ? |
license |
Objet licence : valid, plan, planLabel, holder, etc. |
performance |
État du scénario actif + liste des scénarios disponibles |
scripting, business, functional, security |
{ level, maxLevel } |
pedagogique |
État du parcours pédagogique (niveau, session active) |
La fonction applyStatus() met à jour :
- La bannière « bloqué » (
#blocked-banner) sistudentModeEnabled === false - La barre de statut licence (
#lic-status-bar) - L'onglet Performance via
PerfTab.applyStatus(data.performance, _licensed) - Les 4 cartes classiques via
_updateClassicCard(key, level, maxLevel) - L'onglet Pédagogique via
PedagogyTab.applyStatus(data.pedagogique, _licensed, studentMode)
Actions utilisateur¶
Quand l'étudiant déplace un slider classique, un debounce de 400 ms retarde l'envoi :
Puis _applyClassic(key, level) envoie POST /api/chaos/student/{scripting|business|functional|security} avec le body { level }. Les codes HTTP suivants sont gérés explicitement :
| Code | Signification | Action UI |
|---|---|---|
200 |
Succès | Toast de confirmation, reload du statut |
402 |
Licence manquante | Toast 🔒 Licence requise, reload |
403 |
Mode étudiant désactivé | Toast 🔒 TP non démarré, reload |
| autre | Erreur serveur | Toast ❌ {error}, reload |
Un mécanisme identique existe pour les cartes Performance et Pédagogique, dans leurs modules respectifs.
Activation de licence depuis la page étudiant¶
Un bouton « 🔑 Activer une licence » en en-tête ouvre une bannière qui contient un <textarea> et un bouton « Activer ». La fonction activateLicence() envoie POST /api/license/activate avec la clé saisie :
- Validation format : la clé doit commencer par
PFSH- fetchvers l'API publique (ce endpoint est intentionnellement public, voir Système de licence)- Si succès : toast de confirmation, reload du
statusaprès 1,8 seconde, masquage de la bannière - Si échec : message d'erreur inline
Cette entrée d'activation depuis la page étudiant est pratique en salle de classe : le formateur donne une clé à un étudiant test, qui l'active depuis son poste, et tous les autres étudiants bénéficient immédiatement des niveaux débloqués (la licence est partagée au niveau serveur).
Mode étudiant bloqué¶
Le formateur peut à tout moment bloquer la page étudiant depuis son panneau via POST /api/chaos/student/admin/mode { enabled: false }. Quand c'est le cas, tous les pollings suivants renvoient studentModeEnabled: false, la page étudiant masque la barre de licence et affiche à la place la bannière #blocked-banner :
🔒 TP non démarré — en attente du formateur Le formateur n'a pas encore ouvert la session. Les contrôles seront disponibles dès le démarrage du TP.
Aucun slider n'est utilisable dans cet état. Voir Chaos admin (formateur) pour le déclenchement inverse côté formateur.