Dev Lab: server-autoritatives Entwicklerlabor mit 6 Mechaniken + 189 Aufgaben

Dev Lab bündelt mehrere Disziplinen (SQL, Java/Debugging, Git, HTML, CSS, Regex,
PHP, REST) in 11 Spielen mit zusammen 189 Aufgaben. Im Gegensatz zur ersten,
rein clientseitigen Skizze jetzt server-autoritativ, DB-gestützt und im Admin
pflegbar – mit echter Mechanik-Vielfalt statt überall Lückentext:
cloze (Lücke tippen), choice (Multiple Choice), order (Bausteine zusammensetzen),
spot (Bug anklicken), match (Paare zuordnen), regex (Muster schreiben mit
Live-Treffer-Vorschau).

Prüfung und Score ausschließlich serverseitig – die Lösungen verlassen nie das
Backend; Eingabe-Platzhalter sind neutrale Labels (Lösungs-Leak behoben).
Fehler-Mechanik mit Versuchen + Hinweis + Auflösung, kein Game-Over; Score über
die generische game_scores-Tabelle (Kennung devlab, deck=Spiel-Slug).

- Entities DevLabGame/DevLabTask (JSON-payload) + Flyway V8__devlab.sql
- DevLabService mit sechs Mechanik-Checkern; API /api/devlab/** (CSRF-ausgenommen,
  devlab in KNOWN_GAMES)
- Admin /admin/devlab (Spiele + Aufgaben pflegen); polymorphe Frontend-Engine
  devlabgame.js + DB-getriebener Hub devlab.js
- Inhalte aus devlab/content.json (idempotenter Seeder); ersetzt die erste
  clientseitige Dev-Lab-Skizze (devlab.js/devlabgame.js/-game.html/-game.css neu)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AliceDarkest
2026-06-30 16:32:03 +02:00
parent 55a09cb093
commit b88962da6f
28 changed files with 6542 additions and 2 deletions
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dev Lab Spiel – Mindflux</title>
<link rel="stylesheet" href="/css/theme.css">
<script src="/js/theme.js"></script>
<link rel="stylesheet" href="/css/devlabgame.css?v=3">
</head>
<body class="dlg-body" th:attr="data-game=${gameSlug}">
<div class="dlg-shell">
<header class="dlg-header">
<a href="/devlab" class="dlg-back">⟵ Dev Lab</a>
<div class="dlg-head-title">
<p id="dlg-language" class="mf-eyebrow">Dev Lab</p>
<h1 id="dlg-title">Spiel wird geladen…</h1>
</div>
<div class="dlg-header-tools">
<button type="button" class="mf-theme"></button>
<a href="/logout" class="dlg-logout">Logout</a>
</div>
</header>
<div class="dlg-bar">
<div class="dlg-bar-group">
<span class="dlg-stat">Aufgabe <b id="dlg-task-no">– / –</b></span>
<span class="dlg-stat">Punkte <b id="dlg-score">0</b></span>
<span class="dlg-stat">Zeit <b id="dlg-time">0:00</b></span>
<span class="dlg-stat">Bestwert <b id="dlg-best">–</b></span>
</div>
<div class="dlg-bar-group">
<span id="dlg-mech" class="mf-badge">–</span>
</div>
</div>
<main class="dlg-stage">
<section class="dlg-card">
<div class="dlg-card-head">
<span id="dlg-kind" class="mf-badge">Aufgabe</span>
<span id="dlg-points" class="dlg-points">100</span>
</div>
<h2 id="dlg-prompt"></h2>
<p id="dlg-narrative" class="dlg-narrative"></p>
<p id="dlg-instruction" class="dlg-instruction"></p>
<div id="dlg-playfield" class="dlg-playfield"></div>
<p id="dlg-feedback" class="dlg-feedback" aria-live="polite"></p>
<p id="dlg-success" class="dlg-success" hidden></p>
<div class="dlg-actions">
<button id="dlg-check" class="mf-btn" type="button">Prüfen</button>
<button id="dlg-hint" class="mf-btn ghost" type="button">Hinweis</button>
<button id="dlg-reveal" class="mf-btn outline" type="button" hidden>Auflösung</button>
<button id="dlg-next" class="mf-btn" type="button" hidden>Weiter</button>
</div>
</section>
<aside class="dlg-side mf-panel accent">
<h2 id="dlg-side-title">Mission Log</h2>
<p id="dlg-description" class="dlg-description"></p>
<div class="dlg-progress">
<span>Fortschritt</span>
<div class="mf-bar"><i id="dlg-progress" style="width:0"></i></div>
</div>
<p id="dlg-best-line" class="dlg-best"></p>
</aside>
</main>
</div>
<div id="dlg-result" class="dlg-overlay" hidden>
<div class="dlg-result-card">
<h2>Disziplin abgeschlossen 🎉</h2>
<p id="dlg-result-stars" class="dlg-result-stars">★★★</p>
<p class="dlg-result-score">Score: <strong id="dlg-result-score">0</strong> / <span id="dlg-result-max">0</span></p>
<p id="dlg-result-detail" class="dlg-result-detail"></p>
<p id="dlg-result-high" class="dlg-result-high" hidden>🏆 Neuer Bestwert!</p>
<div class="dlg-result-actions">
<button id="dlg-again" class="mf-btn" type="button">Nochmal</button>
<a href="/devlab" class="mf-btn outline">Zur Spielsammlung</a>
</div>
</div>
</div>
<script src="/js/devlabgame.js?v=3" defer></script>
</body>
</html>