Skip to content

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 (PedagogiqueEnigmeBac1PedagogiqueEnigmeBac5). 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 →