Files
geograsim/v2-platform/lib/README.md
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- 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>
2026-07-08 02:27:02 +02:00

4.9 KiB
Raw Blame History

V2 Plattform-Bibliotheken

Helfer-Libs für V2-Module, sparen Boilerplate. ESM, keine Build-Step, keine Dependencies.

Verfügbar

Lib Zweck
telemetry-client.js Telemetry, Profil, runtime-config, State, Result. Spec-Vollständig.

TelemetryClient — Quickstart

import { TelemetryClient } from '../../../v2-platform/lib/telemetry-client.js';

// 1. Instanz
const tc = new TelemetryClient({
  moduleSlug: 'hallo-welt',
  moduleVersion: '1.0.0',
  specVersion: '1.0',
});

// 2. Init (holt runtime-config + profile, startet Heartbeat + Stuck-Detection)
await tc.init();

// 3. Profil + Session sind jetzt verfügbar
console.log(tc.profile);   // { displayName, avatarUrl, easyLanguage, nachteilsausgleich, levelUnlocks, ... }
console.log(tc.session);   // { mode, difficulty, lang, classId, studentId, isMock, ... }

// 4. Phase wechseln (Lehrperson-Dashboard sieht das live)
tc.setPhase('welcome', 'Begrüßung');

// 5. Milestone emittieren
tc.milestone('welcome-shown', 'Begrüßung gesehen', /* scoreDelta */ 1);

// 6. Score aktualisieren (fließt in nächste Heartbeats)
tc.updateScore(42, 100);

// 7. Resume-State speichern (regelmäßig oder bei Milestones)
await tc.saveState({ ...modulInternerState }, 'Tag 3, Level 2');

// 8. Modul abschließen (sendet Result-POST + cleanup)
await tc.complete({
  completed: true,
  lehrplanCoverage: { 'AT-GW-1.4.2': 'full' },
  freeTextAnswers: [],
  moduleSpecificData: { /* modul-eigene Kennzahlen */ },
});

// 9. Bei manuellem Abbruch (z.B. ✕-Klick)
tc.exit('user-cancelled');

Was die Lib für dich erledigt

  • URL-Param-Parsingsession_token, mode, difficulty, lang, class_id, student_id, mock=1
  • Runtime-Config — Heartbeat-Frequenz wird auf Plattform-Grenzen geclampt (Default 1030s)
  • Heartbeat-Loop — alle X Sekunden automatisch, pausiert bei AFK (>60s ohne Eingabe)
  • Stuck-Detection — bei >90s ohne Eingabe wird Stuck-Event gefeuert (Schwellwert aus runtime-config)
  • Tab-Close-Beacon — navigator.sendBeacon-Final-Heartbeat
  • Fehlertoleranz — Telemetry-Fetches die scheitern blockieren das Modul nicht (silent fail)
  • Token-Expired-Handling — bei 401 default Redirect zu /v2beta/, im iframe wird nur Warnung geloggt
  • Mock-Erkennung — wenn ?mock=1, geht alles automatisch gegen die Mock-Plattform

Was du selbst tun musst

  • Activity-Tracking für click/touchstart/keydown macht die Lib automatisch (an document registriert)
  • A11y-Profil auswertentc.profile.preferences.highContrast etc. → Modul setzt body[data-high-contrast="…"]
  • Easy-Sprache ladentc.session.lang zeigt was geladen werden soll
  • Level-Unlock-Sichttc.profile.levelUnlocks[moduleSlug] für freien Modus
  • Nachteilsausgleichtc.profile.nachteilsausgleich === true → Level-Wähler statt Auftrags-Vorgabe

API-Referenz

Konstruktor

new TelemetryClient({
  moduleSlug: string,         // PFLICHT
  moduleVersion: string,      // PFLICHT
  specVersion: string,        // PFLICHT
  heartbeatPreferenceS?: number,    // default 15
  onProfileLoaded?: (profile) => void,
  onError?: (err) => void,
  onTokenExpired?: (reason) => void,
})

Methoden

Methode Zweck
init() Async. Holt runtime-config + profile, startet Heartbeat + Stuck-Loop.
setPhase(phase, label?, step?) Phase wechseln; löst sofort einen Heartbeat aus.
updateScore(score, scoreMax?) Score aktualisieren. Wird in nächsten Heartbeats mitgesendet.
milestone(id, label, scoreDelta?) Milestone-Event posten (id muss im Manifest deklariert sein).
accessibilityBlocker({blockerType, hint}) A11y-Blocker melden.
saveState(state, summary?) Resume-State speichern (PUT /api/module/state).
complete(result) Result-POST + Cleanup. Ruft destroy() automatisch.
exit(reason?) Abbruch melden + Cleanup.
destroy() Manueller Cleanup (Timer + Listener entfernen).
elapsedTotalS(), elapsedPhaseS() Hilfs-Getter für Sekunden seit Start / Phase-Start.

Properties (nach await init())

Property Inhalt
tc.profile Schüler*innen-Profil (/api/student/me-Response inkl. Nachteilsausgleich + Level-Unlocks)
tc.config Runtime-Config-Werte (heartbeat, stuck, telemetry, auth)
tc.session URL-Param-Werte (sessionToken, studentId, classId, mode, difficulty, lang, resume, isMock)

Bekannte Limitierungen

  • Token-Auto-Refresh ist Stub. Echte Refresh-Logik kommt mit V2-Login. Aktuell: bei Token-Ablauf (401) → Redirect zu /v2beta/.
  • onTokenExpired Callback kann das überschreiben, falls Modul eigene Handhabung will (z.B. iframe-Eltern benachrichtigen).
  • Mock-Erkennung über ?mock=1-URL-Param. Wenn dein Modul-Wrapper-Pfad nicht v2-modules/<slug>/public/ ist, musst du apiBase selbst überschreiben (nicht in der API vorgesehen — am besten Pfad anpassen).