Concept and architecture¶
Pedagogical chaos is the PerfShop learning module: a technical
escape room grafted onto the e-commerce store, in which a student —
playing an "agent" — solves a series of enigmas embedded in the checkout
funnel to progress through a graduated journey from BAC+1 to BAC+5.
This page documents the philosophy, the components and the
lifecycle of a journey. The following pages detail each mechanic
(levels, enigmas, agent code,
stars, hints, success,
final themes).
Why an escape room on an e-commerce site?¶
An e-commerce site is a universal narrative playground: everyone has already added a product to a cart, filled in an address and validated a payment. By grafting enigmas onto these familiar actions, the student learns to observe a real system rather than follow a tutorial. The enigma forces them to read the catalog, compare prices, decode a JWT payload or cross-reference response headers with a Grafana dashboard — in other words, to navigate a production application like an engineer discovering an unknown environment.
The mechanic is deliberately simple on the player side: each enigma expects a short text answer. Server-side, the answer is hashed with SHA-256 and compared to a pre-computed hash — the correct answer is never transmitted in clear. This constraint forces statements whose answer fits in one word, one number or one IP address: ambiguities are forbidden, pedagogy is explicit.
What pedagogical chaos is not
It is not a MOOC. There is no lecture, no video, no automatic
error correction. The student learns by making the store work
while an instructor orchestrates the session from the chaos-admin
panel. The technical documentation in this section describes the
engine mechanism; it contains no enigma answers.
The five levels — the 10,000-foot view¶
The system offers five independent journeys; a student can join any of them as soon as the instructor has activated it.
| Level | Internal name | Steps | Duration | Dominant theme | ⭐ max |
|---|---|---|---|---|---|
| BAC+1 | bac1 |
10 | 30 min | Pure math, commercial arithmetic | 1 |
| BAC+2 | bac2 |
15 | 45 min | Logic, sequences, Caesar cipher, combinatorics | 2 |
| BAC+3 | bac3 |
20 | 60 min | HTTP, Docker, observability, protocol basics | 3 |
| BAC+4 | bac4 |
25 | 75 min | Hexadecimal, XOR, JWT, IPv6, algorithmics | 4 |
| BAC+5 | bac5 |
30 | 90 min | Simplified RSA, Dijkstra, Hamming, complexity, crypto | 5 |
Total: 100 enigmas, all stored in the Java backend
(PedagogiqueEnigmeBac1 … PedagogiqueEnigmeBac5). Each level ends
with a dynamic step whose answer depends on an agent code unique
to each student — see agent-code.md. The level-by-level
breakdown is in levels.md.
Roles and components¶
flowchart LR
subgraph FORMA[Instructor]
ADM[chaos-admin page<br/>Pedagogical tab]
end
subgraph ETUDIANT[Student]
BOUT[Browser<br/>PerfShop store]
OVR[Overlay<br/>PedagogiqueOverlay]
TIM[Timer<br/>PedagogiqueTimer]
SUC[Success page<br/>/s/:token]
end
subgraph BACK[Spring Boot backend]
CTRL[ChaosStudentController]
SVC[PedagogiqueSessionService]
ENI[PedagogiqueEnigme<br/>+ Bac1–5 catalogs]
end
subgraph DB[(MySQL)]
TAB[pedagogique_sessions]
end
ADM -->|POST /activate<br/>/deactivate<br/>/hints| CTRL
BOUT --> OVR
BOUT --> TIM
OVR -->|POST /join<br/>/validate| CTRL
SUC -->|GET /succes/{token}<br/>POST /logique/*<br/>/finale/validate| CTRL
CTRL --> SVC
SVC --> TAB
CTRL --> ENI
The two human actors — instructor and student — share no
credential: the instructor authenticates with their admin token
(X-Admin-Token), the student with an opaque session token
(X-Student-Token) generated at POST /pedagogique/join and stored in
localStorage under the key ped_student_token. This partitioning is
the foundation of the multi-session architecture described in
architecture/multi-session.md.
Instructor side — chaos-admin¶
The chaos-admin panel, served by the container of the same name,
exposes the Pedagogical tab. From this panel the instructor can:
- activate a journey for a given level (
POST /pedagogique/activate) - deactivate the current journey (
POST /pedagogique/deactivate) - view in real time the list of connected students and their
progress (
GET /pedagogique/sessions) - toggle hints (💡 button) in real time during the journey
(
POST /pedagogique/hints) - enable or disable the write-through memory cache for the Memory Chaos demonstration (the "Memory mode — pedagogical heap dump" checkbox)
- view the last summary after a deactivation
(
GET /pedagogique/last-summary)
The instructor panel stores nothing locally: all views are built from
backend endpoints. It polls sessions every few seconds to refresh the
progress table.
Student side — store + overlay¶
Three React components orchestrate the student experience from
App.jsx:
| Component | Role | Lifetime |
|---|---|---|
PedagogiqueOrchestrator |
Entry point mounted once outside the <Routes>. Detects the activation of a journey, drives the timer and the overlay, triggers navigation to /s/:token once the journey is completed. |
Entire browser session |
PedagogiqueTimer |
Fixed timer in the top right corner. Green → orange → red, then "Time's up". Anti-drift anchoring: countdown based on Date.now(), resynchronized on each poll. |
During the active journey |
PedagogiqueOverlay |
Floating, draggable window that displays the current step's statement, an answer field, the 💡 hint button (if enabled), and — after a correct answer — the cultural note and the countdown to the next step. | During the active journey |
The usePedagogiqueState hook drives polling of
GET /api/chaos/student/status every 15 seconds. It also handles
automatic join: if the response contains pedagogique.needsJoin = true,
the hook sends a POST /pedagogique/join with a random alias
(Agent-XXXX — 4 hex chars), stores the received token and triggers an
immediate re-poll. On the frontend, the token is the only proof of
identity; losing it means losing progress.
Backend side — Spring Boot¶
The backend exposes all endpoints under the prefix
/api/chaos/student/pedagogique/* in ChaosStudentController. The
business logic is delegated to PedagogiqueSessionService (interface)
and its single implementation DefaultPedagogiqueSessionService. The
enigma catalog is static and loaded into memory at startup by the
PedagogiqueEnigme class, which delegates loading to five companion
classes: PedagogiqueEnigmeBac1 through PedagogiqueEnigmeBac5.
Statements, hints and cultural notes are not hard-coded in Java:
they are externalized in i18n JSON files, resolved via the t(level, key)
method according to the PERFSHOP_LANG environment variable. The
mechanism is detailed in the i18n/enigmes.md
page.
Lifecycle of a journey¶
From the instructor's click to unlocking the mini-games hub, a session goes through nine clearly identified steps.
sequenceDiagram
autonumber
actor F as Instructor
actor E as Student
participant ADM as chaos-admin
participant CTR as ChaosStudentController
participant SVC as DefaultPedagogiqueSessionService
participant DB as MySQL<br/>pedagogique_sessions
participant ENI as PedagogiqueEnigme
F->>ADM: Clicks "Activate bac3"
ADM->>CTR: POST /pedagogique/activate<br/>{level:"bac3", memoryCache:false}
CTR->>SVC: clearAll()
CTR->>ENI: forLevel("bac3")
Note over CTR: pedagogiqueActive=true<br/>startTime=now()
E->>CTR: GET /status (polling)
CTR-->>E: pedagogique.needsJoin=true
E->>CTR: POST /pedagogique/join {alias}
CTR->>SVC: createSession(alias, "bac3", 3600)
SVC->>SVC: compute agentCode (hex)
SVC->>SVC: compute extractionAnswerHash
SVC->>SVC: compute logiqueQuestionIndices (LCG)
SVC->>SVC: compute logiqueExpectedHash
SVC->>DB: INSERT pedagogique_sessions
SVC-->>CTR: MutableSession
CTR-->>E: {token, alias, level, totalSteps, timerRemaining}
loop For each step
E->>E: Reads statement, acts in the store
E->>CTR: POST /pedagogique/validate<br/>{step, answerHash}
CTR->>CTR: Compare hash (DYNAMIC or static)
alt Correct answer
CTR->>SVC: saveSession(step+=1)
SVC->>DB: UPDATE current_step
CTR-->>E: {valid:true, nextEnigme, culturalNote?}
else Wrong answer
CTR->>SVC: saveSession(attempts++)
CTR-->>E: {valid:false, attempts}
end
end
Note over E: Final DYNAMIC step validated
CTR->>SVC: completedAt = now()
CTR-->>E: {valid:true, completed:true, stars, maxStars}
E->>E: Navigation to /s/{token}
E->>CTR: GET /pedagogique/succes/{token}
CTR-->>E: {alias, level, stars, durationSeconds}
E->>E: Chooses a final theme
E->>CTR: POST /pedagogique/finale/validate<br/>{theme, answerHash}
alt Logic theme
Note over E,CTR: Phase 1: /logique/check<br/>Phase 2: /finale/validate
end
CTR-->>E: {valid:true, gameUrl}
E->>E: window.location = gameUrl
When the last enigma is validated, completedAt is set and the
PedagogiqueOrchestrator automatically navigates to /s/:token. The
token is the authentication: it is non-guessable (UUID v4), carried in
the URL, and the page is entirely outside the PerfShop navbar/footer
for a distinct "end of journey" effect. See success.md
for details.
Access to the pedagogical mini-games hub
Once the final theme is validated, the student gains access to a pedagogical mini-games hub deployed separately. The technical documentation of the hub itself is not exposed in this reference.
Multi-session architecture in one sentence¶
The MySQL database is always the source of truth; a ConcurrentHashMap
write-through memory cache can be enabled at runtime by the instructor
for the Memory Chaos demonstration — in this mode, MutableSession
objects appear in heap dumps and visually illustrate a typical memory
leak. See architecture/multi-session.md
for the write-through pattern details, and hints.md for
the real-time propagation of hints.
Limit of 500 concurrent sessions
The POST /pedagogique/join endpoint refuses any new join with an
HTTP 429 Too Many Requests as soon as the service exceeds
500 active sessions. This limit is a protection against
memory/database saturation and widely covers the expected uses
(classic cohorts of 20 to 60 students). For an exceptional
hackathon-style event with several hundred participants, consider
multiple backend instances or adapting the constant in
ChaosStudentController.
Internationalization¶
The engine is natively multilingual. Statements, hints and cultural
notes are loaded once at startup from the files
src/main/resources/i18n/enigmes/bacN/enigmes_XX.json according to the
PERFSHOP_LANG environment variable (default: fr).
The Java code supports seven languages (fr, en, de, zh,
es, it, pt); to date, the five levels have the seven corresponding
files for enigmas. The pool of 25 questions for the Logic & Math theme
is available in fr and en; the other languages will automatically
fall back to French pending their translation. Adding a language
requires no Java modification: simply drop the translated JSON file
into the right directory and restart the backend.
The MkDocs documentation you are reading is itself built for five
languages (fr, en, es, de, it) — see the plugins.i18n
configuration in mkdocs.yml.
Next pages: BAC1 to BAC5 levels → · Enigma system → · Dynamic agent code →