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).
127 lines
7.1 KiB
Markdown
127 lines
7.1 KiB
Markdown
---
|
|
type: konzept-modul
|
|
projekt: 3d.lehrstun.de
|
|
stand: 2026-05-24
|
|
tags: [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.
|
|
|
|
```python
|
|
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.
|