Syntax Saga: neues Spiel (server-autoritativ) + 34 Seed-Missionen

Drittes Mindflux-Spiel: interaktive IT-Geschichten, in denen man den
fehlenden Code (Schlüsselwörter, Operatoren, ganze Zeilen) in eine kleine
Story tippt. Freitext-Eingabe, drei wählbare Stufen (Junior/Professional/
Senior), mehrere Lücken je Codeblock und mehrere gültige Antworten je Lücke
(optional case-insensitive). Prüfung und Score ausschließlich serverseitig –
die Lösungen verlassen nie das Backend (Anti-Cheat wie TechTacular/MindMatch).
Fehler-Mechanik: bis zu 3 Versuche mit Hinweis, dann Auflösung; kein Game-Over.

Inhalte DB-gestützt und im Admin pflegbar (/admin/syntaxsaga); 34 Seed-
Missionen (Java/SQL/Bash/Git/HTML/Python) aus syntaxsaga/content.json.

- Entities SyntaxSagaMission/Gap/Solution + Flyway V7__syntax_saga.sql
- SyntaxSagaService (Story ohne Lösung / serverseitige Prüfung / Score-Recompute)
- API /api/syntaxsaga (CSRF-ausgenommen) + Admin-CRUD
- Frontend syntaxsaga.html/js/css (Prefix ss-, theme.css-Tokens)
- Dashboard-Kachel aktiv (vorher "coming soon")

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AliceDarkest
2026-06-30 12:13:37 +02:00
parent bbe24c67eb
commit 4599dd12b8
28 changed files with 2749 additions and 2 deletions
@@ -0,0 +1,61 @@
<!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>Syntax Saga – Mindflux</title>
<link rel="stylesheet" href="/css/theme.css">
<script src="/js/theme.js"></script>
<link rel="stylesheet" href="/css/syntaxsaga.css?v=1">
</head>
<body class="ss-body">
<div class="ss-shell">
<header class="ss-header">
<a href="/dashboard" class="ss-back">⟵ Dashboard</a>
<h1 class="ss-title">Syntax Saga</h1>
<div class="ss-header-tools">
<button type="button" class="mf-theme"></button>
<a href="/logout" class="ss-logout">Logout</a>
</div>
</header>
<div class="ss-bar">
<div class="ss-bar-group" aria-label="Schwierigkeit wählen">
<span class="ss-bar-label">Stufe:</span>
<button type="button" class="ss-diff" data-diff="junior">Junior</button>
<button type="button" class="ss-diff" data-diff="professional">Professional</button>
<button type="button" class="ss-diff" data-diff="senior">Senior</button>
</div>
<div class="ss-bar-group ss-hud" aria-live="polite">
<span class="ss-stat">Punkte <b id="ss-score">0</b></span>
<span class="ss-stat">Mission <b id="ss-mission">– / –</b></span>
<span class="ss-stat">Zeit <b id="ss-time">0:00</b></span>
<span class="ss-stat">Bestwert <b id="ss-best">–</b></span>
</div>
</div>
<main class="ss-stage">
<section id="ss-story" class="ss-story" aria-label="Syntax-Saga-Geschichte"></section>
</main>
</div>
<!-- Ergebnis-Overlay -->
<div id="ss-result" class="ss-overlay" hidden>
<div class="ss-result-card">
<h2>Saga beendet 🎉</h2>
<p id="ss-result-stars" class="ss-result-stars">★★★</p>
<p class="ss-result-score">Score: <strong id="ss-result-score">0</strong> / <span id="ss-result-max">0</span></p>
<p id="ss-result-detail" class="ss-result-detail"></p>
<p id="ss-result-high" class="ss-result-high" hidden>🏆 Neuer Bestwert!</p>
<div class="ss-result-actions">
<button type="button" id="ss-again" class="ss-btn">Nochmal</button>
<button type="button" id="ss-choose" class="ss-btn ss-btn-secondary">Andere Stufe</button>
<a href="/dashboard" class="ss-btn ss-btn-secondary">Dashboard</a>
</div>
</div>
</div>
<script src="/js/syntaxsaga.js?v=1" defer></script>
</body>
</html>