Aller au contenu

API — Page étudiant (self-service)

Cette page documente la partie non-pédagogique de ChaosStudentController, montée sous /api/chaos/student. Ces endpoints permettent à l'étudiant de piloter lui-même le chaos sur sa propre machine — dans la limite de sa licence — sans passer par le formateur.

Contrôleur couvert

ChaosStudentController — partie self-service (status, performance, scripting, business, functional, security, scenarios, admin/mode)

La partie parcours pédagogiques du même contrôleur (activation formateur, join, validate, logique, finale, etc.) est documentée séparément dans pedagogique.md.


Le mode étudiant

La page étudiant de PerfShop a une vocation double :

  1. Self-service en autonomie : un étudiant qui s'entraîne seul peut activer les chaos sur sa machine sans avoir besoin d'un formateur.
  2. Support du parcours pédagogique : quand un formateur active un parcours BAC1–BAC5, cette même page bascule en mode guidé.

La séparation est portée par l'état interne du contrôleur, pas par des endpoints différents. Le flag studentModeEnabled contrôle l'accès self-service et peut être verrouillé par le formateur pour forcer les étudiants à suivre le parcours pédagogique.


Vue d'ensemble

Méthode Endpoint Auth Description
GET /api/chaos/student/status Aucune État complet (mode, parcours, niveaux actifs)
POST /api/chaos/student/performance Aucune (licence-gated) Niveau performance self-service
POST /api/chaos/student/scripting Aucune (licence-gated) Niveau scripting self-service
POST /api/chaos/student/business Aucune (licence-gated) Niveau métier self-service
POST /api/chaos/student/functional Aucune (licence-gated) Niveau fonctionnel self-service
POST /api/chaos/student/security Aucune (licence-gated) Niveau sécurité self-service
GET /api/chaos/student/performance/scenarios Aucune (licence-gated) Catalogue des 20 scénarios météo
POST /api/chaos/student/performance/scenario Aucune (licence-gated) Lancer un scénario préconfiguré
POST /api/chaos/student/admin/mode Admin Verrouiller/déverrouiller le mode étudiant

Le mur freemium — code 402

Tous les endpoints de pilotage étudiant (/performance, /scripting, /business, /functional, /security, /scenarios) vérifient la licence courante avant d'autoriser un changement de niveau. Si le niveau demandé dépasse la limite gratuite, la réponse est 402 Payment Required :

{
  "error": "LICENSE_REQUIRED",
  "chaos": "performance",
  "requested": 3,
  "maxFree": 1,
  "message": "Niveau 3 non disponible sans licence. Maximum : 1",
  "portalUrl": "https://perfshop.io"
}
Champ Description
error Toujours LICENSE_REQUIRED
chaos Nom de la famille concernée (performance, scripting, business, functional, security)
requested Niveau demandé par l'étudiant
maxFree Niveau maximum autorisé sans licence
message Message localisé (clé student.license.required.message)
portalUrl URL commerciale pour obtenir une licence

Limites freemium par défaut

Famille Niveau max sans licence Scénarios accessibles
Performance 1 (Junior) N1-01, N1-02 uniquement
Scripting 0 (désactivé)
Métier 0 (désactivé)
Fonctionnel 0 (désactivé)
Sécurité 0 (désactivé)

La licence Pro débloque tous les niveaux et tous les scénarios. Voir license.md.

Le 402 ne bloque rien d'existant

Un 402 empêche un étudiant sans licence d'activer un niveau élevé, mais il n'interrompt pas les chaos déjà actifs. Si le formateur a démarré un niveau 4 avec sa licence Pro, tous les étudiants subissent les effets — ils ne peuvent juste pas en déclencher d'eux-mêmes.


GET /api/chaos/student/status

Retourne l'état consolidé pour la page étudiant : mode actif, niveaux de chaque famille, parcours pédagogique en cours, licence, etc.

Auth : aucune Polling recommandé : toutes les 15 secondes depuis la page étudiant

Réponse — 200 OK

{
  "studentModeEnabled": true,
  "studentBlockedMessage": null,
  "license": {
    "active": false,
    "plan": "FREE",
    "maxLevels": {
      "performance": 1,
      "scripting": 0,
      "business": 0,
      "functional": 0,
      "security": 0
    }
  },
  "chaos": {
    "performance": {
      "cpu": 40,
      "cpuRatio": 1,
      "memoryLeakTarget": 0,
      "gcPressure": 0,
      "dbPool": 0,
      "threadPool": 0,
      "slowQueries": 0,
      "deadlock": 0,
      "network": 0
    },
    "scripting": { "level": 0, "levelName": "Désactivé" },
    "business":  { "level": 0, "levelName": "Niveau 0 — Desactive", "anomalies": [] },
    "functional":{ "level": 0, "levelName": "Niveau 0 — Desactive", "anomalies": [] },
    "security":  { "level": 0, "levelName": "Niveau 0 — Desactive", "faults": [] }
  },
  "activeScenarioId": null,
  "pedagogique": {
    "active": false,
    "level": 0,
    "hintsEnabled": true,
    "session": null
  }
}
Champ clé Description
studentModeEnabled true si l'étudiant peut piloter les chaos en self-service
studentBlockedMessage Message affiché si le mode est bloqué par le formateur (sinon null)
license.active true si une licence Pro est activée
license.maxLevels Niveau max autorisé par famille selon la licence
activeScenarioId ID du scénario en cours (N1-01, N3-02, etc.) ou null
pedagogique.active true si un parcours formateur est en cours — voir pedagogique.md

POST /api/chaos/student/performance

Active un niveau de Chaos Performance simplifié pour l'étudiant. Contrairement à POST /api/admin/chaos/cpu (qui règle chaque paramètre indépendamment), cet endpoint prend un niveau global 0–4 et applique une configuration prédéfinie.

Auth : aucune (mais vérification licence)

Requête

{ "level": 1 }

Table de correspondance niveau → intensité CPU

// ChaosStudentController.PERF_CPU_INTENSITY
{ 0, 40, 60, 80, 95 }
Level étudiant CPU intensity Niveau équivalent admin
0 0 Aucun chaos
1 40 Charge légère
2 60 Charge modérée
3 80 Charge forte
4 95 Charge extrême

L'endpoint règle uniquement le CPU — les autres paramètres (mémoire, DB pool, etc.) restent à leurs valeurs courantes. Pour un contrôle granulaire, l'étudiant doit utiliser POST /api/chaos/student/performance/scenario avec un scénario prédéfini.

Réponse — 200 OK

{
  "success": true,
  "level": 1,
  "cpu": 40,
  "cpuRatio": 1,
  "activeScenarioId": null
}

Ce changement réinitialise activeScenarioId — si un scénario était en cours, il est désactivé.

Codes d'erreur

Code Cause
400 Niveau hors [0–4]
402 Licence insuffisante (voir mur freemium)
403 Mode étudiant bloqué (clé student.error.blocked)

POST /api/chaos/student/scripting, /business, /functional, /security

Ces 4 endpoints partagent la même structure que /performance — ils prennent un niveau global 0–4 et l'appliquent à la famille correspondante. Ils délèguent au service admin sous-jacent après vérification de licence.

Requête

{ "level": 2 }

Réponse — 200 OK

{
  "success": true,
  "family": "business",
  "level": 2,
  "levelName": "Niveau 2 — Confirme",
  "activeAnomalies": ["A1", "A2", "A3", "A4", "A5", "A6", "A7"]
}

Codes d'erreur

Identiques aux autres endpoints étudiants : 400, 402 (licence), 403 (mode bloqué).

Pas de licence = pas de chaos métier/fonctionnel/sécurité/scripting

Ces 4 familles ont une limite freemium à 0 — aucun niveau ne peut être activé sans licence. Ce choix est délibéré : le chaos performance suffit à illustrer les concepts de base en autonomie, tandis que les familles avancées nécessitent un contexte pédagogique cadré.


GET /api/chaos/student/performance/scenarios

Retourne le catalogue des 20 scénarios météo préconfigurés. Chaque scénario est une combinaison multi-paramètres des chaos performance, conçue pour illustrer une situation réelle.

Auth : aucune (mais filtré par licence)

Réponse — 200 OK

{
  "licensed": false,
  "activeScenario": "",
  "scenarios": [
    {
      "id": "N1-01",
      "name": "Brise légère",
      "level": 1,
      "requiresLicense": false,
      "accessible": true
    },
    {
      "id": "N1-02",
      "name": "Brume matinale",
      "level": 1,
      "requiresLicense": false,
      "accessible": true
    },
    {
      "id": "N1-03",
      "name": "Grain passager",
      "level": 1,
      "requiresLicense": true,
      "accessible": false
    },
    {
      "id": "N4-05",
      "name": "Tempête parfaite",
      "level": 4,
      "requiresLicense": true,
      "accessible": false
    }
  ]
}
Champ Description
licensed true si une licence valide est active
activeScenario Identifiant du scénario en cours (chaîne vide si aucun)
scenarios[].id Identifiant N<niveau>-<index> où niveau ∈ {1,2,3,4}, index ∈ {01..05}
scenarios[].name Nom météorologique localisé via la clé scenario.N*-**.name
scenarios[].level Niveau de difficulté 1–4
scenarios[].requiresLicense true si le scénario requiert une licence pour être lancé
scenarios[].accessible true si l'étudiant courant peut le lancer (!requiresLicense || licensed)

Chaque entrée est construite à partir du bloc PerformanceScenario.toPublicMap() enrichi par le contrôleur avec le nom localisé et le flag accessible calculé en fonction de la licence courante.

Les 20 scénarios météo

Niveau 1 — Junior : Brise légère, Brume matinale, Grain passager, Crachin réseau, Nuage de passage Niveau 2 — Confirmé : Vent de travers, Étang gelé, Bourrasque, Brouillard double, Marée montante Niveau 3 — Expert : Tempête de sable, Gel profond, Déluge croisé, Front orageux, Cyclone en formation Niveau 4 — Maestro : Ouragan, Effondrement, Point de rupture, Tsunami, Tempête parfaite

Scénarios gratuits : par convention, les 2 premiers scénarios du niveau 1 (N1-01 Brise légère et N1-02 Brume matinale) sont accessibles sans licence. Tous les autres ont requiresLicense: true.

Codes d'erreur

Code Cause
403 Mode étudiant bloqué par le formateur

POST /api/chaos/student/performance/scenario

Lance un scénario par son ID. Si un autre scénario est en cours, il est remplacé (exclusivité mutuelle).

Auth : aucune (mais vérification licence)

Requête

{ "scenarioId": "N1-01" }

Comportement

  1. Vérification du mode étudiant (403 si bloqué)
  2. Si scenarioId est vide → chaosService.resetAll() + frontendChaosController.resetState() + activeScenarioId = null, retourne {success, scenarioId: "", active: false}
  3. Vérification que le scénario existe dans PerformanceScenario.ALL (clé student.scenario.unknown si non)
  4. Si requiresLicense == true et aucune licence → 402 LICENSE_REQUIRED
  5. Appel de chaosService.resetAll() et frontendChaosController.resetState() — reset complet avant application
  6. Application conditionnelle des paramètres non nuls : cpu, cpuRatio, memory, memoryHeapCap, dbPool, threadPool, slowQuery, deadlock, network, et les 4 chaos frontend (cpuBurn, memoryLeak, domFlood, fetchFlood)
  7. Stockage de activeScenarioId = scenarioId

Réponse — 200 OK (scénario lancé)

{
  "success": true,
  "scenarioId": "N1-01",
  "name": "Brise légère",
  "level": 1,
  "active": true
}

Réponse — 200 OK (reset via scenarioId vide)

{
  "success": true,
  "scenarioId": "",
  "active": false
}

Codes d'erreur

Code Corps Cause
400 {"error": "Scénario inconnu : X"} ID non présent dans le catalogue (clé student.scenario.unknown)
402 {"error": "LICENSE_REQUIRED", ...} Scénario non freemium, licence inactive
403 {"error": "Mode étudiant bloqué par le formateur"} studentModeEnabled = false

Exclusivité via resetAll()

Chaque lancement de scénario commence par un reset complet du chaos performance. C'est intentionnel : les scénarios sont des configurations autonomes, pas des deltas. Lancer N2-01 après N1-01 produit exactement les paramètres de N2-01, pas un cumul.


POST /api/chaos/student/admin/mode

Verrouille ou déverrouille le mode étudiant. Endpoint admin — le formateur utilise cet endpoint pour bloquer le self-service pendant un parcours dirigé.

Auth : admin (session ou X-Admin-Token)

Requête

{
  "enabled": false,
  "message": "Mode étudiant désactivé pendant l'examen — reprise à 14h"
}
Champ Type Requis Description
enabled boolean oui true pour autoriser le self-service, false pour le bloquer
message string non Message affiché à l'étudiant (si enabled: false)

Réponse — 200 OK

{
  "success": true,
  "studentModeEnabled": false,
  "studentBlockedMessage": "Mode étudiant désactivé pendant l'examen — reprise à 14h"
}

Si enabled: false et message absent, le message par défaut est Mode étudiant bloqué par le formateur (clé student.mode.disabled).

Codes d'erreur

Code Cause
401 Non authentifié admin

Réconciliation avec isAllChaosOff()

Quand le mode étudiant est bloqué et que tous les chaos sont à 0, le contrôleur force activeScenarioId = null — cohérence de l'affichage côté étudiant. Cette logique est dans ChaosStudentController.isAllChaosOff().


Exemple curl

# 1. État initial
curl http://localhost:9080/api/chaos/student/status | jq

# 2. Lancer le scénario Brise légère (gratuit)
curl -H "Content-Type: application/json" \
     -d '{"scenarioId":"N1-01"}' \
     http://localhost:9080/api/chaos/student/performance/scenario

# 3. Tenter un scénario payant → 402
curl -H "Content-Type: application/json" \
     -d '{"scenarioId":"N3-02"}' \
     http://localhost:9080/api/chaos/student/performance/scenario
# Réponse :
# { "error": "LICENSE_REQUIRED", "chaos": "performance",
#   "requested": 3, "maxFree": 1, "portalUrl": "https://perfshop.io" }

# 4. Activer une licence Pro (voir license.md)
curl -H "Content-Type: application/json" \
     -d '{"licenseKey":"PFSH-XXXX-XXXX-XXXX-XXXX"}' \
     http://localhost:9080/api/license/activate

# 5. Re-tenter le scénario → 200
curl -H "Content-Type: application/json" \
     -d '{"scenarioId":"N3-02"}' \
     http://localhost:9080/api/chaos/student/performance/scenario

# 6. Le formateur bloque le mode étudiant (admin requis)
TOKEN=$(curl -s -H "Content-Type: application/json" \
  -d '{"email":"admin@perfshop.fr","password":"admin"}' \
  http://localhost:9080/api/admin/login | jq -r '.adminToken')

curl -H "X-Admin-Token: $TOKEN" -H "Content-Type: application/json" \
     -d '{"enabled":false,"message":"TP guidé en cours"}' \
     http://localhost:9080/api/chaos/student/admin/mode

Points d'attention

Séparation stricte student / admin

La page étudiant ne dispose pas d'endpoints de reset. Pour réinitialiser, l'étudiant doit :

  1. Repasser tous les niveaux à 0 (un par un) OU
  2. Lancer le scénario N1-01 (Brise légère) qui fait un reset avant d'appliquer

Le reset complet via POST /api/admin/chaos/reset reste réservé à l'admin. Ce choix évite qu'un étudiant puisse « effacer ses traces » après une démonstration de panne — le formateur garde le contrôle de la session.

Compatibilité parcours pédagogique

Quand un parcours pédagogique est actif (voir pedagogique.md), le pilotage self-service reste autorisé sauf si le formateur l'a explicitement bloqué via /admin/mode. Cette flexibilité permet à un étudiant de combiner exercices guidés et exploration libre dans la même session.


Liens associés