Files

127 lines
7.1 KiB
Markdown
Raw Permalink Normal View History

2026-05-24 18:56:59 +02:00
---
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)
2026-05-24 18:56:59 +02:00
| 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.