- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/ - 12 code-workspace-Files - STATUS-*.md - viele M/D/R-Änderungen an bereits getrackten Files - .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8.1 KiB
Vertrag 2: Input-API
Was ein Modul beim Start von der Plattform bekommt und wie es die restlichen Daten anfragt. Module dürfen NICHT direkt auf die DB zugreifen für User-Daten — alles über die API.
URL-Aufruf
Wenn ein:e Schüler*in im V2-Cockpit auf das Modul klickt, ruft die
Plattform entryHtml mit definierten Query-Parametern auf:
https://geograsim.at/v2beta/sims/logistik/public/game.html
?session_token=eyJhbGc...
&student_id=4711
&class_id=42
&mode=teacher_started
&difficulty=L1
&lang=de-AT-easy
&resume=1
Pflicht-Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
session_token |
JWT-String | Auth-Token, vom Modul für alle API-Calls verwendet. Gültigkeit und Refresh-Fenster aus /api/runtime-config (Default 1h Lebensdauer, 5min Refresh-Fenster vor Ablauf). Plattform-Helper-Lib (telemetry-client.js) übernimmt Auto-Refresh transparent. |
student_id |
Integer | DB-ID Schüler*in |
class_id |
Integer | DB-ID Klasse |
mode |
Enum | free / teacher_started / assessment / demo |
difficulty |
String | Ein Level-ID aus manifest.difficultyLevels |
lang |
String | Locale-Code <sprache>-<land>-<variante>, z.B. de-AT-standard, de-AT-easy. Aus Profil-Default oder Lehrer-Override. Heute Pflicht: AT-Varianten; später de-DE-*, de-CH-*. |
resume |
0/1 |
Soll das Modul den letzten Stand wiederherstellen |
Modus-Bedeutung
free— Schüler*in arbeitet selbstgewählt. Wählt Level auslevelUnlocks[moduleSlug].highestUnlocked(Default L1). Beinachteilsausgleich=truedarf jeder Level gewählt werden. Ergebnis wird gespeichert aber zählt nicht für die Lehrperson-Bewertung.teacher_started— Lehrperson hat einen Auftrag mit fester Schwierigkeit angelegt (class_assignments_v2).difficulty-Parameter ist vorgegeben, Schülerin kann nicht wechseln. Ausnahme beinachteilsausgleich=true: Schülerin darf trotzdem frei wählen. Live-Telemetry wird priorisiert im Lehrperson-Dashboard dargestellt.assessment— Bewertungs-Modus, das Modul soll Hilfen reduzieren und das Ergebnis fließt in die Schüler-Bewertung ein. Hinweis im UI: „Du bearbeitest gerade eine Bewertung — keine Tipps verfügbar."demo— Demo-Mode für Lehrperson-Vorführung, kein Speichern, keine Telemetry an die DB (Heartbeat trotzdem schicken, aber Plattform verwirft sie still).
API: Profil holen
Direkt nach Start ruft das Modul das Profil ab:
GET /v2beta/api/student/me
Authorization: Bearer <session_token>
Response 200:
{
"studentId": 4711,
"displayName": "Lena",
"avatarSlug": "fuchs-explorer",
"avatarUrl": "/v2beta/assets/avatars/avatar-fuchs-explorer.png",
"easyLanguage": true,
"locale": "de-AT-easy",
"country": "AT",
"classId": 42,
"className": "1A 2025/26",
"schoolName": "MS Test",
"preferences": {
"soundOn": true,
"musicOn": false,
"highContrast": false,
"reducedMotion": false,
"screenReader": false,
"textScale": "normal"
}
}
A11y-Settings (siehe platform-standards.md § 9):
highContrast— aktiviert High-Contrast-Token-Set (body[data-high-contrast="light"]default)reducedMotion— Modul muss Auto-Play-Animationen unterdrückenscreenReader— Schüler*in nutzt Screen-Reader; Modul soll visuell-zwingende Aufgaben vermeiden oder per Telemetry-Eventaccessibility-blockermeldentextScale—"normal"/"large"/"xlarge"— Modul kann eigene Text-Tokens entsprechend skalieren (Stufe 2)
Nachteilsausgleich + Level-Unlocks:
nachteilsausgleich(Boolean) — wenntrue, darf Schüler*in alle Level frei wählen, auch im Auftragsmodus (siehe level-unlock-konzept.md)levelUnlocks(Object) — MapmoduleSlug → { highestUnlocked, highestCompleted, bestScorePerLevel, attemptsPerLevel }. Modul nutzt das im freien Modus, um die Level-Auswahl zu rendern.
Locale und Country:
locale— der effektive Locale-Code (kombiniert aus Profil + Modus)country— Kurz-Code des Heimat-Landes (AT,DE,CH, ...) für geografisch sinnvolle Default-Beispiele (z.B. „Hauptstadt deines Landes")
Response 401: Token ungültig → Modul zeigt „Bitte erneut einloggen"
und ruft parent.location = '/v2beta/' auf.
API: Resume-State holen (wenn resume=1)
GET /v2beta/api/module/state?slug=logistik
Authorization: Bearer <session_token>
Response 200 (wenn Stand existiert):
{
"exists": true,
"lastUpdated": "2026-05-15T14:23:00Z",
"state": {
"<modul-spezifisches JSON>": "..."
},
"summary": "Tag 3, Level 2, 4 von 8 Aufträgen erledigt"
}
Response 200 (kein Stand):
{ "exists": false }
Modul speichert seinen State per PUT /v2beta/api/module/state
(siehe Output-API).
API: Glossar-Tooltip holen
GET /v2beta/api/glossary/intermodalverkehr?lang=de-AT-easy
Authorization: Bearer <session_token>
Response 200:
{
"slug": "intermodalverkehr",
"title": "Kombi-Verkehr",
"shortText": "Wenn du Sachen erst mit dem Lkw und dann mit der Bahn schickst.",
"longTextHtml": "<p>...</p>",
"imageUrl": "/v2beta/assets/glossar/intermodalverkehr.png"
}
Modul nutzt das für Tooltip/Modal beim Tap auf einen Fachbegriff. Plattform cached pro Sprache.
API: Runtime-Config holen (Pflicht beim Start)
Beim Start (vor dem ersten Heartbeat) holt das Modul die Plattform- Konfiguration. Werte können von einer Lehrperson mit Admin-Rolle im Admin-Board justiert werden — Modul nutzt sie statt fixer Konstanten.
GET /v2beta/api/runtime-config
Authorization: Bearer <session_token>
Response 200:
{
"heartbeat": { "minIntervalS": 10, "maxIntervalS": 30 },
"stuck": { "thresholdS": 90 },
"telemetry": { "rateLimitPerS": 1, "eventCapPerSession": 2000, "retentionDays": 30 },
"auth": { "tokenTTLs": 3600, "refreshWindowS": 300 }
}
Modul wählt Heartbeat-Intervall innerhalb der Plattform-Grenzen (Default 10–30s): ruhige Module eher Richtung 30s, schnelle Richtung 10s. Stuck-Schwellwert wird vom Modul übernommen (kein Override).
Plattform-Helper-Lib telemetry-client.js macht das transparent — Modul
muss den Endpoint nicht selbst aufrufen, wenn die Lib genutzt wird.
API: Lehrplan-Anker holen (wenn das Modul es braucht)
GET /v2beta/api/lehrplan/anker/AT-GW-1.4.2
Authorization: Bearer <session_token>
Response 200:
{
"code": "AT-GW-1.4.2",
"country": "AT",
"scheme": "GW",
"level": "Sekundarstufe 1, Klasse 2",
"topic": "Wirtschaftsräume Europas",
"competence": "Verkehrsnetze beschreiben und bewerten"
}
Lehrplan-Codes sind immer mit Land-Prefix (AT-..., DE-...,
CH-...). Module sollen Codes ihres lehrplanAnker-Manifests
referenzieren, nicht hardcoden.
Was das Modul NICHT direkt darf
- ❌ Direkter Zugriff auf
students,classes,teachers,licenses,assessmentsTabellen (alles via API) - ❌ Eigene Login-Logik bauen
- ❌ Cookies setzen mit Session-Daten (nur eigene Modul-Cookies erlaubt)
- ❌ Andere Module aufrufen oder deren DB-Tabellen lesen
- ❌ Glossar-Datenbank direkt querien (nur API)
Was das Modul darf
- ✅ Eigene
m_<slug>_*-Tabellen frei nutzen (CRUD per eigene PHP-Endpoints unter<modul>/server/) - ✅ Eigene Modul-Cookies setzen (z.B. „Tutorial gesehen")
- ✅ localStorage frei nutzen (für UI-State, nicht für Lerndaten)
- ✅ Externe APIs aufrufen (z.B. OSRM, Tile-Server) — auf eigene Verantwortung
✅ Geklärt mit Thomas (2026-05-17)
- Token-TTL: Default 1h mit Auto-Refresh-Fenster 5min vor Ablauf.
Wert ist Admin-konfigurierbar (siehe
/api/runtime-config). mode=assessment: wird dem Sch*in sichtbar angezeigt („Du bearbeitest eine Bewertung — keine Tipps verfügbar"), damit sie weiß warum sich das Modul anders verhält.- Modul-eigene PHP-Endpoints: dürfen mit
session_tokenaufgerufen werden, müssen aber das Token viav2_auth_require()selbst verifizieren. Plattform-Helper steht zur Verfügung (v2-platform/php/lib/auth.phpincluden).