Files
geograsim/v2-modules/_spec/telemetry-api.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

197 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Vertrag 4: Telemetry-API (Pflicht)
Was ein Modul **kontinuierlich** während der Sitzung an die Plattform
pushen muss, damit das Lehrer-Live-Dashboard funktioniert.
**Das ist Spec-Pflicht, kein Add-on.** Wer keine Telemetry liefert,
wird nicht integriert. Live-Sicht für Lehrpersonen ist der
pädagogische Kern-USP von GeoGraSim — Module müssen sie tragen.
## Drei Event-Typen
### 1. Heartbeat — alle 1030 Sekunden bei Aktivität
Sagt: „Schüler*in ist da, aktueller Stand ist X."
```http
POST /v2beta/api/telemetry
Authorization: Bearer <session_token>
Content-Type: application/json
{
"type": "heartbeat",
"moduleSlug": "logistik",
"moduleVersion": "2.0.0",
"phase": "auftrag-bearbeiten",
"phaseLabel": "Auftrag wird bearbeitet",
"step": "3/7",
"currentScore": 42,
"scoreMax": 100,
"timeInPhaseS": 252,
"totalTimeS": 1023,
"ts": "2026-05-15T14:23:45Z"
}
```
| Feld | Pflicht | Beschreibung |
|---|---|---|
| `type` | ✓ | `"heartbeat"` |
| `moduleSlug` | ✓ | aus Manifest |
| `moduleVersion` | ✓ | aus Manifest |
| `phase` | ✓ | Modul-interne Phase-ID (string, frei wählbar) |
| `phaseLabel` | ✓ | Anzeigename der Phase für Lehrer-Dashboard |
| `step` | | „X/Y"-Format wenn Modul Schritt-Konzept hat, sonst weglassen |
| `currentScore` | | aktueller Score wenn vorhanden |
| `scoreMax` | | maximaler Score wenn vorhanden |
| `timeInPhaseS` | ✓ | Sekunden in der aktuellen Phase |
| `totalTimeS` | ✓ | Sekunden seit Modul-Start (ohne Pausen >5min) |
| `ts` | ✓ | ISO-Timestamp |
**Frequenz**: aus `/api/runtime-config` (Default 1030s). Modul wählt
innerhalb der Plattform-Grenzen, je nach Geschwindigkeit. Bei sehr
schnellen Modulen (Klick-Spiel) eher 10s, bei Reflexions-Modulen 30s.
**Bei Inaktivität (Schüler*in hat 60s nichts getan)**: Heartbeat
pausieren bis wieder Aktivität.
Plattform-Helper-Lib `telemetry-client.js` macht das transparent — Modul
übergibt seine bevorzugte Frequenz, Lib clamped auf Plattform-Grenzen.
### 2. Milestone — bei definiertem Fortschritt
Sagt: „Schüler*in hat etwas Konkretes geschafft."
```json
{
"type": "milestone",
"moduleSlug": "logistik",
"milestoneId": "first-order-accepted",
"milestoneLabel": "Erster Auftrag angenommen",
"scoreDelta": 15,
"currentScore": 42,
"phase": "auftrag-bearbeiten",
"ts": "..."
}
```
| Feld | Pflicht | Beschreibung |
|---|---|---|
| `type` | ✓ | `"milestone"` |
| `milestoneId` | ✓ | Aus `manifest.telemetryMilestones[].id` |
| `milestoneLabel` | ✓ | Anzeigetext |
| `scoreDelta` | | Punkte für diesen Milestone (kann negativ sein) |
**Wichtig**: `milestoneId` muss vorab im Manifest deklariert sein.
Plattform lehnt unbekannte IDs ab. Erweiterung erfordert Modul-Update.
### 3. Stuck — bei Inaktivität trotz aktivem Tab
Sagt: „Schüler*in zögert / hängt fest. Lehrperson sollte hinschauen."
```json
{
"type": "stuck",
"moduleSlug": "logistik",
"phase": "auftrag-bearbeiten",
"phaseLabel": "Auftrag wird bearbeitet",
"step": "4/7",
"idleS": 95,
"lastActionLabel": "Container ausgewählt",
"hint": "Möglicherweise unsicher bei Routenwahl",
"ts": "..."
}
```
| Feld | Pflicht | Beschreibung |
|---|---|---|
| `type` | ✓ | `"stuck"` |
| `idleS` | ✓ | Sekunden seit letzter sinnvoller Eingabe |
| `lastActionLabel` | | Was war die letzte Aktion (Lehrperson-Hilfe) |
| `hint` | | Modul-Diagnose was wahrscheinlich los ist |
**Wann auslösen**: bei `idleS >= 90` Sekunden ohne sinnvolle
Eingabe (Mouse-Move zählt nicht, Klick/Tap/Drag schon). Sobald
wieder Aktivität: einmaliger neuer Heartbeat, kein „unstuck"-Event.
### 4. Accessibility-Blocker — bei A11y-Hindernis
Sagt: „Schüler*in mit A11y-Bedarf kann an dieser Stelle nicht weiter."
```json
{
"type": "accessibility-blocker",
"moduleSlug": "logistik",
"blockerType": "visual-required",
"hint": "Karten-Tap zur Routenwahl ist nicht per Tastatur ersetzbar in dieser Modul-Version",
"phase": "auftrag-bearbeiten",
"ts": "..."
}
```
| Feld | Pflicht | Beschreibung |
|---|---|---|
| `type` | ✓ | `"accessibility-blocker"` |
| `blockerType` | ✓ | `"visual-required"` / `"audio-required"` / `"mouse-required"` / `"motor-required"` |
| `hint` | ✓ | Was genau ist das Hindernis (für Lehrperson) |
**Wann auslösen**: wenn das Modul aus den Profil-Settings sieht
(`preferences.screenReader === true` o.ä.), dass eine Aufgabe für
diese Schüler*in nicht bearbeitbar ist. Lehrer-Cockpit zeigt das
prominent — Lehrperson kann ein anderes Modul anbieten.
## Idempotenz und Reliability
- Plattform akzeptiert dasselbe Event mehrfach (z.B. nach Netz-Hiccup);
Deduplizierung über `ts` + `type` + `moduleSlug` + `session_token`
- Modul soll bei Netz-Fehler **maximal 1× retryen**, dann verwerfen
(kein Endlos-Queue im Browser, sonst Memory-Leak)
- Bei Tab-Close: ein finaler Heartbeat mit `type: "heartbeat"` und
`phase: "tab-closed"` falls möglich (`navigator.sendBeacon`)
## Was die Plattform damit macht
- **Tabelle `telemetry_events_v2`** — alle Events landen dort
- **Live-Push an Lehrer-Dashboard** via Server-Sent-Events
(`/v2beta/api/teacher/live-stream?classId=42`)
- **Lehrer-Dashboard zeigt pro Schüler*in**:
- Aktuelles Modul + Phase + Step
- Score-Bar
- Zeit in aktueller Phase (rot wenn >> erwartet)
- Stuck-Indikator (orange Warning bei aktivem Stuck-Event)
- Letzter Milestone
## Performance-Limits
- Plattform nimmt **maximal 1 Event pro Sekunde pro Schüler*in** an.
Mehr wird gedrosselt (HTTP 429).
- Pro Sitzung **maximal 2000 Events**. Danach werden Heartbeats
ignoriert (Milestones noch akzeptiert).
- Payload-Max: 4 KB pro Event.
## Mock-Endpoint für Modul-Entwicklung
Während der Modul-Entwicklung (vor Integration) liefert die Plattform
einen Mock-Endpoint:
```
http://localhost/v2beta-mock/api/telemetry
```
Akzeptiert alle Events, gibt 200 OK zurück, loggt nach
`v2-platform/logs/mock-telemetry.log`. Modul-Instanzen können damit
ihren Code testen, bevor sie liefern.
## ✅ Geklärt mit Thomas (2026-05-17)
- **Heartbeat-Frequenz**: Modul wählt selbst innerhalb der Plattform-
Grenzen (`/api/runtime-config`, Default 1030s). Admin-Board justierbar.
- **Stuck-Schwellwert**: zentrale Plattform-Konfig (Default 90s).
Module können im Manifest keinen eigenen Wert setzen — wenn ein
Modul stark abweichende Werte braucht, im Inbox-Ping an Atlas
begründen.
- **Stuck-Events**: vorerst nur visuell im Lehrperson-Dashboard
(Rot-blinkender Indikator), keine Push-Notifications. Push folgt
in Phase 2 wenn Auto-Tuning + Alerting kommt.
- **Speicherdauer**: 30 Tage Default, Admin-konfigurierbar bis 365 Tage.
Für Bildungsforschungs-Auswertungen einzelne Klassen auf 90 Tage
oder mehr hochsetzen.