Schwester-Projekt zu arduino.lehrstun.de fuer die 3D-Druck-AG am Lessing-Gymnasium. Offene jahrelange Nachmittags-AG (kein Trimester), 8-10 Einzel-SuS mit optionalen 2er-Paarungen, 4 Bambu-Lab-Drucker (3 geschlossen + 1 A1 mini). Konzept v2 (Reality-Check-Iteration 2026-05-24): - Onboarding-Pfad statt Pflicht-Lektionen (L1-L3 selbst-zertifiziert) - Selbstlern-Loop als Kern: SuS-Projekte wachsen die interne Bibliothek - Drill-Down-Lehrer-Dashboard (Wer ist hier / Wartet Review / Haengt fest) - Cockpit progressiv: zeigt nur was zum Status passt - Bambu-Cloud-API fuer Drucker-Live-Status (fragil + Fallback manuell) - Three.js-Vorschau fuer Cover-aus-3D-Ansicht (Etappe 6) - Vollstaendige Doku als Obsidian-Vault (24 Markdown-Dateien) - Entscheidungen E-001 bis E-022 in docs/decisions.md Etappe 1 lauffaehig (~1800 Zeilen Code): - Blueprint-Struktur (V8): routes/oeffentlich+profil+admin+api, services/auth+bambu+datei - Komplettes Schema in database.py (14 Tabellen, idempotent) - Login mit bcrypt + persistentem Lockout in DB (V7, verbessert ggue Arduino-Kurs der In-Memory-Dict nutzt) - Admin-Login + Profile-CRUD + PIN-Reset + PIN-Karten-Druckbogen - Inline-Edit-Endpunkt mit Whitelist + Audit-Log - Seeds: AG lessing-3d-ag + 4 Drucker + Default-Einstellungen - Smoke-Test bestanden (Login, Profil-Anlage, Lockout-Logging) Nicht im Repo (.gitignore): .env, *.db, venv/, .obsidian/workspace.json
7.1 KiB
7.1 KiB
type, projekt, stand, tags
| type | projekt | stand | tags | |||
|---|---|---|---|---|---|---|
| konzept-modul | 3d.lehrstun.de | 2026-05-24 |
|
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 + Markus)
| 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=1und SuS eingeloggt; Lehrer sieht immer alles. - Hartes Löschen (V3-Aktion) mit Audit-Log (Datum, Lehrer, SuS, Grund optional) — Dateien sind danach weg.