Files
3d.lehrstun.de/docs/etappen.md

206 lines
9.0 KiB
Markdown
Raw Normal View History

2026-05-24 18:56:59 +02:00
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-24
tags: [konzept, plan, etappen]
---
# Implementierungs-Etappen
> Grobe Reihenfolge zum Bauen. Detaillierte Inhalte: [[../kurskonzept]].
> **V8 ([[../decisions#E-020]]): Blueprint-Struktur von Anfang an** — `app.py`
> ist Bootstrap, Routen in `routes/`, externe Services in `services/`.
## Etappe 0 — Skelett (✓ am 2026-05-23)
- [x] Projektordner + CLAUDE.md + README.md + CHANGELOG.md
- [x] [[architektur]] + [[datenmodell]] + [[routen]] + [[druckerapi]] + [[slotsystem]] + [[sicherheit]] + [[etappen]] + [[selbstlern-loop]] + [[lehrer-dashboard]]
- [x] Flask-Skelett (app.py mit Stubs, database.py, tiere.py)
- [x] base.html portiert vom Arduino-Kurs
- [x] [[../COCKPIT]] als Vault-Startseite + .obsidian/-Konfig
- [x] Reality-Check-Iteration mit Selbstlern-Loop, V1-V8 angenommen (2026-05-24)
## Etappe 1 — Basis: Blueprints + Login + Profile + Inline-Edit (✓ am 2026-05-24)
**Blueprint-Refactoring (V8):**
- [x] `routes/oeffentlich.py`, `routes/profil.py`, `routes/admin.py`, `routes/api.py` anlegen
- [x] `services/datei.py` anlegen (abstrahiertes File-Handling, Stubs)
- [x] `services/bambu.py` anlegen (Stub, Implementation folgt in Etappe 4)
- [x] `services/auth.py` anlegen (bcrypt + persistenter Lockout + Decorators)
- [x] `app.py` zur Bootstrap-Datei umbauen (90 Zeilen, Blueprint-Registrierung)
**Schema:**
- [x] `init_db()` aktualisieren mit allen Tabellen aus [[datenmodell]]
- [x] `ag_mitgliedschaft` Initial-Seed („lessing-3d-ag")
- [x] 4 Drucker-Stammdaten als Seeds
- [x] Default-Einstellungen (`tag_vorschlaege`, `default_lockout_dauer_min`, `feedback_widget_aktiv`)
**Login + Profile:**
- [x] Profil-Kacheln-Seite mit Vorname + Tier
- [x] PIN-Eingabe mit `bcrypt`-Check
- [x] **Persistenter Login-Lockout** in `login_lockout`-Tabelle (V7) statt In-Memory wie Arduino
- [x] `/logout`
- [x] Admin-Login mit Passwort aus `.env`
**Profil-Verwaltung im Admin:**
- [x] `/admin/profile` Liste mit aktiv-Toggle, PIN-Reset
- [x] `/admin/profil/neu` mit PIN-Generation (einmalig sichtbar via Flash)
- [x] `/admin/profile/karten` Druckbogen (CSS-Print)
**Inline-Edit-Infrastruktur:**
- [x] `ERLAUBTE_INLINE_TABELLEN`-Dict mit Whitelist (Backend)
- [x] `/admin/inline-edit`-POST mit Audit-Log in `aenderung_log`
- [ ] base.html-JS für Inline-Edit-UI (kommt in Etappe 2, wenn das erste editierbare Feld in der UI sichtbar wird)
- [ ] CSRF-Token (kommt in Etappe 2, sobald Forms wachsen)
Etappe 2: Cockpit progressiv + Check-In + Paarung + Lehrer-Dashboard Cockpit (V1, progressives Layout): - /cockpit zeigt nur Karten, die zum Status passen. Onboarding-Karte nur fuer Neue; Paarungs-Karte immer wenn aktiv; Drucker-Buchung erst nach L1 fertig. - Banner-System: ungelesene Lehrer-Notizen, offene Rueckfragen, eingegangene Paarungs-Anfragen. Check-In (V3 + E-021): - Modal beim ersten Cockpit-Aufruf eines Besuchstages. - "Ich arbeite weiter" als Default-Ein-Klick-Option. - Freitext optional. - POST /cockpit/check-in mit UNIQUE-Constraint pro Tag. Onboarding-Status (E-019): - /cockpit/lektion/<nr>/status (selbst-zertifiziert). - profil_lektion_status-Tabelle, ON CONFLICT-Upsert. Paarung (E-002): - profil_anfrage-Tabelle on-demand. - Anfrage stellen / annehmen / ablehnen / aufloesen. - Konflikt-Check (keine Doppel-Paarungen). - Banner im Cockpit des Adressaten. Lehrer-Dashboard (V5, docs/lehrer-dashboard.md): - /admin/dashboard mit 4 Sektionen (Wer ist heute hier / Wartet auf Review / Drucker-Status / Wer haengt fest) + Schnell-Zahlen + offene Rueckfragen. - "Notiz hinterlassen"-Quick-Action via lehrer_notiz-Tabelle. - Live-Drucker-Status kommt mit Etappe 5 (aktuell nur DB-Stand). Daten-Helper getrennt: - services/cockpit_status.py: Bundle fuer progressives Cockpit - services/dashboard_status.py: 4-Sektionen-Queries Vorgezogen aus Etappe 3: - /lektionen + /lektion/<nr> Minimal-Renderer mit Markdown - 3 Onboarding-Lektionen als Seeds (Platzhalter-Text fuer Markus) Smoke-Test bestanden: Login als neuer SuS -> Onboarding -> Check-In -> L1 fertig -> Paarung mit zweitem SuS -> Admin-Dashboard -> Lehrer-Notiz -> Banner im Cockpit.
2026-05-24 19:13:19 +02:00
## Etappe 2 — Cockpit (progressiv) + Check-In + Paarung + Lehrer-Dashboard (✓ am 2026-05-24)
2026-05-24 18:56:59 +02:00
**Cockpit (V1 — progressives Layout):**
Etappe 2: Cockpit progressiv + Check-In + Paarung + Lehrer-Dashboard Cockpit (V1, progressives Layout): - /cockpit zeigt nur Karten, die zum Status passen. Onboarding-Karte nur fuer Neue; Paarungs-Karte immer wenn aktiv; Drucker-Buchung erst nach L1 fertig. - Banner-System: ungelesene Lehrer-Notizen, offene Rueckfragen, eingegangene Paarungs-Anfragen. Check-In (V3 + E-021): - Modal beim ersten Cockpit-Aufruf eines Besuchstages. - "Ich arbeite weiter" als Default-Ein-Klick-Option. - Freitext optional. - POST /cockpit/check-in mit UNIQUE-Constraint pro Tag. Onboarding-Status (E-019): - /cockpit/lektion/<nr>/status (selbst-zertifiziert). - profil_lektion_status-Tabelle, ON CONFLICT-Upsert. Paarung (E-002): - profil_anfrage-Tabelle on-demand. - Anfrage stellen / annehmen / ablehnen / aufloesen. - Konflikt-Check (keine Doppel-Paarungen). - Banner im Cockpit des Adressaten. Lehrer-Dashboard (V5, docs/lehrer-dashboard.md): - /admin/dashboard mit 4 Sektionen (Wer ist heute hier / Wartet auf Review / Drucker-Status / Wer haengt fest) + Schnell-Zahlen + offene Rueckfragen. - "Notiz hinterlassen"-Quick-Action via lehrer_notiz-Tabelle. - Live-Drucker-Status kommt mit Etappe 5 (aktuell nur DB-Stand). Daten-Helper getrennt: - services/cockpit_status.py: Bundle fuer progressives Cockpit - services/dashboard_status.py: 4-Sektionen-Queries Vorgezogen aus Etappe 3: - /lektionen + /lektion/<nr> Minimal-Renderer mit Markdown - 3 Onboarding-Lektionen als Seeds (Platzhalter-Text fuer Markus) Smoke-Test bestanden: Login als neuer SuS -> Onboarding -> Check-In -> L1 fertig -> Paarung mit zweitem SuS -> Admin-Dashboard -> Lehrer-Notiz -> Banner im Cockpit.
2026-05-24 19:13:19 +02:00
- [x] `/cockpit` rendert je nach Status (services/cockpit_status.py liefert das Bundle)
- [x] Cockpit-Banner für ungelesene Lehrer-Notizen (V5-Quick-Action)
- [x] Cockpit-Banner für offene Rückfragen (V6) — Render-seitig, Daten kommen mit Etappe 6
- [x] Cockpit-Banner für eingegangene Paarungs-Anfragen
2026-05-24 18:56:59 +02:00
**Check-In (V3 + E-021):**
Etappe 2: Cockpit progressiv + Check-In + Paarung + Lehrer-Dashboard Cockpit (V1, progressives Layout): - /cockpit zeigt nur Karten, die zum Status passen. Onboarding-Karte nur fuer Neue; Paarungs-Karte immer wenn aktiv; Drucker-Buchung erst nach L1 fertig. - Banner-System: ungelesene Lehrer-Notizen, offene Rueckfragen, eingegangene Paarungs-Anfragen. Check-In (V3 + E-021): - Modal beim ersten Cockpit-Aufruf eines Besuchstages. - "Ich arbeite weiter" als Default-Ein-Klick-Option. - Freitext optional. - POST /cockpit/check-in mit UNIQUE-Constraint pro Tag. Onboarding-Status (E-019): - /cockpit/lektion/<nr>/status (selbst-zertifiziert). - profil_lektion_status-Tabelle, ON CONFLICT-Upsert. Paarung (E-002): - profil_anfrage-Tabelle on-demand. - Anfrage stellen / annehmen / ablehnen / aufloesen. - Konflikt-Check (keine Doppel-Paarungen). - Banner im Cockpit des Adressaten. Lehrer-Dashboard (V5, docs/lehrer-dashboard.md): - /admin/dashboard mit 4 Sektionen (Wer ist heute hier / Wartet auf Review / Drucker-Status / Wer haengt fest) + Schnell-Zahlen + offene Rueckfragen. - "Notiz hinterlassen"-Quick-Action via lehrer_notiz-Tabelle. - Live-Drucker-Status kommt mit Etappe 5 (aktuell nur DB-Stand). Daten-Helper getrennt: - services/cockpit_status.py: Bundle fuer progressives Cockpit - services/dashboard_status.py: 4-Sektionen-Queries Vorgezogen aus Etappe 3: - /lektionen + /lektion/<nr> Minimal-Renderer mit Markdown - 3 Onboarding-Lektionen als Seeds (Platzhalter-Text fuer Markus) Smoke-Test bestanden: Login als neuer SuS -> Onboarding -> Check-In -> L1 fertig -> Paarung mit zweitem SuS -> Admin-Dashboard -> Lehrer-Notiz -> Banner im Cockpit.
2026-05-24 19:13:19 +02:00
- [x] Modal beim ersten Cockpit-Aufruf eines Besuchstages
- [x] Default-Option „Ich arbeite an X weiter" wenn aktives Projekt vorhanden
- [x] `/cockpit/check-in`-POST speichert in `check_in`-Tabelle (UNIQUE pro Tag)
**Onboarding-Status:**
- [x] `/cockpit/lektion/<nr>/status` (selbst-zertifiziert, E-019)
- [x] Onboarding-Karte mit Lektion-Status-Anzeige + Aktions-Buttons
2026-05-24 18:56:59 +02:00
**Paarung:**
Etappe 2: Cockpit progressiv + Check-In + Paarung + Lehrer-Dashboard Cockpit (V1, progressives Layout): - /cockpit zeigt nur Karten, die zum Status passen. Onboarding-Karte nur fuer Neue; Paarungs-Karte immer wenn aktiv; Drucker-Buchung erst nach L1 fertig. - Banner-System: ungelesene Lehrer-Notizen, offene Rueckfragen, eingegangene Paarungs-Anfragen. Check-In (V3 + E-021): - Modal beim ersten Cockpit-Aufruf eines Besuchstages. - "Ich arbeite weiter" als Default-Ein-Klick-Option. - Freitext optional. - POST /cockpit/check-in mit UNIQUE-Constraint pro Tag. Onboarding-Status (E-019): - /cockpit/lektion/<nr>/status (selbst-zertifiziert). - profil_lektion_status-Tabelle, ON CONFLICT-Upsert. Paarung (E-002): - profil_anfrage-Tabelle on-demand. - Anfrage stellen / annehmen / ablehnen / aufloesen. - Konflikt-Check (keine Doppel-Paarungen). - Banner im Cockpit des Adressaten. Lehrer-Dashboard (V5, docs/lehrer-dashboard.md): - /admin/dashboard mit 4 Sektionen (Wer ist heute hier / Wartet auf Review / Drucker-Status / Wer haengt fest) + Schnell-Zahlen + offene Rueckfragen. - "Notiz hinterlassen"-Quick-Action via lehrer_notiz-Tabelle. - Live-Drucker-Status kommt mit Etappe 5 (aktuell nur DB-Stand). Daten-Helper getrennt: - services/cockpit_status.py: Bundle fuer progressives Cockpit - services/dashboard_status.py: 4-Sektionen-Queries Vorgezogen aus Etappe 3: - /lektionen + /lektion/<nr> Minimal-Renderer mit Markdown - 3 Onboarding-Lektionen als Seeds (Platzhalter-Text fuer Markus) Smoke-Test bestanden: Login als neuer SuS -> Onboarding -> Check-In -> L1 fertig -> Paarung mit zweitem SuS -> Admin-Dashboard -> Lehrer-Notiz -> Banner im Cockpit.
2026-05-24 19:13:19 +02:00
- [x] `profil_anfrage`-Tabelle on-demand angelegt
- [x] `/cockpit/paarung/anfragen/<id>` mit Konflikt-Check
- [x] `/cockpit/paarung/anfrage/<id>/annehmen|ablehnen`
- [x] `/cockpit/paarung/aufloesen`
2026-05-24 18:56:59 +02:00
**Lehrer-Dashboard (V5, [[lehrer-dashboard]]):**
Etappe 2: Cockpit progressiv + Check-In + Paarung + Lehrer-Dashboard Cockpit (V1, progressives Layout): - /cockpit zeigt nur Karten, die zum Status passen. Onboarding-Karte nur fuer Neue; Paarungs-Karte immer wenn aktiv; Drucker-Buchung erst nach L1 fertig. - Banner-System: ungelesene Lehrer-Notizen, offene Rueckfragen, eingegangene Paarungs-Anfragen. Check-In (V3 + E-021): - Modal beim ersten Cockpit-Aufruf eines Besuchstages. - "Ich arbeite weiter" als Default-Ein-Klick-Option. - Freitext optional. - POST /cockpit/check-in mit UNIQUE-Constraint pro Tag. Onboarding-Status (E-019): - /cockpit/lektion/<nr>/status (selbst-zertifiziert). - profil_lektion_status-Tabelle, ON CONFLICT-Upsert. Paarung (E-002): - profil_anfrage-Tabelle on-demand. - Anfrage stellen / annehmen / ablehnen / aufloesen. - Konflikt-Check (keine Doppel-Paarungen). - Banner im Cockpit des Adressaten. Lehrer-Dashboard (V5, docs/lehrer-dashboard.md): - /admin/dashboard mit 4 Sektionen (Wer ist heute hier / Wartet auf Review / Drucker-Status / Wer haengt fest) + Schnell-Zahlen + offene Rueckfragen. - "Notiz hinterlassen"-Quick-Action via lehrer_notiz-Tabelle. - Live-Drucker-Status kommt mit Etappe 5 (aktuell nur DB-Stand). Daten-Helper getrennt: - services/cockpit_status.py: Bundle fuer progressives Cockpit - services/dashboard_status.py: 4-Sektionen-Queries Vorgezogen aus Etappe 3: - /lektionen + /lektion/<nr> Minimal-Renderer mit Markdown - 3 Onboarding-Lektionen als Seeds (Platzhalter-Text fuer Markus) Smoke-Test bestanden: Login als neuer SuS -> Onboarding -> Check-In -> L1 fertig -> Paarung mit zweitem SuS -> Admin-Dashboard -> Lehrer-Notiz -> Banner im Cockpit.
2026-05-24 19:13:19 +02:00
- [x] `/admin/dashboard` mit 4 Sektionen + Schnell-Zahlen + Rückfragen-Liste
- [x] „Notiz hinterlassen"-Quick-Action via `lehrer_notiz`-Tabelle
- [ ] Live-Drucker-Status (kommt mit Etappe 5)
**Lektion-Detail-Seite (vorgezogen aus Etappe 3):**
- [x] `/lektionen` und `/lektion/<nr>` Minimal-Renderer mit Markdown + Status-Buttons (vollständige Version mit Inline-Edit kommt in Etappe 3)
**Seeds:**
- [x] 3 Onboarding-Lektionen mit Platzhalter-Text (Markus fuellt mit Inline-Edit nach)
2026-05-24 18:56:59 +02:00
## Etappe 3 — Lektionen + Software-Sektion + Troubleshooting (1 Sitzung)
- [ ] `/lektionen` mit Onboarding-Pfad-Markierung
- [ ] `/lektion/<nr>` mit Markdown-Rendering + Inline-Edit (für Lehrer)
- [ ] `/cockpit/lektion/<nr>/status` (selbst-zertifizierend, [[../decisions#E-019]])
- [ ] `/software` + `/software/<slug>` (CMS-artig, Inline-Edit)
- [ ] `/troubleshooting` mit Entscheidungsbaum
- [ ] L1-L3 Inhalte ausgearbeitet (mit Markus zusammen, ggf. asynchron)
## Etappe 4 — Drucker-API-Spike (0.5 Sitzung)
- [ ] `scripts/drucker_api_spike.py` — einmalige Abfrage aller 4 Drucker
- [ ] Bambu-Cloud-Credentials in `.env`
- [ ] Validierung: Auth funktioniert, alle 4 Drucker erreichbar, welche Felder liefern sie
- [ ] Entscheidung: `bambulabs_api` direkt nutzen oder Code aus `pybambu` extrahieren
## Etappe 5 — Drucker-Integration + Live-Status (1 Sitzung)
- [ ] `services/bambu.py` implementieren (Poll-Funktion)
- [ ] Poll-Worker als Hintergrund-Thread in Flask (oder eigener systemd-Service)
- [ ] `/drucker` Live-View
- [ ] `/api/drucker/status` JSON-Endpunkt für Polling
- [ ] `/admin/drucker` + manueller Status-Override
- [ ] UI: „Status veraltet"-Banner wenn Poll > 5 Min alt
## Etappe 6 — Selbstlern-Loop: Projekt-Katalog + Lebenszyklus + Files + Review + Three.js (2 Sitzungen)
**Datenmodell + Backend:**
- [ ] Alle Selbstlern-Loop-Tabellen aus [[datenmodell]] anlegen
- [ ] `services/datei.py` voll implementieren (Upload, Größen-Check, Download, Löschen)
**Projekt-Workflow im Cockpit:**
- [ ] `/cockpit/projekt/neu` (Vorlage aus Katalog wählen oder eigene Idee)
- [ ] `/cockpit/projekt/<id>/edit` während `in_arbeit`
- [ ] Datei-Upload-UI (mit Drag&Drop, 30 MB-Limit)
- [ ] `/cockpit/projekt/<id>/abschluss` mit V4-Checkliste (3 Pflicht-Felder)
**Projekt-Katalog:**
- [ ] `/projekte` mit Filter (Tag, Schwierigkeit, Erfolg, Macher)
- [ ] `/projekte/<id>` Detail-Seite
- [ ] `/api/projekte/suche` für Live-Suche
- [ ] „Sowas mache ich auch"-Button → neues Projekt mit `vorlage_projekt_id`
**Three.js-Vorschau (V3-Aktion + E-018):**
- [ ] `static/js/three.min.js` + `static/js/STLLoader.js` (zwei einzelne JS-Dateien, kein npm)
- [ ] STL-Viewer-Widget für Detail-Seite und Lehrer-Review
- [ ] „Aus 3D-Ansicht Cover speichern"-Funktion (Canvas-Screenshot)
**Lehrer-Review (V3-Aktionen + E-017):**
- [ ] `/admin/projekt-freigabe` Queue
- [ ] `/admin/projekt-freigabe/<id>` Detail mit Three.js + Inline-Edit
- [ ] Freigeben / Rückfrage / Hart-Löschen-Aktionen
- [ ] Audit-Log für Löschungen
**Rückfrage-Mechanik (V6):**
- [ ] `/cockpit/projekt/<id>/rueckfrage/<rid>/erledigt` als Reaktions-Endpunkt
- [ ] Banner-Rendering im Cockpit
- [ ] Lehrer-Sicht der Rückfragen-Antworten
## Etappe 7 — Slot-System + Druckaufträge (1 Sitzung)
**Slots:**
- [ ] `/cockpit/slots` Kalender-Ansicht
- [ ] `/cockpit/slot/reservieren` mit Konflikt-Check
- [ ] **V2-Gate**: Slot-Routen mit Decorator `@onboarding_l1_fertig` schützen
- [ ] `/admin/slot/<id>/prioritaet` Lehrer-Priorisierung
- [ ] `/admin/slot/<id>/verschieben` Drucker-Wechsel bei Ausfall
**Druckaufträge:**
- [ ] `/cockpit/druckauftrag/neu` (verknüpft mit Projekt + Slot)
- [ ] `/cockpit/druckauftraege` Eigene Liste
- [ ] `/admin/druckauftraege` Queue mit Freigabe für lange Drucke
## Etappe 8 — ZSL-Material-Import (1 Sitzung mit Markus)
- [ ] Markus + Herb wählen 8-10 ZSL-Projekte aus
- [ ] Pro Projekt: Beschreibung in unser Format umarbeiten (CC-BY-4.0-Nachweis als Footer)
- [ ] Bilder + STLs in `projekt_datei` importieren (Initial-Seed via Admin-Upload)
- [ ] Tag `zsl-vorlage` + spezifische Tags pro Projekt setzen
- [ ] Sichtbarkeits-Test im Katalog
## Etappe 9 — Deploy + Polish (0.5 Sitzung)
- [ ] DNS-A-Record `3d.lehrstun.de` → 46.225.114.15 (via Hetzner Cloud DNS-CLI)
- [ ] Nginx vhost + Let's-Encrypt
- [ ] systemd-Service `3d-ag.service`
- [ ] PummelHummel/Alph-Integration aus `D:/Claude-Projekte/PummelHummel/`
- [ ] PIN-Karten-Druckbogen testen
- [ ] Bambu-Cloud-Credentials produktiv setzen
- [ ] Erste echte AG-Sitzung als Soft-Launch
## Erwarteter Gesamtaufwand
8-10 Coding-Sitzungen. Davon:
- Etappen 1-3: Grundlage (3 Sitzungen)
- Etappen 4-5: Drucker-API (1.5 Sitzungen)
- Etappen 6-7: Selbstlern-Loop + Slots (3 Sitzungen)
- Etappen 8-9: Inhalte + Deploy (1.5 Sitzungen)
## Reihenfolge-Hinweise
- **Etappen 1-3 zusammenhängend** bauen, sonst nichts funktioniert sinnvoll.
- **Etappe 4 (Spike)** früh, weil davon abhängt, ob die Drucker-Anbindung überhaupt geht.
- **Etappen 6 (Selbstlern-Loop) und 7 (Slots) sind unabhängig** — können in beliebiger Reihenfolge.
- **Etappe 8 (ZSL-Inhalte) kann parallel** zu 6 laufen (Markus pflegt Inhalte ein, während ich Code schreibe).
- **Etappe 9 (Deploy) erst, wenn 1-7 lokal stabil läuft.**
## Querverweise
- Konzept-Übersicht: [[../kurskonzept]]
- Datenmodell pro Etappe: [[datenmodell]]
- Routen pro Etappe: [[routen]]
- Selbstlern-Loop-Details: [[selbstlern-loop]]
- Lehrer-Dashboard: [[lehrer-dashboard]]
- Entscheidungen: [[decisions]]
- Offene Punkte: [[offene-fragen]]