Files
3d.lehrstun.de/docs/routen.md
Hans Puettmann 76addcb846 Herr Rechmann + L3-Titel + L2-Workflow
Drei Aenderungen aus Herbs Feedback:

1. Markus -> Herr Rechmann (60 Treffer in 26 Dateien + DB-Lektionen L2/L3)
   Konvention: Herb bleibt 'Herb' (interne Anrede fuer Claude), Markus
   wird in SuS-sichtbaren Texten als 'Herr Rechmann' ausgeschrieben.
   Wo 'Herb und Markus' stand -> 'Herb und Herr Rechmann'. Wenn das
   stilistisch zu uneinheitlich wirkt, koennen wir Herb spaeter auch
   in SuS-Texten zu 'Herr Puettmann' umziehen.

2. L3-Titel: 'Customizer — parametrisches 3D-Modell anpassen'
   -> 'Mein eigenes 3D-Modell designen'
   Begruendung Herb: 'Customizer' + 'parametrisch' wirken abschreckend.
   Methode kommt in den Aufgabe-Text, nicht in den Titel.

3. L2-Inhalt komplett geschrieben (~4.8 KB):
   - 8-Schritte-Workflow vom Stoebern auf Printables bis zum
     Druck-Abholen
   - A1-mini-Spezifika klar markiert (offen → nur PLA, 18×18 cm)
   - P-Serie-Spezifika fuer groessere Drucke
   - Tipps zur Modell-Wahl (klein anfangen, 4+ Sterne)
   - Was-tun-wenn-Tabelle bei Druckproblemen
   - Lehrer-Eskalations-Pfad: pausieren via Handy-App + Lehrer rufen

   Quellenlage: PDF-Anleitung A1 mini im OneDrive + Bambu-Wiki online
   waren beide nicht maschinell zugaenglich (pdftoppm fehlt, Wiki
   gibt HTTP 402). Workflow basiert auf Standard-Bambu-Studio-Bedienung
   + Konsistenz mit der L1-P2S-Beschreibung. Herb/Herr Rechmann pruefen
   die A1-mini-Spezifika beim Lehrer-Test und korrigieren via Inline-Edit
   (oder per Migration, wenn Inline-Edit-UI noch nicht live ist).
2026-05-24 19:51:19 +02:00

7.1 KiB

type, projekt, stand, tags
type projekt stand tags
konzept-modul 3d.lehrstun.de 2026-05-24
konzept
routen
api

Routen

Vollständige Routen-Liste. Live im Code: app.py + routes/*.py (V8: Blueprint-Struktur, siehe ../decisions#E-020). Welche Etappe was baut: etappen. Selbstlern-Loop-Details: selbstlern-loop. Lehrer-Dashboard: lehrer-dashboard.

Blueprint-Aufteilung (V8)

Blueprint-Datei URL-Präfix Inhalt
routes/oeffentlich.py / (kein Präfix) Startseite, Lektionen, Software, Projekt-Katalog, Drucker, Troubleshooting
routes/profil.py /cockpit, /login Login, Cockpit, Projekt-Workflow, Slots, Druckaufträge
routes/admin.py /admin Dashboard, Profile, Lektionen, Projekt-Freigabe, Inline-Edit
routes/api.py /api JSON-Endpunkte für Frontend-Polling
services/bambu.py (kein HTTP) Bambu-Cloud-API-Wrapper, isoliert für späteren Austausch
services/datei.py (kein HTTP) File-BLOB-Handling, abstrahiert für spätere Object-Storage-Migration

Öffentlich (routes/oeffentlich.py)

Methode Pfad Zweck Etappe
GET / Startseite ✓ skelett
GET /lektionen Onboarding-Pfad + freie Module 3
GET /lektion/<nr> Einzelne Lektion 3
GET /software Software-Tools 3
GET /software/<slug> Software-Detail 3
GET /projekte Projekt-Katalog (mit Filter: tag, level, erfolg, macher) 6
GET /projekte/<id> Projekt-Detail (Cover, Beschreibung, Files, Bewertung, Macher) 6
GET /projekte/datei/<id> Datei-Download (mit Auth-Check, sichtbar_in_ag prüfen) 6
GET /troubleshooting Entscheidungsbaum + Suchliste 3
GET /drucker 4 Drucker live 5

Profil (routes/profil.py — eingeloggt)

Methode Pfad Zweck Etappe
GET /login Profil-Kacheln (Vorname + Tier) 1
POST /login/<profil_id> PIN-Eingabe (Rate-Limit + persistenter Lockout) 1
GET /logout Abmelden 1
GET /cockpit Progressiv (V1): zeigt nur was zum Status passt 2
POST /cockpit/check-in Stunden-Beginn-Abfrage (V3: 1 Radio, 1 optionaler Freitext, "weiter wie bisher" als Default) 2
POST /cockpit/lektion/<nr>/status Onboarding-Lektion als fertig/läuft markieren (V2-relevant) 3
GET /cockpit/projekt/neu Projekt anlegen (mit Vorlage-Auswahl aus Katalog) 6
POST /cockpit/projekt/neu Speichern 6
POST /cockpit/projekt/<id>/edit Projekt-Details anpassen (während in_arbeit) 6
GET /cockpit/projekt/<id>/abschluss Abschluss-Checkliste (V4: 3 Pflicht-Felder) 6
POST /cockpit/projekt/<id>/abschluss Abschluss absenden → Status wartet_auf_freigabe 6
POST /cockpit/projekt/<id>/datei Datei hochladen (30 MB Limit) 6
POST /cockpit/projekt/<id>/datei/<dateiid>/loeschen Eigene Datei entfernen 6
POST /cockpit/projekt/<id>/rueckfrage/<rid>/erledigt Rückfrage als erledigt markieren (V6) 6
GET /cockpit/druckauftraege Eigene Auftragsliste 7
POST /cockpit/druckauftrag/neu Auftrag eintragen 7
GET /cockpit/slots Slot-Kalender (eigene + freie) — gesperrt bis L1 fertig (V2) 6
POST /cockpit/slot/reservieren Neuen Slot buchen — gesperrt bis L1 fertig 6
POST /cockpit/slot/<id>/stornieren Slot zurückgeben 6
POST /cockpit/paarung/anfragen/<andere_id> Paar-Anfrage 2
POST /cockpit/paarung/aufloesen Paar trennen 2

Admin (routes/admin.py — Herb + Herr Rechmann)

Methode Pfad Zweck Etappe
GET /admin/login Passwort-Eingabe 1
GET /admin/dashboard Drill-Down (V5): „Wer ist heute hier / Wartet auf Review / Wer hängt fest" 2
GET /admin/profile Liste + Edit 1
POST /admin/profil/neu Neues SuS-Profil + PIN-Generation 1
GET /admin/profile/karten Druckbogen PIN-Karten (CSS-Print) 1
GET /admin/projekt-freigabe Review-Queue mit Badge im Dashboard 6
GET /admin/projekt-freigabe/<id> Detail-Review mit Three.js-Vorschau + Edit-Möglichkeit 6
POST /admin/projekt/<id>/freigeben Projekt freigeben (mit optionaler Eigenbearbeitung) 6
POST /admin/projekt/<id>/rueckfrage Rückfrage stellen → Status rueckfrage + Notiz im Cockpit 6
POST /admin/projekt/<id>/loeschen Hartes Löschen mit Bestätigung (Audit-Log behält Datum + Lehrer + SuS-Name) 6
POST /admin/projekt/<id>/datei-aus-3d Three.js-Screenshot als Cover speichern (von Detail-Review aus) 6
GET /admin/druckauftraege Queue + Freigabe-UI 7
POST /admin/druckauftrag/<id>/freigeben Lange Drucke explizit freigeben 7
POST /admin/slot/<id>/prioritaet Slot-Priorität setzen 6
POST /admin/slot/<id>/verschieben Slot bei Drucker-Ausfall auf anderen Drucker 6
GET /admin/drucker Drucker-Stammdaten + manueller Status 5
POST /admin/drucker/<id>/manueller_status Override bei API-Ausfall 5
GET/POST /admin/lektionen Lektionen-CRUD 3
GET /admin/einstellungen Konfig-Werte (auch Tag-Vorschläge) 1
POST /admin/inline-edit Universal-Endpoint für Inline-Edit (Whitelist!) 1

API (routes/api.py — JSON für Frontend-Polling)

Methode Pfad Liefert Frequenz
GET /api/drucker/status JSON aller 4 Drucker mit Status/Restzeit alle 30 s im Frontend
GET /api/slots/heute JSON aller aktiven/anstehenden Slots heute alle 60 s
GET /api/projekte/suche?q=...&tag=...&erfolg=... Projekt-Filter-Ergebnis als JSON (für Live-Suche im Katalog) on-demand
GET /api/admin/dashboard-zahlen Badge-Zahlen für Admin-Dashboard beim Page-Load

Inline-Edit-Whitelist (ERLAUBTE_INLINE_TABELLEN)

Pattern aus Arduino-Kurs (app.py:~1530-1550). Pro Tabelle und Feld definiert, was editiert werden darf.

ERLAUBTE_INLINE_TABELLEN = {
    "lektion": {"titel", "aufgabe_md", "tipp_md", "extern_link"},
    "projekt": {"titel", "beschreibung_md", "tags"},  # bei Lehrer-Review zusätzlich
    "einstellung": {"wert"},
    "software_seite": {"titel", "inhalt_md", "url", "quickstart_md"},
    "drucker": {"name", "notiz"},
}

# Zeitliche Begrenzung beim Projekt: Lehrer darf alle Felder editieren,
# aber nur wenn projekt.freigabe_status IN ('wartet_auf_freigabe', 'rueckfrage')

Jede Änderung loggt in aenderung_log (Tabelle, Datensatz-ID, Feld, alter Wert, neuer Wert, Lehrer-Profil-ID).

Sicherheit

  • Admin-Routen via @admin_required-Decorator (Passwort aus .env).
  • Profil-Routen via @login_required (Session-basiert).
  • Slot-Buchung zusätzlich via @onboarding_l1_fertig (V2).
  • Inline-Edit-POST mit CSRF-Token.
  • Login: persistenter Lockout über login_lockout-Tabelle (V7). Fenster: 5 Versuche / 5 Min, danach 15 Min Sperre.
  • Datei-Download nur wenn sichtbar_in_ag=1 und SuS eingeloggt; Lehrer sieht immer alles.
  • Hartes Löschen (V3-Aktion) mit Audit-Log (Datum, Lehrer, SuS, Grund optional) — Dateien sind danach weg.