Files
geograsim/App/Don_t_Deploy/REVIEW-TODO-2026-08-14.md
T

110 lines
13 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.
# GeoGraSim — Komplett-Review & ToDo (2026-08-14)
## ✅ ERLEDIGT (Batch 1, 2026-08-14, deployed + Prod)
- **#2 IDOR progress.php** — student_id-Zweig verlangt jetzt Lehrer-Login + Klassenbesitz (403 sonst).
- **#3 licenses.php** — `?admin=1` + `generate` nur noch echter Admin (`$_SESSION['admin_id']`); Collision-Retry mit Cap gegen Endlosschleife.
- **#4 .env-Deny** — `<FilesMatch>` für `.env*/.sh/.sql/.bak` in .htaccess (Docroot aktualisiert); `.env` weiterhin 404 (verifiziert).
- **#6 Schüler-Ergebnisse** — sim-metrics.js + .ivm-CSS in schueler.html; `renderOwnRunCard`-Fallback zeigt Sterne + grafische Kacheln für die 9 bisher leeren Sims.
- **#13 klima-Budget** — SIM_METRICS `final_budget` als „Mio €" (statt „€").
- **#7 Assessments-Aufblähung** — assessment.php skippt phase running/started; heli-30s-Ping entfernt; Altlast bereinigt (lokal 8678→276, Prod 1696→197).
- **#9/#16 Cockpit/Matrix-Performance** — akute Last schon durch #7 gekappt (Scan ~200 statt 8000 Zeilen); zusätzlich Indizes `assessments(class_id,submitted_at)` + `student_results(class_id,completed_at)` gesetzt (lokal+Prod). APCu nicht verfügbar → App-Cache verworfen; Benchmark-Summary-Tabelle = späteres, größeres Stück falls nötig.
- **#8 String-Identität → student_id-FK (Stufe 1+2)** — `student_sessions.student_id` (Spalte+Index+Backfill, lokal 35/35, Prod 90/91); `Session::createStudent` setzt es künftig; ALLE ~15 Name-Joins (Benchmark, live×5, results×5, modules, profile, progress×2) auf `student_id` umgestellt. Verlustfrei verifiziert (alt==neu, diff=0 auf Prod). Robust gegen Umbenennung. *Rest (optional):* 1 Waisen-Session „Susi1" (kein Schüler), assessments-eigene student_id-Spalte (nicht nötig).
## Geklärt ohne Code-Änderung (Entscheidung Thomas, 2026-08-14)
- **#1 Secrets — Rotieren WEGGELASSEN.** `git push` geht nur an eigenen Gitea (`git.schroffenegger.at:2222`), nichts Öffentliches → Restrisiko akzeptiert. Keine Rotation, kein History-Rewrite.
- **#5 Klartext-Passwörter — WORKS AS DESIGNED.** `password_plaintext` = systemvergebener PIN (druckbar). Lehrperson-Anlage/Reset setzt PIN+Hash; Selbst-Registrierung setzt KEIN plaintext; es gibt keinen Schüler-Selbständerungs-Flow → kein geändertes Passwort liegt je im Klartext. Kein Bug.
- *Zukunfts-Hinweis:* falls je ein Schüler-„Passwort ändern"-Feature gebaut wird, muss es `password_plaintext = NULL` setzen.
## ✅ ERLEDIGT (Batch 2, 2026-08-15 — Balancing sonnensystem + energiemanager)
- **#10 sonnensystem** — Bewertung war bedeutungslos (Lösung sofort aufgedeckt + Endlos-Retry → immer 5★). NEU:
- Falsche Antwort deckt die richtige NICHT mehr auf → nur diese Option wird gesperrt, man wählt weiter (`obsAnswered` umgebaut, `.obs-option.spent`).
- Sterne = **Erst-Treffer-Quote** (persistiert in `sonnensystem_obs_firsttry`), nicht mehr completed/total. Schwellen 0.85/0.68/0.50/0.30.
- `level`-Feld (14) jetzt **genutzt**: Schwierigkeits-Badge pro Aufgabe (Grundlagen/Aufbau/Vertiefung/Profi).
- Endscreen zeigt „Auf Anhieb richtig X/Y". Payload: `firstTryCount`/`firstTryQuote`. Benchmark.php `scoreSonnensystem` nutzt `firstTryQuote` (Fallback = alt). sim-metrics.js: „Auf Anhieb"-Kachel.
- **#11 energiemanager** — kein Fail → immer 5★. NEU:
- **Echter Blackout** an der Netzfrequenz: `freqError` akkumuliert (`·retain + balance·0.10`), Regelreserve zieht zurück; < 49,5 Hz oder > 50,5 Hz → Blackout-Overlay, Tag muss neu geplant werden (Plan bleibt erhalten).
- **Schwierigkeitsrampe** über `retain` je Set (0.45 Frühling → 0.70 Wochenende): früh viel Reserve/verzeihend, spät summieren sich Fehler.
- Frequenz-Tacho zeigt jetzt die **akkumulierte** Frequenz (Wegdriften sichtbar). Blackouts deckeln Sterne (1→max 3★, ≥2→max 2★), erscheinen in Set-Bilanz + `GGS_LIVE_STATE` (phase `blackout`, `blackouts`).
- Numerisch verifiziert: optimales Spiel bleibt 49,950,0 Hz (nie Blackout); grober Richtungsfehler (Pumpen in Abendspitze) → 47,9 Hz → Blackout. Beide game.html + Benchmark.php syntaxgeprüft.
- **Offen/Notiz:** „konkurrierende Stufen" ist über Tank-Zwang + Frequenz-Drift jetzt spürbar, aber echte Mehr-Strategien-Trade-offs bräuchten Config-Redesign (18 Tage neu tunen) → separat mit Thomas. Tank-Übertrag „Speicher von gestern" ist derzeit nur kosmetisch (runDayStepwise resettet auf tankTopInit) — bewusst NICHT angefasst (Solvability). Für Thomas notiert.
- **DEPLOYED + Prod-verifiziert 2026-08-15** (Top-Level + App/, apache graceful) · committed · Gitea-Push ok.
## ❌ GESTRICHEN (Thomas-Entscheidung)
- **Heli-Navigation NICHT erschweren.** Wird nicht mehr angefasst (früheres #19 „Navi-Drittel entschärfen" ist damit erledigt/vom Tisch).
## 📋 OFFENE TODOS (Stand 2026-08-15)
### A · Balancing — weiche Sims (kein echter Verlierzustand/Abschluss)
- **fluss, farmer, tourismustal, weltküche, eu-werkstatt:** je ein sinnvoller Fail/Abschluss (Muster wie energiemanager).
- **fluss:** Level-Skalierung (Wetter/Zeit). **farmer:** Klimahinweis VOR dem Pflanzen + wählbare Level. **busfahrt:** L3-Ziel (35 k) nachrechnen / `fixedFee` aktivieren.
### B · Konsistenz & Verdrahtung
- **#12 Drei Feld-Schemata → eine Quelle** (SIM_METRICS / MODULE_HIGHLIGHTS / LIVE_PRIMARY_FIELDS). Lücken: `fluggesellschaft` in SIM_METRICS+badges.js; `LIVE_PRIMARY_FIELDS` für klima-3d/farmer/logistik.
- **#14 Generischer Live-Vergleich** zeigt „0 %"/rohe Phase für weltkueche/farmer/fluss/logistik/kofferdetektiv/tourismus* (mit #12 lösen).
- **#15 Lehrplan Liechtenstein (FL)** für eu-werkstatt, busfahrt, logistik, tourismusregion.
- **#22 `weltkueche.page_url`** setzen (Info-Button kaputt) · **kofferdetektiv** fehlt `module_info`-Eintrag.
- **#23 `$_SESSION['student_id']` wird nie gesetzt** → Leichte Sprache / per-Schüler-Land greift für Cookie-Schüler nie. Prüfen + fixen.
- **#17 class_modules/class_assignments** transaktional vereinheitlichen (eine autoritative Quelle, `create`+`set_mode` in einem Write).
### C · Sicherheits-Härtung (keine akute Lücke mehr)
- **#21** Login-Throttling/Lockout · `session_regenerate_id(true)` nach Login · Cookie-Flags (HttpOnly/SameSite/Secure) · CSRF/SameSite · Foto-Upload-PIN (`0815`) aus `.env`.
### D · Aufräumen (Wartbarkeit)
- **#25 ~40 MB `.bak`-Müll + `_inbox` + DB-Dumps aus git** + `.gitignore` (macht jeden Push/Deploy schneller). ← größter Sofort-Nutzen
- **#24 Toter Code:** renderLiveCockpit + `_cockpit*`, `toggleAssignmentPause`, `IV_PLABEL`/`ivParams`, altes `ACHIEVEMENTS`.
- **#27** Toter Vite-Build-Stack (`vite.config.ts`, `App/src/`) + verwaiste Sims (wal/landwirtschaft/vulkan/staustufen) klären/entfernen.
- **#26** design-system.css in teacher/schueler einbinden · **#28** Matrix-Spaltenköpfe Kurzname statt Emoji (iPad/a11y) · **#29** `kofferdetektiv/outlines.json` (1,4 MB) lazy laden · **#30** Migrations-Runner + `LIVE_SIM_SHORT` Geister-Module (stadt/regenwald/erdbeben) bereinigen.
---
Read-only-Audit über 6 Dimensionen (Verdrahtung, Darstellungen, Skalierung/DB, Balancing,
Codequalität, Sicherheit). Nichts geändert. Priorisiert P0→P3.
**Positiv vorab:** SQL durchgängig prepared (keine ausnutzbare Injection), Fremd-Inhalte
escaped (keine cross-user-XSS), DB-vs-JSON sauber getrennt (kein Laufzeitzustand in Dateien),
alle 13 aktiven Sims sind grundverdrahtet. Vorbild-Balance: tourismusregion + klima.
## P0 — Sofort (Sicherheit / Datenintegrität)
1. **[Sec] Secrets aus git entfernen + rotieren.** MySQL-Root-PW im Klartext in `Don_t_Deploy/deploy.sh`, `deploy-2026-04-26.sh`, `bulk-reset-lernapps.php`; SMTP-PW-Fallback in `lib/Mailer.php:15`. Blockiert sicheres Gitea-Push. → rotieren, untracken, aus History (BFG/filter-repo).
2. **[Sec] IDOR in `progress.php:34`.** Zweig `if($studentId && $simId)` hat KEINEN Auth-Guard → fremder Fortschritt/Results ohne Login lesbar (ID enumerierbar). Kleiner, dringender Fix.
3. **[Sec] `licenses.php` Access Control.** `?admin=1` (Z.15) autorisiert jede Lehrperson → liest ALLE Lizenzcodes; `action=generate` (Z.173) ohne Admin → 1000 Codes generierbar. An `$_SESSION['admin_id']` binden.
4. **[Sec] `.env`-Deny ergänzen (Defense-in-Depth).** Verifiziert: `.env.production/.local` werden aktuell NICHT ausgeliefert (HTTP 404), aber es gibt keinen bewussten Schutz. `<FilesMatch "^\.env">Require all denied</FilesMatch>` in `.htaccess`.
5. **[Sec] Schüler-Passwörter Klartext.** `students.password_plaintext` (auch im GET). Zugriff strikt auf Ticket-Druck scopen, aus normalem Schüler-GET raus (besser Reset-only).
## P1 — Hoch (Korrektheit / Skalierung / Balancing-kritisch)
6. **[Darstellung] Schüler sehen bei 9/15 Sims keine Ergebnisse.** `renderOwnRunCard` (schueler.html) hat nur 6 Renderer + Fallback zeigt nur Datum/Dauer; `sim-metrics.js` ist in schueler.html NICHT eingebunden. → einbinden + Fallback nutzt `renderSimMetrics(simId,d)`.
7. **[Skalierung] `assessments`-Aufblähung.** `assessment.php:28` immer INSERT; Heli-Ping alle 30 s → 8678 Zeilen bei 31 Schülern, 96,7 % Wegwerf-Telemetrie (phase 'running'). → Zwischenpings NICHT in `assessments` (nur `live_sessions.state_json`) + Purge-Job.
8. **[Skalierung/Code] String-Identität → `student_id`-FK.** Alles per `class_id + display_name` verknüpft (kein FK, unindexiert; „Anna" 16×). Umbenennen/Doppelname zerlegt Historie; Join nicht indexierbar. FK auf `student_sessions` (+`assessments`), ~40 Name-Joins ersetzen.
9. **[Skalierung] Cache-lose Voll-Historien-Aggregation.** `live.php` (benchRows/lastLogin) + `results.php` Matrix scoren die GESAMTE Klassen-Historie pro Poll, alle 4 s. → Datums-/LIMIT-Grenzen + gecachte Benchmark-Aggregate.
10. **[Balancing] sonnensystem — Bewertung bedeutungslos.** Falsche Antwort deckt sofort die richtige auf + Endlos-Retry → immer 5★; `obsShowEnd` nur bei 100 %; `level` 14 ungenutzt. → Score aus Erst-Treffer; Lösung nicht sofort zeigen.
11. **[Balancing] energiemanager — immer 5★, kein Fail.** Eindeutiges Lookup (5er-Schritte) löst alle Sets. → konkurrierende Stufen + echter Blackout-Fail (Frequenz-Tacho) + Schwierigkeitsrampe.
## P2 — Mittel (Konsistenz / Balancing / Skalierung)
12. **[Code/Darstellung] Drei Feld-Schemata konsolidieren** (SIM_METRICS / MODULE_HIGHLIGHTS / LIVE_PRIMARY_FIELDS) → eine Quelle. Sofort-Lücken: `fluggesellschaft` in SIM_METRICS+badges.js; `LIVE_PRIMARY_FIELDS` für klima-3d/farmer/logistik.
13. **[Darstellung] klima `final_budget`** in SIM_METRICS als „Mio €" (aktuell „€", 10⁶ falsch).
14. **[Darstellung] Generischer Live-Vergleich** zeigt „0 %"+rohe Phase für weltkueche/farmer/fluss/logistik/kofferdetektiv/tourismus* (mit #12 lösen).
15. **[Verdrahtung] Lehrplan Liechtenstein (FL)** für eu-werkstatt, busfahrt, logistik, tourismusregion ergänzen (D-A-CH+FL-Regel).
16. **[Skalierung] Indizes:** `assessments(class_id, submitted_at)`, `student_results(class_id, completed_at)`, Join-Seite `student_sessions`.
17. **[Code] class_modules/class_assignments** transaktional vereinheitlichen (eine autoritative Quelle; `create` und `set_mode` in einem Write).
18. **[Balancing] Echter Verlierzustand + Abschluss-Feedback** für die „weichen" Sims: fluss, farmer, tourismustal, weltküche, eu-werkstatt.
19. ~~**[Balancing] heli** Navi-Drittel entschärfen~~**GESTRICHEN (Thomas 2026-08-15): Heli-Navigation bleibt, nicht erschweren.**
20. **[Balancing] fluss** Level-Skalierung (Wetter/Zeit); **farmer** Klimahinweis VOR dem Pflanzen + wählbare Level; **busfahrt** L3-Ziel (35 k) nachrechnen/`fixedFee` aktivieren.
21. **[Sec] Härtung:** Login-Throttling/Lockout, `session_regenerate_id(true)` nach Login, Session-Cookie explizit (HttpOnly/SameSite/Secure), CSRF-Token oder SameSite erzwingen, foto-upload-PIN (`0815`) aus .env.
22. **[Verdrahtung] `weltkueche.page_url`** setzen (Info-Button/href kaputt); **kofferdetektiv** fehlt `module_info`-Eintrag (überall sonst verdrahtet).
23. **[Code] `$_SESSION['student_id']` wird nie gesetzt** → Leichte Sprache / per-Schüler-Land greifen für Cookie-Schüler nie (stiller Fallback). Verifizieren + fixen.
## P3 — Aufräumen (Wartbarkeit / niedrig)
24. **[Code] Toter Code:** `renderLiveCockpit` + ~15 `_cockpit*`-Helfer, `toggleAssignmentPause`, `IV_PLABEL`/`ivParams`, altes `ACHIEVEMENTS` (schueler.html).
25. **[Code] ~40 MB `.bak`-Müll** (347 Dateien, v. a. heli/sounds), `_inbox/` (~300 md), DB-Dumps aus git; `.gitignore` (`*.bak*`).
26. **[Code] design-system.css** in teacher/schueler einbinden (715 bzw. 130 Hex hartkodiert); perspektivisch auf `--ggs-*`.
27. **[Code] Toter Vite-Build-Stack** (`vite.config.ts`, `App/src/`), verwaiste Sims (wal/landwirtschaft/vulkan/staustufen) klären/entfernen.
28. **[Darstellung] Matrix-Spaltenköpfe:** sichtbarer Kurzname statt nur Emoji (a11y/iPad).
29. **[Skalierung] `kofferdetektiv/outlines.json` (1,4 MB)** cachen/lazy laden.
30. **[Code/Infra] Migrations-Runner** (`schema_migrations`) + idempotentes Deploy (`--delete`-Schutz, Mirror-Whitelist entschärfen); `LIVE_SIM_SHORT` Geister-Module (stadt/regenwald/erdbeben) bereinigen.
---
Systemisches Muster Balancing: häufigster Mangel = **fehlender echter Verlierzustand** + „Lösung
aufgedeckt + Endlos-Retry → garantierte Bestnote". Systemisches Muster Code: gute Abstraktionen
existieren, werden aber nicht erzwungen (String-Join, 3 Schemata, design-system.css ungenutzt).