Initial commit: Konzept v2 + Etappe 1 (Blueprints + Login + Profile)

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
This commit is contained in:
2026-05-24 18:56:59 +02:00
commit 4658d4931a
59 changed files with 4653 additions and 0 deletions

111
docs/architektur.md Normal file
View File

@@ -0,0 +1,111 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-23
tags: [konzept, architektur]
---
# Architektur
> Komponentensicht der 3D-Druck-AG-Plattform. Detail-Schema siehe [[datenmodell]],
> Bambu-Anbindung siehe [[druckerapi]], Reservierungen siehe [[slotsystem]].
## 1. Komponenten
```mermaid
flowchart LR
subgraph Browser["Browser"]
SUS[SuS-Cockpit]
LEHRER[Lehrer-Dashboard]
OEFF[Öffentliche Seiten]
end
subgraph Server["Hetzner: 3d.lehrstun.de:5057"]
FL[Flask-App]
DB[(SQLite)]
POLL[Drucker-Poll-Worker<br/>alle ~30 s]
FL --- DB
POLL --- DB
end
subgraph Schule["Schule"]
BS_PC[Bambu Studio<br/>auf Schul-PCs]
DRU[4 Bambu-Drucker]
BS_PC -.WLAN.-> DRU
end
subgraph Cloud["Bambu Cloud"]
BAMBU[api.bambulab.com<br/>+ MQTT]
end
Browser -->|HTTPS| FL
POLL -->|HTTPS| BAMBU
DRU -->|MQTT| BAMBU
BS_PC -->|HTTPS| BAMBU
```
## 2. Datenfluss bei einem Druckauftrag
```mermaid
sequenceDiagram
actor SuS
participant Site as 3d.lehrstun.de
participant DB as SQLite
participant Studio as Bambu Studio
participant Drucker
participant Cloud as Bambu Cloud
SuS->>Site: Druckauftrag eintragen (Titel, Dauer, Material)
Site->>DB: druckauftrag (status=geplant)
SuS->>Site: Slot reservieren (Drucker X, 14:00-16:00)
Site->>DB: slot (status=reserviert)
Note over SuS,Studio: SuS slict ausserhalb der Site
SuS->>Studio: Modell slicen
Studio->>Cloud: Job hochladen
Cloud->>Drucker: Job starten
Drucker->>Cloud: Status (printing, ETA, ...)
loop alle 30 s
Site->>Cloud: GET Status aller Drucker
Cloud-->>Site: JSON
Site->>DB: drucker_status aktualisieren
end
SuS->>Site: Cockpit aufrufen
Site-->>SuS: "Dein Job auf Drucker X läuft, noch 1h 20m"
Drucker->>Cloud: Status (finished)
Site->>Cloud: GET (im nächsten Poll)
Site->>DB: druckauftrag.status = fertig
SuS->>Site: "Abgeholt" klicken
Site->>DB: druckauftrag.status = abgeholt
```
## 3. Fehlerfälle
```mermaid
flowchart TB
A[Drucker meldet 'failed' an Cloud] --> B{Poll erkennt es}
B --> C[drucker_status.status = failed]
C --> D[Dashboard zeigt rote Markierung]
D --> E{Aktive Slots betroffen?}
E -- ja --> F[Vorschlag: Slot auf anderen Drucker verschieben]
E -- nein --> G[Nur Drucker als 'Wartung nötig' markieren]
F --> H[Herb/Markus klickt 'Verschieben']
H --> I[Slot.drucker_id neu, Notiz im SuS-Cockpit]
J[Cloud-API antwortet nicht] --> K{Letzter Poll-Erfolg > 5 Min her?}
K -- ja --> L[UI: 'Status veraltet']
L --> M[Admin: Button 'Manueller Status']
K -- nein --> N[Normal weiter]
```
## 4. Querverweise
- Detail-Tabellen: [[datenmodell]]
- Welche Routes welche Komponenten füttern: [[routen]]
- Wie das Polling konkret läuft: [[druckerapi]]
- Wie Slots verteilt werden: [[slotsystem]]
- Welche Etappe was baut: [[etappen]]

249
docs/datenmodell.md Normal file
View File

@@ -0,0 +1,249 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-24
tags: [konzept, datenmodell, sql]
---
# Datenmodell
> SQLite-Schema. Live-Schema im Code: [`database.py`](../database.py).
> Architektur-Übersicht: [[architektur]]. Routes: [[routen]]. Selbstlern-Loop: [[selbstlern-loop]].
## ERD (Entity-Relationship)
```mermaid
erDiagram
AG_MITGLIED ||--o{ PROFIL : "umfasst"
PROFIL ||--o{ PROJEKT : "besitzt (Einzel)"
PROFIL ||--o{ DRUCKAUFTRAG : "stellt ein"
PROFIL ||--o{ SLOT : "reserviert"
PROFIL ||--o{ CHECK_IN : "macht pro Besuch"
PROFIL ||--o{ PROFIL_LEKTION_STATUS : "Fortschritt"
PROFIL ||--o{ LOGIN_LOCKOUT : "Sperrhistorie"
PROFIL ||--o{ PAARUNG : "Profil A"
PROFIL ||--o{ PAARUNG : "Profil B"
PAARUNG ||--o{ PROJEKT : "besitzt (Gruppe)"
DRUCKER ||--|| DRUCKER_STATUS : "hat Live-Status"
DRUCKER ||--o{ SLOT : "wird reserviert"
DRUCKER ||--o{ DRUCKAUFTRAG : "druckt"
PROJEKT ||--o{ DRUCKAUFTRAG : "gehört zu"
PROJEKT ||--o{ PROJEKT_DATEI : "hat Files"
PROJEKT ||--o{ PROJEKT_TAG : "hat Tags"
PROJEKT ||--o{ PROJEKT_RUECKFRAGE : "Lehrer-Notizen"
DRUCKAUFTRAG ||--o{ SLOT : "passt in"
LEKTION ||--o{ PROFIL_LEKTION_STATUS : "Fortschritt pro SuS"
AG_MITGLIED { TEXT id_PK "z.B. lessing-3d-ag" }
PROFIL { INT id_PK TEXT vorname TEXT tier TEXT pin_hash TEXT ag_id }
PAARUNG { INT id_PK INT profil_a INT profil_b INT aktiv }
PROJEKT { INT id_PK TEXT titel TEXT status_lebenszyklus TEXT selbsteinschaetzung TEXT freigabe_status }
PROJEKT_DATEI { INT id_PK TEXT dateiname TEXT art BLOB inhalt }
PROJEKT_TAG { INT projekt_id_FK TEXT tag }
PROJEKT_RUECKFRAGE { INT id_PK INT projekt_id TEXT text DATETIME erstellt_am TEXT status }
CHECK_IN { INT id_PK DATE besuch_datum TEXT modus TEXT freitext }
PROFIL_LEKTION_STATUS { INT profil_id INT lektion_nummer TEXT status }
LOGIN_LOCKOUT { INT id_PK INT profil_id INT versuche_count DATETIME sperre_bis }
DRUCKER { INT id_PK TEXT name TEXT modell TEXT serial_nr }
DRUCKER_STATUS { INT drucker_id_PK TEXT status INT restzeit_min }
DRUCKAUFTRAG { INT id_PK TEXT titel TEXT status }
SLOT { INT id_PK DATETIME start_zeit DATETIME ende_zeit INT prioritaet }
LEKTION { INT id_PK INT nummer TEXT titel INT onboarding }
```
## Tabellen-Übersicht
| Tabelle | Zweck | Querverweis |
|---|---|---|
| `ag_mitgliedschaft` | AG als dauerhafte Entität (statt Trimester-Kurs) | [[../decisions#E-012]] |
| `profil` | Einzel-SuS mit Vorname + Tier + PIN | [[../decisions#E-003]] |
| `paarung` | Optionale 2er-Zusammenschlüsse | [[../decisions#E-002]] |
| `profil_lektion_status` | Onboarding-Fortschritt pro SuS (offen/läuft/fertig) | [[../decisions#E-013]], [[../decisions#E-019]] |
| `login_lockout` | Persistenter Login-Lockout (V7, überlebt Restart) | [[../decisions#E-020]] |
| `projekt` | Eigene Projekte mit vollem Lebenszyklus | [[selbstlern-loop]] |
| `projekt_datei` | STL / 3MF / Fotos / Sonstiges pro Projekt | [[../decisions#E-016]] |
| `projekt_tag` | Tags für Such- und Vernetzungs-Logik | [[selbstlern-loop]] |
| `projekt_rueckfrage` | Lehrer-Rückfragen + Antworten | [[../decisions#E-017]] |
| `check_in` | „Was machst du heute?"-Abfrage pro Besuchstag | [[../decisions#E-021]] |
| `drucker` | 4 Bambu-Drucker als Entitäten | [[druckerapi]] |
| `drucker_status` | Live-Status, vom Poll-Worker aktualisiert | [[druckerapi]] |
| `druckauftrag` | Was die SuS drucken wollen | [[slotsystem]] |
| `slot` | Reservierungen auf Druckern | [[slotsystem]] |
| `lektion` | Onboarding-Lektionen + freie Module | [[lektion-L1-drucker-kennenlernen]] |
| `einstellung` | Konfigurierbare Werte (Inline-Edit) | — |
| `aenderung_log` | Audit-Trail für Inline-Edit + Lehrer-Aktionen | — |
## Wichtige neue Tabellen (gegenüber Skelett-Stand)
### `ag_mitgliedschaft` — ersetzt `kurs`
Die AG ist dauerhaft, nicht trimester-basiert. Eine einzelne Zeile (`id='lessing-3d-ag'`) reicht. Tabelle bleibt, weil später evtl. mehrere Schulen oder ein Reset möglich.
```sql
CREATE TABLE ag_mitgliedschaft (
id TEXT PRIMARY KEY, -- 'lessing-3d-ag'
name TEXT NOT NULL, -- '3D-Druck-AG Lessing-Gymnasium'
start_datum DATE,
status TEXT DEFAULT 'aktiv' -- 'aktiv'|'archiviert'
);
```
### `profil_lektion_status` — Onboarding-Fortschritt
Analog zu `gruppe_lektion_status` im Arduino-Kurs (`app.py:305-309`).
```sql
CREATE TABLE profil_lektion_status (
profil_id INTEGER NOT NULL,
lektion_nummer INTEGER NOT NULL,
status TEXT DEFAULT 'offen', -- 'offen'|'laeuft'|'fertig'
geaendert_am DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (profil_id, lektion_nummer),
FOREIGN KEY (profil_id) REFERENCES profil(id) ON DELETE CASCADE
);
```
### `login_lockout` — V7, persistenter Lockout
Verbesserung gegenüber Arduino-Kurs (In-Memory-Dict, bei Restart verloren).
```sql
CREATE TABLE login_lockout (
id INTEGER PRIMARY KEY AUTOINCREMENT,
profil_id INTEGER NOT NULL,
versuche_count INTEGER DEFAULT 1,
sperre_bis DATETIME, -- NULL = nicht gesperrt, nur gezählt
letzter_versuch_am DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (profil_id) REFERENCES profil(id) ON DELETE CASCADE
);
CREATE INDEX idx_lockout_profil ON login_lockout(profil_id);
```
### `projekt` — erweitert um Lebenszyklus
```sql
CREATE TABLE projekt (
id INTEGER PRIMARY KEY AUTOINCREMENT,
profil_id INTEGER,
paarung_id INTEGER,
titel TEXT NOT NULL,
beschreibung_md TEXT,
-- Lebenszyklus
status_lebenszyklus TEXT DEFAULT 'in_arbeit', -- 'in_arbeit'|'abgeschlossen'
abgeschlossen_am DATETIME,
selbsteinschaetzung TEXT, -- 'zufrieden'|'mittel'|'gelernt' (E-015)
was_gelernt TEXT, -- optionaler Freitext
-- Freigabe-Workflow
freigabe_status TEXT DEFAULT 'in_arbeit', -- 'in_arbeit'|'wartet_auf_freigabe'|'freigegeben'|'rueckfrage'
freigegeben_am DATETIME,
freigegeben_von INTEGER, -- Lehrer-Profil-ID, NULL=Admin direkt
-- Sichtbarkeit
sichtbar_in_ag INTEGER DEFAULT 1, -- SuS kann das ausschalten
-- Referenz auf Vorlage (wenn aus Katalog gewählt)
vorlage_projekt_id INTEGER, -- "ich mache sowas wie Mia"
geaendert_am DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (profil_id) REFERENCES profil(id) ON DELETE CASCADE,
FOREIGN KEY (paarung_id) REFERENCES paarung(id) ON DELETE CASCADE,
FOREIGN KEY (vorlage_projekt_id) REFERENCES projekt(id) ON DELETE SET NULL,
CHECK ((profil_id IS NOT NULL) <> (paarung_id IS NOT NULL))
);
CREATE INDEX idx_projekt_freigabe ON projekt(freigabe_status);
CREATE INDEX idx_projekt_sichtbar ON projekt(sichtbar_in_ag, freigabe_status);
```
### `projekt_datei` — STL / 3MF / Fotos
```sql
CREATE TABLE projekt_datei (
id INTEGER PRIMARY KEY AUTOINCREMENT,
projekt_id INTEGER NOT NULL,
dateiname TEXT NOT NULL,
mime_type TEXT,
groesse_bytes INTEGER,
inhalt BLOB,
art TEXT NOT NULL, -- 'cover_foto'|'stl'|'3mf'|'foto'|'sonstiges'
hochgeladen_am DATETIME DEFAULT CURRENT_TIMESTAMP,
hochgeladen_von INTEGER, -- profil_id (SuS oder Lehrer)
FOREIGN KEY (projekt_id) REFERENCES projekt(id) ON DELETE CASCADE,
FOREIGN KEY (hochgeladen_von) REFERENCES profil(id) ON DELETE SET NULL
);
CREATE INDEX idx_datei_projekt ON projekt_datei(projekt_id);
```
**Limit:** 30 MB pro Datei (App-Logik, nicht DB-Constraint).
**Abstraktion:** Zugriff über `services/datei.py` (siehe [[../decisions#E-016]]).
### `projekt_tag` — für Suche und Vernetzung
```sql
CREATE TABLE projekt_tag (
projekt_id INTEGER NOT NULL,
tag TEXT NOT NULL,
PRIMARY KEY (projekt_id, tag),
FOREIGN KEY (projekt_id) REFERENCES projekt(id) ON DELETE CASCADE
);
CREATE INDEX idx_tag ON projekt_tag(tag);
```
Tag-Pool ist offen (SuS gibt eigene Tags ein), aber Admin kuratiert kanonische Liste via `einstellung.tag_vorschlaege`. Beispiele: `schluesselanhaenger`, `organizer`, `werkzeug`, `spiel`, `dekoration`, `ersatzteil`, `geschenk`, `figur`.
### `projekt_rueckfrage` — Lehrer-Rückfrage-Notizen
```sql
CREATE TABLE projekt_rueckfrage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
projekt_id INTEGER NOT NULL,
von_profil_id INTEGER NOT NULL, -- Lehrer
text TEXT NOT NULL,
erstellt_am DATETIME DEFAULT CURRENT_TIMESTAMP,
status TEXT DEFAULT 'offen', -- 'offen'|'erledigt'
erledigt_am DATETIME,
FOREIGN KEY (projekt_id) REFERENCES projekt(id) ON DELETE CASCADE,
FOREIGN KEY (von_profil_id) REFERENCES profil(id) ON DELETE SET NULL
);
```
Wird im Cockpit als gelbes Banner angezeigt (V6).
### `check_in` — angepasst an V3 und E-021
```sql
CREATE TABLE check_in (
id INTEGER PRIMARY KEY AUTOINCREMENT,
profil_id INTEGER NOT NULL,
besuch_datum DATE NOT NULL,
modus TEXT NOT NULL, -- 'weiter_wie_bisher'|'neues_projekt'|'onboarding'|'drucken'|'helfen'|'sonstiges'
freitext TEXT, -- optional
erstellt_am DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(profil_id, besuch_datum),
FOREIGN KEY (profil_id) REFERENCES profil(id) ON DELETE CASCADE
);
```
**Wichtig:** „weiter_wie_bisher" ist die Default-Option und kann mit einem Klick gewählt werden (kein Freitext nötig). Erst bei „neues_projekt" oder „sonstiges" wird der Freitext sinnvoll.
## Wichtige Constraints
- `profil` UNIQUE(`ag_id`, `vorname`, `tier`) — zwei SuS mit demselben Vornamen müssen unterschiedliche Tiere wählen.
- `paarung` CHECK(`profil_a < profil_b`) + UNIQUE-Index für aktive Paarungen.
- `projekt` CHECK — entweder `profil_id` ODER `paarung_id`, nicht beides.
- `check_in` UNIQUE(`profil_id`, `besuch_datum`) — eine Abfrage pro SuS pro Tag.
- `slot` — überlappungsfreie Reservierungen werden in der App-Logik geprüft (Konflikt-Query siehe [[slotsystem]]).
- `projekt_datei` — 30-MB-Limit als App-Logik (kein DB-Constraint).
## Migrations-Strategie
- Initiales Schema in [`database.py`](../database.py) via `init_db()` (idempotent — `CREATE TABLE IF NOT EXISTS`).
- Spätere Änderungen als datierte Skripte in `migrations/YYYY-MM-DD_*.py`
Konvention wie bei `arduino.lehrstun.de`.
- Vor Migrationen auf der Live-Site immer Service stoppen (DB-Lock-Vermeidung).
## Performance-Hinweise
- Indexes auf häufig gefilterte Spalten: `idx_projekt_freigabe`, `idx_projekt_sichtbar`, `idx_tag`, `idx_lockout_profil`, `idx_datei_projekt`.
- Cockpit-Queries für „eigene Projekte / Aufträge / Slots" sind über `profil_id` indexiert (FK-Index ist in SQLite automatisch).
- BLOB-Größen bleiben durch 30-MB-Limit überschaubar; bei 5 GB+ DB ggf. Migration auf Object-Storage (siehe [[../decisions#E-016]]).

166
docs/decisions.md Normal file
View File

@@ -0,0 +1,166 @@
---
type: decisions-log
projekt: 3d.lehrstun.de
tags: [entscheidungen]
---
# Entscheidungs- und Änderungslog — 3d.lehrstun.de
> Anker-Format: `[[decisions#E-NNN]]` aus anderen Dateien verlinkt direkt
> auf den jeweiligen Entscheid.
Format: chronologisch, neueste oben. Pro Entscheidung: Kontext, Optionen, Entscheidung, Begründung.
---
## 2026-05-23 — Projekt-Skelett angelegt
### E-001: Bestehende Arduino-Kurs-Architektur als Vorlage nehmen
**Kontext:** Neuer Kurs für 3D-Druck-AG. `arduino.lehrstun.de` läuft erprobt seit Mai 2026.
**Optionen:** (a) Neue Architektur, (b) Arduino-Kurs als Basis übernehmen + anpassen, (c) Bestehende Site erweitern.
**Entscheidung:** (b) — Arduino-Stack (Flask/SQLite/Jinja2 + Tier-PIN-Login + Inline-Edit + PummelHummel) als Basis, eigenständige Site.
**Begründung:** Herb will einheitliches Design. Tier-PIN-Login + Migrations-System + Admin-Inline-Edit haben sich im Schultest 2026-05-11 bewährt. Eigenständige Site, weil andere Domain (`3d.lehrstun.de`) und Inhalte komplett anders.
### E-002: SuS-Profil als Primär-Objekt (statt Gruppe)
**Kontext:** AG hat 8-10 SuS, optional 2er-Gruppen.
**Optionen:** (a) Gruppe primär (wie Arduino), (b) Profil primär, Paarung sekundär.
**Entscheidung:** (b).
**Begründung:** Bei einer AG ändert sich die Sozialform — Einzelarbeit ist hier der Normalfall, Paarung ein Sonderfall. Das ist anders als beim Arduino-Pflichtkurs, wo 2er-Gruppen fest waren. Datenmodell muss das abbilden: `profil` + optional `paarung`.
**Wirkt sich aus auf:** [[datenmodell#profil]], [[datenmodell#paarung]]
### E-003: Login = Vorname + Tier-Icon + 4-stellige PIN
**Kontext:** SuS-Identifikation auf der Site.
**Optionen:** (a) Tier-PIN (wie Arduino), (b) Vorname + PIN, (c) TinkerCAD-Style (Klassencode + Spitzname), (d) Hybrid Vorname+Tier+PIN.
**Entscheidung:** (d) — Vorname (Klarname) + Tier-Icon (visuell) + 4-stellige PIN.
**Begründung:** Herb-Wunsch. Vorname für persönliche Ansprache, Tier-Icon für Differenzierung bei Namens-Duplikaten und als spielerisches Element, PIN als Auth.
### E-004: Sichtbarkeit zwischen SuS — nur Projekttitel
**Kontext:** SuS sollen sich gegenseitig inspirieren, aber kein Druck durch Stand-Vergleich.
**Optionen:** (a) Nur Lehrer sieht alles, (b) alle SuS sehen alles, (c) Lehrer voll + SuS sehen nur Projekttitel.
**Entscheidung:** (c).
**Begründung:** Inspiration ja (Projekttitel sind Anregung), Vergleich nein (Stand/Drucke/Probleme bleiben privat).
### E-005: Drucker-Status via Bambu Cloud-API (kein Pi-Bridge)
**Kontext:** Drucker stehen im Schul-LAN, Site auf Hetzner. Live-Status gewünscht.
**Optionen:** (a) Raspberry Pi in der Schule als MQTT-Bridge, (b) Cloud-API direkt vom Hetzner pollen, (c) manuell, (d) gar nicht.
**Entscheidung:** (b).
**Begründung:** Herb: "Alle SuS in der AG haben über Handy-App Cloud-Zugang zu den Druckern, bisher keine schlechten Erfahrungen." Cloud-API ist akzeptabel, kein Pi-Hardware-Aufwand. Risiko bekannt: Bambu ändert die API ab und zu → Fallback "manueller Status" eingeplant.
**Wirkt sich aus auf:** [[druckerapi]]
### E-006: Kein Druckjob-Upload von der Site zum Drucker
**Kontext:** Wäre nice-to-have, aber Bambu erlaubt das nur mit „Developer Mode" am Drucker.
**Optionen:** (a) Developer Mode aktivieren + Site darf Jobs senden, (b) SuS slicen weiterhin in Bambu Studio.
**Entscheidung:** (b).
**Begründung:** Developer Mode würde Bambu-Cloud-Konto-Funktionen am Drucker abschalten. Zu hoher Preis für einen Komfort-Gewinn. Site verwaltet nur Reservierungen + zeigt Status.
**Wirkt sich aus auf:** [[druckerapi#was-wir-nicht-machen]], [[slotsystem]]
### E-007: Drucker laufen auch über Nacht / Freistunden
**Kontext:** Druckzeit ≫ Schulstunde.
**Entscheidung:** Drucker dürfen 24/7 laufen, Slot-System bildet das ab.
**Begründung:** Druckraum mit Dauerlüftung, Bambu-Drucker mit Notabschaltung. Erlaubt komplexere Projekte.
### E-008: PLA + PLA+ als Default, PETG/ABS nur unter Aufsicht
**Entscheidung:** Material-Auswahl bei Druckauftrag standardmäßig auf PLA-Varianten beschränkt; PETG/ABS nur freischaltbar im Admin.
**Begründung:** Herb: "Für die grundlegenden Sachen erst mal alles mit PLA (weil ungefährlich)."
**Wirkt sich aus auf:** [[sicherheit]], [[datenmodell#druckauftrag]]
### E-009: Site-Inhalt bei Kursstart = Skelett + L1-L3 fertig
**Entscheidung:** Lektionen L4+ und Software-Detailseiten kommen später inline durch Herb + Markus.
**Begründung:** Herb hat 3D-Druck selbst noch nie unterrichtet — Inhalt entsteht im Doing. Admin-Inline-Edit muss daher von Anfang an stabil sein.
### E-010: Brand = "3D-Druck-AG"
**Begründung:** Herb-Entscheidung. Passt zum tatsächlichen Format (Wahl-AG, nicht Kurs).
### E-011: Obsidian-tauglich, aber kein Plugin-Zwang
**Kontext:** `D:\Claude-Projekte\` ist bereits Obsidian-Vault. Markdown + Wikilinks sollten überall funktionieren.
**Entscheidung:** Doku-Dateien als reines Markdown mit normalen Links (keine `[[wikilinks]]`-Pflicht), damit sie auch in jedem anderen Editor lesbar bleiben. Wikilinks dürfen ergänzt werden, sind aber optional.
**Begründung:** Markus arbeitet vielleicht nicht mit Obsidian — Doku muss universell lesbar bleiben.
---
## 2026-05-24 — Reality-Check + Selbstlern-Loop
Nach Analyse aus vier Perspektiven (neuer SuS / erfahrener SuS / Lehrer / technische Machbarkeit) plus Vergleich mit `arduino.lehrstun.de`. Vollständige Analyse: `~/.claude/plans/f-hre-noch-einmal-eina-cosmic-wind.md` (approved).
### E-012: AG ist offen, jahrelang, keine festen Termine
**Kontext:** Hatte ursprünglich „12 Termine à 60 Min" vom Arduino-Trimester unwissend übernommen.
**Entscheidung:** Die AG ist Nachmittags-Wahlangebot, läuft über Jahre, kein Lehrplan, freier Zugang.
**Begründung:** Herb-Korrektur. Bedeutet: Mitgliedschaften sind dauerhaft, Onboarding-Pfad für Neue, danach freie Bibliotheks-Nutzung.
**Wirkt sich aus auf:** [[kurskonzept]], [[etappen]]
### E-013: Onboarding-Pfad statt Pflicht-Lektionen
**Kontext:** „L1-L3 Pflicht für alle" passt nicht zu einer freien AG.
**Entscheidung:** L1-L3 werden zum **Onboarding-Pfad** — Pflicht nur für Neue. Erledigt → unsichtbar im Cockpit.
**Begründung:** Bei kontinuierlicher AG-Mitgliedschaft kommt nicht jeder gleichzeitig dazu. Onboarding ist Einstiegs-Werkzeug, kein Curriculum.
**Wirkt sich aus auf:** [[kurskonzept]], [[selbstlern-loop]], [[datenmodell#profil_lektion_status]]
### E-014: Selbstlern-Loop mit interner Projekt-Bibliothek
**Kontext:** Mentoring-Idee von Herb. Die Site wächst über die Jahre durch SuS-Projekte selbst.
**Entscheidung:** Vollständiger Projekt-Lebenszyklus: Stöbern → Auswählen → Arbeiten → Abschluss-Checkliste → Lehrer-Review → AG-öffentlich. Vernetzung über Stöbern (Variante 1), nicht Auto-Match.
**Begründung:** Macht die Site wertvoller als jeden externen Katalog. SuS sehen „bei uns hat das schonmal jemand gemacht". Lehrer-Review ist Qualitätsfilter.
**Wirkt sich aus auf:** [[selbstlern-loop]], [[datenmodell#projekt]], [[routen]]
### E-015: Feedback nach Abschluss = A-Variante (sachlich) + optionaler Freitext
**Entscheidung:** Drei Stufen: 🟢 zufrieden / 🟡 würde Sachen anders machen / 🔴 nicht geklappt, aber gelernt. Optionales Freitext-Feld „Was würdest du anderen mitgeben?".
**Begründung:** Sachliche Sprache schlägt Maker-Slang oder Sterne-Bewertung. Freitext optional, weil 8.-Klässler Pflicht-Freitext oft nicht ausfüllen.
**Wirkt sich aus auf:** [[selbstlern-loop]], [[datenmodell#projekt]]
### E-016: File-Storage als BLOB in SQLite, 30 MB pro Datei, abstrahiert
**Kontext:** Projekt-Dateien (STL, 3MF, Fotos) gehören zum Lebenszyklus.
**Entscheidung:** Files in SQLite-BLOBs, Limit 30 MB pro Datei. File-Handling über `services/datei.py` abstrahieren, damit später Migration auf Hetzner-Object-Storage / S3 möglich ist.
**Begründung:** SQLite hält 2-3 GB ohne Performance-Probleme; bei 8 SuS × 5 Projekte/Jahr × 5 Files × 10 MB → ~2 GB/Jahr. Reicht für die ersten 5 AG-Jahre.
**Wirkt sich aus auf:** [[datenmodell#projekt_datei]]
### E-017: Lehrer-Review mit drei Aktionen (Variante 3)
**Entscheidung:** Lehrer kann beim Review (a) freigeben (mit oder ohne eigene Bearbeitung), (b) Rückfrage stellen (Status zurück + Notiz im Cockpit), (c) hart löschen (für Penismodelle, Copyright-Probleme).
**Begründung:** Flexibilität. Hartes Löschen mit Audit-Log-Eintrag (Datum, Lehrer, SuS, optional Grund — aber Dateien sind weg).
**Wirkt sich aus auf:** [[lehrer-dashboard]], [[selbstlern-loop]]
### E-018: 3D-Vorschau mit Three.js — Cover-Foto aus 3D-Ansicht
**Kontext:** SuS vergisst manchmal Cover-Foto. Lehrer beim Review oder SuS selbst soll Screenshot aus STL-Vorschau machen können.
**Entscheidung:** Three.js + STLLoader im Browser einbinden (zwei JS-Dateien in `static/js/`, kein npm, kein Build).
**Begründung:** Herb-OK. Externe Frontend-Dependency, ca. 600 KB. Funktioniert offline auf jedem modernen Browser, inkl. iPad. Falls Browser-Test scheitert: Lehrer macht Screenshot in Bambu Studio manuell.
**Wirkt sich aus auf:** [[selbstlern-loop]], `static/js/three.min.js` + `STLLoader.js`
### E-019: Onboarding-Pfad = Selbst-Zertifizierung
**Kontext:** Wer markiert eine Onboarding-Lektion als „fertig"?
**Optionen:** (a) SuS klickt selbst „fertig", (b) Lehrer nickt ab.
**Entscheidung:** (a) — selbst-zertifiziert, analog zu `gruppe_lektion_status` im Arduino-Kurs.
**Begründung:** Lehrer sieht im Drill-Down-Dashboard ohnehin Fortschritts-Stände — Abnahme-Workflow wäre Overhead. Vertrauen geht vor Kontrolle.
**Wirkt sich aus auf:** [[datenmodell#profil_lektion_status]], [[selbstlern-loop]]
### E-020: 8 Empfehlungen aus Reality-Check angenommen (V1-V8)
- **V1 — Cockpit progressiv:** zeigt nur was zum Status passt (Onboarding nicht erledigt → nur Onboarding-Karte; nach Abschluss kommen Projekt-Karte, Slot-Buchung etc. dazu).
- **V2 — Slot-Buchung erst nach L1 (Sicherheits-Lektion).** Bis dahin Hinweis statt Button.
- **V3 — Stunden-Beginn-Abfrage radikal kurz.** Ein Radio, ein optionales Freitext-Feld. Default: „Ich arbeite an X weiter" als Ein-Klick-Option.
- **V4 — Abschluss-Checkliste auf 3 Pflicht-Felder runter** (Selbsteinschätzung + Cover-Foto **oder** STL + 1 Tag). Rest optional.
- **V5 — Drill-Down-Lehrer-Dashboard** mit „Wer ist heute hier / Wartet auf Review / Wer hängt fest".
- **V6 — Rückfrage-Mechanik via Cockpit-Banner**, keine E-Mail.
- **V7 — Persistenter Login-Lockout in DB-Tabelle** (statt In-Memory wie Arduino-Kurs).
- **V8 — Blueprint-Struktur von Anfang an** (`routes/oeffentlich.py`, `routes/profil.py`, `routes/admin.py`, `routes/api.py`, `services/bambu.py`).
### E-021: Herb-Zusatz „Ich arbeite weiter"-Knopf
**Kontext:** Zu V1/V3 ergänzt: bei laufenden Projekten soll das Stunden-Beginn-Modal mit einem Klick übersprungen werden können.
**Entscheidung:** Modal hat als allererste Option „Ich arbeite an meinem laufenden Projekt weiter" — bei Klick: kein Freitext nötig, direkt ins Cockpit. Erkennt das System, dass ein aktives Projekt da ist, ist diese Option vorausgewählt.
**Begründung:** Reibungsfreie Routine für erfahrene SuS, die wochenlang am gleichen Projekt arbeiten.
**Wirkt sich aus auf:** [[selbstlern-loop]], [[datenmodell#check_in]]
### E-022: ZSL-Material in 8-10 Projekten umarbeiten, Rest später
**Kontext:** ZSL Baden-Württemberg liefert 20+ CC-BY-4.0-Projekte. Zu viel auf einmal.
**Entscheidung:** Markus + Herb wählen 8-10 Projekte aus (gemischte Schwierigkeit), arbeiten Beschreibungen + Bilder in unser Design um (mit Urhebernachweis). Rest als Notiz „weitere verfügbar" — SuS-Projekte ergänzen die Bibliothek automatisch über die Zeit.
**Begründung:** Keep it small (Herb). Wachstum kommt aus SuS-Projekten + späterer Erweiterung durch Lehrer-Inline-Edit.
**Wirkt sich aus auf:** [[selbstlern-loop]], [[offene-fragen]]
---
## Vorlage für neue Einträge
```
## YYYY-MM-DD — Titel
### E-NNN: Kurz-Titel der Entscheidung
**Kontext:**
**Optionen:**
**Entscheidung:**
**Begründung:**
```

96
docs/druckerapi.md Normal file
View File

@@ -0,0 +1,96 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-23
tags: [konzept, druckerapi, bambu]
---
# Drucker-API-Anbindung (Bambu Cloud)
> Architektur-Einbettung: [[architektur#3-Fehlerfälle]].
> Entscheidung dazu: [[../decisions#E-005]] und [[../decisions#E-006]].
## Ziel
Live-Status aller 4 Bambu-Lab-Drucker auf der Site anzeigen, mit Fallback auf manuellen Status bei API-Ausfall.
## Variante (gewählt): Cloud-API-Polling vom Hetzner
```mermaid
flowchart LR
PW[Poll-Worker<br/>auf Hetzner] -->|GET alle 30s| BAMBU[api.bambulab.com]
BAMBU --> PW
PW --> DB[(drucker_status)]
FE[Frontend] -.alle 30s.-> API[/api/drucker/status/]
API --> DB
```
- **Auth:** Bambu-Cloud-Konto-Credentials in `.env` (`BAMBU_EMAIL`, `BAMBU_PASSWORT`, `BAMBU_REGION=eu`).
- **Lib:** [`bambulabs_api`](https://github.com/BambuTools/bambulabs_api) (Python, aktiv gepflegt). Alternativ Code aus [`pybambu`](https://github.com/greghesp/ha-bambulab) (Home-Assistant-Integration) extrahieren.
- **Frequenz:** ~30 s pro Drucker. Bei 4 Druckern unkritisch.
- **Polling-Worker:** entweder als Hintergrund-Thread in Flask oder eigener systemd-Service (saubere Trennung, wird in [[etappen#etappe-5]] entschieden).
## Welche Felder lesen wir?
| Feld | Beispiel | Pflicht? |
|---|---|---|
| `status` | `printing`, `idle`, `paused`, `finished`, `failed`, `offline` | ja |
| `job_name` | "schluesselanhaenger_mia.3mf" | ja |
| `progress_pct` | 67.5 | ja |
| `restzeit_min` | 42 | ja |
| `bett_temp` | 58.2 | nein |
| `duese_temp` | 210.0 | nein |
| `fehlermeldung` | "AMS error: filament jam" | nein |
Die Bonus-Felder werden im UI nur angezeigt, wenn vorhanden.
## Fallback-Strategie
```mermaid
flowchart TB
A[Poll-Versuch] --> B{Erfolg?}
B -- ja --> C[drucker_status aktualisiert]
B -- nein --> D[Lasse alten Wert stehen]
D --> E{gepollt_am > 5 Min alt?}
E -- ja --> F[UI: 'Status veraltet']
F --> G[Admin: Button 'Manueller Status']
E -- nein --> H[Noch ignorierbar]
```
- **Admin-Override**: `/admin/drucker/<id>/manueller_status` — Herb/Markus setzen manuell, überschreibt nächsten Poll.
- **Notbetrieb ohne API**: Wenn die Cloud dauerhaft nicht erreichbar ist, kann der Slot-Betrieb komplett manuell laufen — SuS sehen Status nur über Bambu Handy App, Reservierungen funktionieren weiter, weil sie nicht von API abhängen.
## Was wir **nicht** machen
- **Keine Druckjob-Übertragung von der Site zum Drucker.** Würde "Developer Mode" am Drucker brauchen → Verlust der Bambu-Cloud-Funktionen. Siehe [[../decisions#E-006]].
- **Keine Kamera-Streams** auf der Site. SuS nutzen die Bambu Handy App fürs Bild. DSGVO-Frage in der Schule wäre sonst aufwendig.
## Spike vor Integration
Bevor wir das in die Site einbauen, baue ich ein eigenständiges Script:
```
scripts/drucker_api_spike.py
```
- Liest Credentials aus `.env`.
- Fragt einmalig alle 4 Drucker ab.
- Gibt JSON auf STDOUT.
- Validiert: funktioniert die Auth? Werden alle 4 Drucker gefunden? Welche Felder liefert die API?
Wenn der Spike läuft, übernehmen wir die Logik in einen sauberen Poll-Worker (Etappe 5).
## Risiken (Stand 2026-05)
- **Bambu hat 2024/25 die API mehrfach geändert** ("Authorization Control"-Update). Status-Lesen funktioniert weiterhin, aber kann jederzeit brechen.
- **Inoffizielle API**: Bambu supportet keine Drittsoftware. Bei Bruch helfen nur die GitHub-Communities (`bambulabs_api`, `pybambu`).
- **Cloud-Login-Flow** ändert sich gelegentlich (2FA, Captcha). Wenn das passiert, Spike-Script anpassen.
→ Deshalb ist [[slotsystem]] so gebaut, dass es **ohne** Drucker-API funktioniert. Status-Anzeige ist Komfort, nicht Pflicht.
## Querverweise
- DB-Schema: [[datenmodell#drucker]]
- Route: `/api/drucker/status` siehe [[routen]]
- Architektur: [[architektur]]
- Entscheidungen: [[../decisions#E-005]], [[../decisions#E-006]]

195
docs/etappen.md Normal file
View File

@@ -0,0 +1,195 @@
---
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 (1 Sitzung)
**Cockpit (V1 — progressives Layout):**
- [ ] `/cockpit` rendert je nach Status:
- Onboarding nicht erledigt → nur Onboarding-Karte + Check-In-Trigger
- L1 fertig → zusätzlich: Drucker-Buchung freigeschaltet
- Hat aktive Projekte → zusätzlich: eigene Projekte, Druckaufträge, Slots
- [ ] Cockpit-Banner für offene Rückfragen (V6)
- [ ] Cockpit-Banner für ungelesene Lehrer-Notizen
**Check-In (V3 + E-021):**
- [ ] Modal beim ersten Cockpit-Aufruf eines Besuchstages
- [ ] Default-Option „Ich arbeite an X weiter" wenn aktives Projekt vorhanden
- [ ] `/cockpit/check-in`-POST speichert in `check_in`-Tabelle
**Paarung:**
- [ ] `/cockpit/paarung/anfragen/<id>` + Bestätigungsmechanik
- [ ] `/cockpit/paarung/aufloesen`
**Lehrer-Dashboard (V5, [[lehrer-dashboard]]):**
- [ ] `/admin/dashboard` mit 4 Sektionen (Wer hier / Wartet Review / Drucker-Status / Hängt fest)
- [ ] Badge im Header für „wartet auf Review"-Anzahl
- [ ] „Notiz hinterlassen"-Quick-Action via `lehrer_notiz`-Tabelle
## 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]]

66
docs/glossar.md Normal file
View File

@@ -0,0 +1,66 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-23
tags: [glossar, begriffe]
---
# Glossar — 3D-Druck-Begriffe
> Begriffe, die in [[../kurskonzept]] und den Lektionen vorkommen. Für SuS und
> für Markus (falls noch nicht 3D-Druck-vertraut).
## Drucker + Hardware
- **AMS** (Automatic Material System) — Bambu-Wechslerbox für bis zu 4 Filamentrollen, ermöglicht Multi-Color-Druck oder automatischen Rollenwechsel.
- **Bauraum** — der Bereich, in dem ein Drucker drucken kann (z.B. P1S: 256×256×256 mm).
- **Bett / Druckbett** — die beheizte Platte, auf der die erste Schicht haftet.
- **Düse / Nozzle** — die heiße Spitze, aus der das geschmolzene Filament kommt. Standardgröße 0.4 mm.
- **Hotend** — der heizbare Teil des Druckkopfs (umfasst Düse + Heizpatrone + Sensor).
- **Schichthöhe** — Höhe einer einzelnen Druckschicht (typisch 0.16-0.28 mm). Niedriger = feiner = länger.
- **Support / Stützmaterial** — temporäre Streben, die Überhänge stützen. Werden nach dem Druck abgebrochen.
## Material
- **PLA** (Polylactid) — biologisch abbaubares Bio-Plastik, niedriger Schmelzpunkt (~190-220°C), Standard für Schule. Siehe [[sicherheit]].
- **PLA+** — Variante mit Additiven für mehr Zähigkeit, sonst wie PLA.
- **PETG** — etwas zäher als PLA, höhere Drucktemperatur (~230°C), klebt fest am Bett.
- **ABS** — klassisches Plastik (Lego), schmilzt bei ~240°C, Geruch beim Druck, in der Schule selten verwendet. Siehe [[sicherheit]].
- **Filament** — der Draht (1.75 mm), aus dem gedruckt wird. Wird auf Rollen geliefert.
## Software & Dateien
- **STL** — Standard-Format für 3D-Modelle (nur Geometrie, keine Druckeinstellungen).
- **3MF** — moderneres Format, enthält Geometrie + Druckeinstellungen + Stützen + Plattenposition.
- **G-Code** — die maschinen-lesbare Anweisungsliste, die der Drucker tatsächlich ausführt. Wird aus STL/3MF beim Slicen generiert.
- **Slicer** — die Software, die ein 3D-Modell in Schichten zerlegt und G-Code daraus macht. Bei uns: [[software-bambu-studio|Bambu Studio]].
- **CAD** (Computer Aided Design) — Software, mit der 3D-Modelle entworfen werden. Bei uns: [[software-tinkercad|TinkerCAD]] und [[software-openscad|OpenSCAD]].
## Druckparameter
- **Infill / Fülldichte** — wie dicht das Innere eines Drucks gefüllt wird (0% = hohl, 100% = massiv, typisch 15-30%).
- **Druckgeschwindigkeit** — mm/s, bei Bambu typisch 200-500 mm/s.
- **Adhäsion / Haftung** — wie gut die erste Schicht am Bett klebt. Wichtigster Faktor für erfolgreichen Druck.
- **Warping** — wenn ein Druck sich an den Ecken vom Bett löst und nach oben biegt.
- **Spaghetti** — Druckfehler, bei dem nicht-haftendes Filament zu einem Wurmnest wird. Drucker sofort stoppen.
- **Stringing / Fäden** — feine Fäden zwischen getrennten Druckbereichen, oft durch zu heißes Hotend.
## Plattformen & Communities
- **[[software-printables|Printables.com]]** — Modell-Plattform von Prusa, sauber, kein NSFW.
- **[[software-makerworld|MakerWorld]]** — Bambu-eigene Modell-Plattform, mit parametrischem Customizer.
- **Thingiverse** — älteste Modell-Plattform, aber bei uns nicht empfohlen (NSFW-Werbung).
- **Customizer** — Browser-Tool auf MakerWorld, mit dem ein fertiges parametrisches Modell (z.B. Schlüsselanhänger) angepasst werden kann, ohne CAD-Software.
## Methoden
- **FDM** (Fused Deposition Modeling) — was unsere Bambu-Drucker machen: heißes Filament schichtweise auftragen. Auch "FFF" genannt.
- **Resin / SLA** — andere Druckmethode mit flüssigem Kunstharz, bei uns **nicht** im Einsatz.
- **Slicen** — der Prozess, ein 3D-Modell in Druck-Schichten zu zerlegen.
- **Benchy** — kleines Test-Schiffchen (Bench-mark), Standard-Modell zum Drucker-Test/Kalibrierung.
## Querverweise
- Lektionen, in denen Begriffe vorkommen: [[lektion-L1-drucker-kennenlernen]], [[lektion-L2-modell-drucken]], [[lektion-L3-customizer]]
- Software-Tool-Übersicht: [[software-bambu-studio]], [[software-printables]] etc.
- Sicherheits-Aspekte: [[sicherheit]]

308
docs/kurskonzept.md Normal file
View File

@@ -0,0 +1,308 @@
---
type: konzept-hauptdokument
projekt: 3d.lehrstun.de
stand: 2026-05-24
status: entwurf v2
tags: [konzept, hauptdokument]
---
# 3D-Druck-AG — Kurskonzept (Entwurf v2)
> **Lesehinweis Obsidian:** Das ist das Hauptdokument am Stück. Detail-Module
> liegen in eigenen Dateien — siehe [[COCKPIT]] für die Übersicht, oder direkt
> [[architektur]], [[datenmodell]], [[routen]], [[druckerapi]], [[slotsystem]],
> [[sicherheit]], [[selbstlern-loop]], [[lehrer-dashboard]], [[etappen]],
> [[offene-fragen]], [[glossar]].
**Stand:** 2026-05-24 (nach Reality-Check-Iteration mit Herb)
**Status:** Entwurf v2, zur Abstimmung mit Markus
**Rahmen:** Offene Nachmittags-AG am Lessing-Gymnasium, **läuft jahrelang**,
ca. 8-10 Einzel-SuS (optional 2er-Paarungen), eigener Druckraum mit
4 Bambu-Lab-Druckern (3 geschlossen + 1 A1 mini). **Unbenotet**, kein Lehrplan,
freier Zugang. Neue Mitglieder kommen über die Jahre dazu, alte gehen.
> **Lesehinweis für Markus:** Dieses Dokument ist Entwurf v2. Es ersetzt v1
> (2026-05-23) nach einer Reality-Check-Analyse aus vier Perspektiven (neuer
> SuS / erfahrener SuS / Lehrer / Technik). Wichtige Korrektur gegenüber v1:
> Wir haben fälschlich „12 Termine" angenommen — die AG ist tatsächlich offen
> und langfristig. Das ändert mehrere Architektur-Entscheidungen. Vollständige
> Entscheidungs-Historie: [[decisions]].
---
## 1. Didaktischer Kern
### Onboarding-Pfad statt fester Lehrplan
Die AG hat **keinen Curriculum**. Neue Mitglieder bekommen einen
**Onboarding-Pfad** mit 3 selbst-zertifizierten Lektionen — danach freie
Wahl, was sie machen wollen.
| Lektion | Inhalt | Pflicht für | Nach Abschluss freigeschaltet |
|---|---|---|---|
| **L1 Drucker-Kennenlernen + Sicherheit** | Drucker-Übersicht, A1-mini-Hands-Off, Bambu Handy App einrichten, vorbereitetes Modell drucken | Neue | **Slot-Buchung** (V2 — siehe [[../decisions#E-020]]) |
| **L2 Fremdes Modell wählen + drucken** | Modell auf Printables/MakerWorld suchen, in Bambu Studio slicen, drucken | Neue | Eigene Projekte aus Katalog |
| **L3 Customizer / parametrisches Modell** | MakerWorld-Customizer: Schlüsselanhänger mit eigenem Namen | Neue | Eigenes-Projekt-Vollzugriff |
| **L4+ Eigene Modelle zeichnen** | TinkerCAD → OpenSCAD | Frei | — |
| **Eigene Projekte (Dauer-Modus)** | Idee → Modell → Druck → Iteration → Abschluss mit Reflexion → in Katalog | Frei | — |
Nach Onboarding **verschwindet die Onboarding-Karte** aus dem Cockpit (V1 — progressives Cockpit, [[../decisions#E-020]]). Erfahrene SuS sehen nur noch ihre laufenden Projekte, Druckaufträge, Slots.
### Warum diese Reihenfolge
Quellen: PHBern IdeenSet, inf-schule.de, ZSL Baden-Württemberg.
- „Druck zuerst, Modellierung später" verhindert Frust.
- Customizer als Brücke zwischen „fertig laden" und „selbst zeichnen" — fehlt in den meisten Schulkonzepten, MakerWorld macht ihn so leicht zugänglich.
- L4+ ist optional und nach Interesse — TinkerCAD für klick-basierte, OpenSCAD für code-basierte SuS.
### Selbstlern-Loop als Kern (Wachstums-Mechanismus)
**Was die Site vom Arduino-Kurs grundsätzlich unterscheidet:** Jedes
abgeschlossene Projekt wird nach Lehrer-Freigabe in die interne Bibliothek
aufgenommen. Über die Jahre wächst eine **eigene Projekt-Sammlung** — wertvoller
als jeder externe Modell-Katalog, weil sie zeigt: „Das wurde bei uns
schonmal gemacht."
Vollständiger Workflow: [[selbstlern-loop]].
Kurzfassung:
1. Neuer SuS **stöbert** im Projekt-Katalog (eigene + ZSL-Seed).
2. **Wählt** Vorlage oder eigene Idee.
3. **Arbeitet** im Cockpit (Files, Druckaufträge, Slots).
4. Beim Abschluss: **Pflicht-Checkliste** (Selbsteinschätzung 🟢🟡🔴 + Cover-Foto **oder** STL + 1 Tag — sonst alles optional).
5. **Lehrer-Review**: freigeben, Rückfrage, oder hartes Löschen (Penismodell-Fall).
6. Bei Freigabe: Projekt landet im Katalog, ist für andere SuS sichtbar.
### Doku-Hürde
8.-Klässler tun sich schwer mit ausführlicher Stand-Notiz. Lösung:
**Stunden-Beginn-Abfrage** (siehe §7) als „Was machst du heute?"-Mini-Modal,
das mit einem Klick beantwortbar ist („Ich arbeite an X weiter").
Kein KI-Lernhelfer in dieser Site. SuS nutzen Schul-Copilot.
---
## 2. Architektur — eine Site, drei Zonen
> 📎 Detail mit Mermaid-Diagrammen: [[architektur]]. Datenmodell: [[datenmodell]]. Routen: [[routen]].
> Code-Organisation: **Blueprint-Struktur** von Anfang an (V8, [[../decisions#E-020]]).
```
┌─────────────────────── 3d.lehrstun.de ─────────────────────────┐
│ │
│ ÖFFENTLICH (kein Login) │
│ ───────────────────────── │
│ • Lektionen (Onboarding-Pfad + freie Module) │
│ • Software-Sektion (Bambu Studio, Printables, ...) │
│ • Projekt-Katalog (interner Wachstum + ZSL-Seed) │
│ • Drucker-Status (Live, anonym) │
│ • Troubleshooting │
│ │
│ ┌── Vorname + Tier-Icon + PIN-Login ─────────────────────┐ │
│ │ │ │
│ │ SuS-COCKPIT (PROGRESSIV, V1) │ │
│ │ ─ Neu: nur Onboarding-Karte + Check-In │ │
│ │ ─ Onboarding fertig: + eigene Projekte, Druck, Slots │ │
│ │ ─ Erfahren: voll, ohne Onboarding-Karte │ │
│ │ Bei Lehrer-Rückfrage: gelbes Banner ganz oben (V6) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ADMIN (Passwort, Herb + Markus) │
│ • Drill-Down-Dashboard (V5): Wer ist heute hier / │
│ Wartet auf Review / Wer hängt fest / Drucker-Status │
│ • Projekt-Freigabe-Queue (mit Three.js-Vorschau, V3-Aktion) │
│ • SuS-Profile, PIN-Generierung, Druckbogen │
│ • Slot-Priorisierung │
│ • Drucker-Übersicht + manueller Status-Override │
│ • Lektionen-/Software-Editor (inline, Whitelist) │
└─────────────────────────────────────────────────────────────────┘
```
---
## 3. Datenmodell (Kurzfassung)
> 📎 Detail mit ERD + Tabellen-Erklärung: [[datenmodell]]. Live im Code: [`database.py`](../database.py).
**Kern-Tabellen (gegenüber v1 erweitert):**
- `ag_mitgliedschaft` (ersetzt `kurs` — AG ist dauerhaft, nicht trimester-basiert)
- `profil` (Vorname + Tier + PIN, Pflicht-Login)
- `paarung` (optional, 2er-Zusammenschluss)
- `profil_lektion_status` ([[../decisions#E-019]] — Onboarding-Fortschritt, selbst-zertifiziert)
- `login_lockout` (V7 — persistenter Lockout in DB)
- `projekt` (vollständiger Lebenszyklus: `status_lebenszyklus`, `selbsteinschaetzung`, `freigabe_status`, `vorlage_projekt_id`)
- `projekt_datei` (BLOB, 30 MB Limit, abstrahiert)
- `projekt_tag` (für Suche und Filter)
- `projekt_rueckfrage` (Lehrer-Notizen pro Projekt)
- `lehrer_notiz` (allgemeine Notizen vom Lehrer ans SuS-Cockpit)
- `check_in` (V3-Format mit Modus + optionalem Freitext)
- `drucker`, `drucker_status`, `druckauftrag`, `slot`, `lektion`, `einstellung`, `aenderung_log`
---
## 4. Routen (Kurzfassung)
> 📎 Vollständige Routen-Tabelle: [[routen]]. Stubs im Code: [`app.py`](../app.py).
Blueprint-Aufteilung (V8):
- `routes/oeffentlich.py` — öffentliche Seiten
- `routes/profil.py` — Login, Cockpit, eigene Projekte/Aufträge/Slots
- `routes/admin.py` — Dashboard, Review-Queue, Inline-Edit
- `routes/api.py` — JSON-Endpunkte (Drucker-Status, Slot-Polling)
- `services/bambu.py` — Cloud-API-Wrapper (isoliert)
- `services/datei.py` — File-BLOB-Handling (abstrahiert für spätere S3-Migration)
---
## 5. Drucker-API-Anbindung
> 📎 Detail: [[druckerapi]]. Entscheidungen: [[../decisions#E-005]], [[../decisions#E-006]].
- Bambu Cloud-API-Polling vom Hetzner aus, alle ~30 s (Lib: `bambulabs_api`).
- Inoffiziell, fragil → Fallback: manueller Status-Override durch Lehrer.
- Lesen: Status, Job, Restzeit. **Kein** Job-Upload von der Site (Developer-Mode-Pflicht wäre Bambu-Cloud-Verlust).
---
## 6. Slot-System
> 📎 Detail mit Sequenz-Diagrammen + UI-Skizze: [[slotsystem]].
- **Windhund-Prinzip** als Default, Lehrer kann priorisieren oder verschieben.
- **Slot-Buchung erst freigeschaltet nach L1 (Sicherheits-Lektion)** — V2, [[../decisions#E-020]].
- Drucker dürfen über Nacht / Freistunden laufen.
- Drucker-Ausfall → Admin-Vorschlag „Slot auf anderen Drucker verschieben".
---
## 7. Stunden-Beginn-Abfrage (V3 — radikal kurz)
UI im Cockpit beim ersten Aufruf eines Besuchstages:
```
┌─ Hallo Mia! Was machst du heute? ──────────┐
│ │
│ ◉ Ich arbeite an meinem Projekt weiter: │
│ „Schlüsselanhänger mit Logo" │
│ │
│ ○ Neues Projekt anfangen │
│ ○ Onboarding-Lektion machen │
│ ○ Drucken (warte auf Drucker) │
│ ○ Anderen helfen │
│ ○ Sonstiges │
│ │
│ [Optional] kurz, was genau: │
│ ┌──────────────────────────────────────┐ │
│ │ │ │
│ └──────────────────────────────────────┘ │
│ │
│ [Los geht's] │
└──────────────────────────────────────────────┘
```
**Verhaltens-Details (V3 + E-021):**
- Default-Auswahl ist „Ich arbeite weiter" mit Titel des aktiven Projekts — **ein Klick reicht**.
- Freitext **ist immer optional**, nicht Pflicht.
- Nur einmal pro Besuchstag (UNIQUE-Constraint auf `check_in`).
- Lehrer-Dashboard zeigt alle Antworten des Tages aggregiert (siehe [[lehrer-dashboard]]).
---
## 8. Software-Sektion
| Software | Wofür | Lektion |
|---|---|---|
| **Bambu Studio** | Slicer (PC), Pflicht | L1 |
| **Bambu Handy** | Live-Kamera, Druck-Steuerung | L1 |
| **Bambu Academy** | Kostenloser Drucker-Kurs mit Zertifikat | L1 |
| **Printables.com** | Modell-Plattform (sauber, kein NSFW) | L2 |
| **MakerWorld.com** | Bambu-eigene Plattform + Customizer | L2 + L3 |
| **TinkerCAD** | Visuelles CAD im Browser, Klassenraum-Modus | L4 |
| **OpenSCAD** | Parametrisches CAD (Code) | L4+ |
**Nicht empfohlen:** Thingiverse (NSFW-Ads), Cults3D (Bezahl-Push).
---
## 9. Sicherheit + Organisation
> 📎 Detail: [[sicherheit]]. Quellen: siehe [[COCKPIT#wichtige-externe-quellen]].
- **UKBW-Richtlinie** als Basis für L1.
- **PLA + PLA+ als Default**, PETG + ABS nur unter Aufsicht (Admin-Toggle).
- **A1 mini (offen):** explizite Hands-Off-Regel beim Hotend.
- **Druckraum mit Dauerlüftung** → entspannte Lage.
---
## 10. ZSL-Material als Seed-Inhalt
Bei Kursstart ist die Projekt-Bibliothek leer. Damit Neuzugänge nicht ins Nichts schauen:
- **8-10 ZSL-Projekte** aus dem CC-BY-4.0-Material des Landes Baden-Württemberg werden in unser Design **umgearbeitet** (mit Urhebernachweis).
- Markus + Herb wählen aus den 20+ verfügbaren Projekten gemischte Schwierigkeit.
- Beschreibungen werden auf unsere Bambu-Drucker + 8-10-SuS-AG angepasst (keine 1:1-PDF-Einbettung).
- Bilder + STLs werden mit Quellen-Hinweis übernommen.
- Diese Projekte erscheinen als reguläre Katalog-Karten mit Badge „Vorlagen-Projekt".
Über die Jahre **wächst die Bibliothek durch SuS-Projekte selbst** — siehe [[selbstlern-loop]].
Details: [[../decisions#E-022]].
---
## 11. Implementierungs-Etappen (Übersicht)
> 📎 Lebende Detail-Version mit Checkboxen: [[etappen]].
Etappen sind seit V8 ([[../decisions#E-020]]) **mit Blueprint-Struktur von Anfang an** gedacht:
```
0 ✓ Skelett anlegen (2026-05-23)
1 Basis: Login + Profile + Onboarding-Status + Inline-Edit + Persistenter Lockout
2 Cockpit (progressiv, V1) + Check-In + Paarung + Lehrer-Dashboard (V5)
3 Lektionen + Software-Sektion + Troubleshooting
4 Drucker-API-Spike (Bambu-Cloud-Auth + Felder-Validierung)
5 Drucker-Integration + Live-Status + manueller Override
6 Selbstlern-Loop: Projekt-Katalog + Lebenszyklus + Files + Review + Three.js
7 Slot-System (gesperrt bis L1, V2) + Druckaufträge
8 ZSL-Material-Import (8-10 Projekte umgearbeitet)
9 Deploy + Polish (DNS, nginx, systemd, PummelHummel)
```
Erwarteter Gesamtaufwand: 8-10 Coding-Sitzungen.
---
## 12. Offene Punkte (lebende Liste)
> 📎 Aktuelle Liste: [[offene-fragen]]. Geklärte Punkte stehen in [[decisions]].
**Vor Implementation noch zu klären** (mit Markus oder im Doing):
- Welche 8-10 ZSL-Projekte konkret? (mit Markus)
- Material-Tracking als späteres Modul nötig? (siehe [[offene-fragen]])
- Bambu-Cloud-Account-Inhaber (Schul-Account vs. Herb privat)
- A1-mini-Firmware-Version (für API-Kompatibilität)
---
## 13. Quellen
- **PHBern IdeenSet 3D-Drucken**: https://www.phbern.ch/dienstleistungen/unterrichtsmedien/ideenset-3d-drucken
- **inf-schule.de 3D-Druck**: https://inf-schule.de/informatiksysteme/3d_druck
- **ZSL Baden-Württemberg „3D-Druck erleben"**: CC-BY-4.0, im OneDrive-Bücher-Ordner
- **UKBW Sicherheit (PDF)**: https://www.ukbw.de/fileadmin/user_upload/Sicherer-Umgang-mit-3D-Druckern-in-der-Schule.pdf
- **Bambu Lab Academy**: https://bambulab.com/en/support/academy
- **Printables Education**: https://www.printables.com/education
- **bambulabs_api (Python)**: https://github.com/BambuTools/bambulabs_api
---
## 14. Was als Nächstes passieren muss
1. **Markus liest dieses Konzept** + die Detail-Module ([[selbstlern-loop]], [[lehrer-dashboard]], [[datenmodell]]).
2. Markus + Herb wählen die 8-10 ZSL-Projekte aus (siehe §10).
3. **DNS**: `3d.lehrstun.de` als A-Record auf 46.225.114.15 anlegen.
4. **Etappe 1 starten**: Blueprint-Struktur + Login + Profile + Onboarding-Status (siehe [[etappen]]).

147
docs/lehrer-dashboard.md Normal file
View File

@@ -0,0 +1,147 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-24
tags: [konzept, admin, dashboard]
---
# Lehrer-Dashboard mit Drill-Down
> **V5 aus der Reality-Check-Analyse** ([[../decisions#E-020]]). Schließt eine
> bekannte Lücke des Arduino-Kurses, wo Herb manuell in jedes Gruppen-Cockpit
> schauen muss, um zu sehen, wer wo steht.
Route: `/admin/dashboard`. Berechtigung: `@admin_required`. Vom Cockpit nicht zu verwechseln — das ist der **Lehrer-Arbeitsplatz**.
## Layout-Skizze
```
┌─ Admin-Dashboard ──────────────────────────────────────────────┐
│ │
│ ┌─ Wer ist heute hier (basiert auf check_in von HEUTE) ───┐ │
│ │ 🦊 Mia "Schlüsselanhänger weitermachen" → [→] │ │
│ │ 🦦 Tom "neues Projekt: Wasserrakete" → [→] │ │
│ │ 🐧 Lara "L2 fertig machen" → [→] │ │
│ │ 3 SuS heute eingeloggt │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Wartet auf Lehrer-Reaktion ─────────────────── [3] ─────┐ │
│ │ 🟡 Mia — "Schlüsselanhänger" zur Freigabe (2 Tage) │ │
│ │ 🟡 Tom — "Drohnenrahmen" zur Freigabe (heute) │ │
│ │ 🔵 Lara — Rückfrage offen seit 5 Tagen │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Drucker-Status (live) ─────────────────────────────────┐ │
│ │ 🟢 P1S #1 drucken "Schlüsselanhänger Mia" 43% │ │
│ │ 🟢 P1S #2 idle │ │
│ │ 🟡 X1C drucken "Drohnenrahmen Tom" 89% │ │
│ │ 🔴 A1 mini offline (Status veraltet >5min) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Wer hängt fest (>2 Wochen kein Fortschritt) ───────────┐ │
│ │ 🐝 Anna — letzter Check-In vor 3 Wochen │ │
│ │ → [Erinnerungs-Notiz im Cockpit hinterlassen] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## Sektion 1: Wer ist heute hier
**Datenquelle:** `check_in` mit `besuch_datum = TODAY`.
**Inhalt pro Zeile:**
- Tier-Icon + Vorname (Klick → Profil-Detail)
- Modus aus Check-In (z.B. „weiter wie bisher", „neues Projekt", „onboarding", „helfen")
- Optionaler Freitext aus Check-In (falls vorhanden, in kursiv)
- Link zum aktuellen Projekt (falls vorhanden)
- Quick-Action: „Notiz hinterlassen" → schreibt Lehrer-Notiz ins SuS-Cockpit
**Zweck:** In den ersten 5 Minuten der AG-Stunde weiß der Lehrer ohne Rumfragen, was läuft.
## Sektion 2: Wartet auf Lehrer-Reaktion
**Datenquelle:** Zwei Untergruppen:
1. **Projekte mit `freigabe_status = 'wartet_auf_freigabe'`** — sortiert nach Wartezeit, älteste oben.
2. **Rückfragen** mit `status = 'offen'`, die schon länger als 3 Tage warten — der SuS hat möglicherweise vergessen, nachzubessern.
**Badge im Header:** Anzahl der zu reviewen Projekte. Sichtbar auch in der Navigation (klein, rote Zahl neben „Admin").
**Quick-Action:** Klick auf Eintrag → `/admin/projekt-freigabe/<id>` öffnet Detail-Review mit Three.js-Vorschau, allen Files, Edit-Möglichkeit, Freigeben-/Rückfrage-/Löschen-Buttons.
**Zweck:** Review-Last sichtbar machen, damit nichts liegen bleibt.
## Sektion 3: Drucker-Status (live)
**Datenquelle:** `drucker_status` (vom Bambu-Cloud-Polling befüllt — siehe [[druckerapi]]).
**Inhalt pro Drucker:**
- Status-Ampel (🟢 druckt/idle, 🟡 pausiert/Wartung, 🔴 offline/failed)
- Drucker-Name + Modell
- Aktueller Job-Name (wenn drucken)
- Fortschritt + Restzeit
- Quick-Action bei roter Ampel: „Manueller Status setzen" (Override)
**Zweck:** Der Lehrer sieht beim Reinkommen in den Druckraum sofort, welche Drucker frei sind, welche fertig zur Abholung sind, welche Probleme haben.
## Sektion 4: Wer hängt fest
**Datenquelle:** SuS, die in den letzten 2 Wochen weder einen `check_in` gemacht haben noch ein Projekt abgeschlossen haben.
**Zweck:** Stille Aussteiger erkennen. Wer 3 Wochen nicht da war, ist möglicherweise nicht mehr dabei — oder braucht eine kurze Nachricht.
**Quick-Action:** „Erinnerungs-Notiz im Cockpit hinterlassen" — beim nächsten Login sieht der SuS ein grünes Banner („Hey, lange nicht gesehen — alles okay?").
## Performance-Hinweise
Das Dashboard macht 4 Queries:
- `SELECT` aus `check_in WHERE besuch_datum = TODAY` + JOIN `profil` + LEFT JOIN aktives `projekt`
- `SELECT` aus `projekt WHERE freigabe_status IN ('wartet_auf_freigabe')` + JOIN `profil`
- `SELECT` aus `drucker_status` (4 Zeilen)
- Subquery für „hängt fest"-Liste
Alle Indexes setzen: `idx_projekt_freigabe`, FK-Index auf `check_in.besuch_datum`. Bei 8-10 SuS und ~50 Projekten/Jahr ist Performance kein Thema.
## Quick-Action-Mechanik: „Notiz im Cockpit hinterlassen"
Tabelle `lehrer_notiz` (neu):
```sql
CREATE TABLE lehrer_notiz (
id INTEGER PRIMARY KEY AUTOINCREMENT,
profil_id INTEGER NOT NULL, -- Adressat
von_profil_id INTEGER, -- Lehrer (NULL = System)
text TEXT NOT NULL,
erstellt_am DATETIME DEFAULT CURRENT_TIMESTAMP,
gelesen_am DATETIME, -- NULL = ungelesen
typ TEXT DEFAULT 'info', -- 'info'|'rueckfrage'|'erinnerung'
FOREIGN KEY (profil_id) REFERENCES profil(id) ON DELETE CASCADE
);
```
Wird im Cockpit als gelbes Banner gerendert (analog zur Rückfrage-Mechanik V6). SuS kann jede Notiz mit „verstanden" wegklicken → `gelesen_am` wird gesetzt.
## Was das Dashboard NICHT zeigt
- Keine Aggregate über die ganze AG-Historie (das wäre Statistik, gehört in `/admin/statistik` als optionaler späterer Bereich).
- Keine Daten anderer Lehrkräfte (es gibt nur Herb + Markus, gleiche Sicht).
- Kein Eingriff in laufende Druckjobs — das macht weiterhin die Bambu Handy App.
## Inline-Edit-Berechtigungen für Lehrer
Aus [[routen#inline-edit-whitelist]]:
- Lektionen: titel, aufgabe_md, tipp_md, extern_link — **immer**.
- Software-Seiten: titel, inhalt_md, url, quickstart_md — **immer**.
- Projekte: titel, beschreibung_md, tags — **nur während Review** (Status `wartet_auf_freigabe` oder `rueckfrage`).
- Einstellungen: wert — **immer**.
Jede Inline-Edit-Aktion landet in `aenderung_log` mit Lehrer-Profil-ID. So bleibt nachvollziehbar, wer was wann geändert hat.
## Querverweise
- Routen: [[routen#admin-routesadminpy--herb--markus]]
- Selbstlern-Loop (das Dashboard zeigt dessen Status): [[selbstlern-loop]]
- Drucker-Anbindung: [[druckerapi]]
- Datenmodell: [[datenmodell]]
- Entscheidung V5: [[../decisions#E-020]]
- Rückfrage-Mechanik V6: [[../decisions#E-020]]

View File

@@ -0,0 +1,56 @@
---
type: lektion
nummer: 1
pflicht: true
titel: "Drucker-Kennenlernen + Sicherheit"
stand: stub
tags: [lektion, pflicht, sicherheit]
---
# L1 — Drucker-Kennenlernen + Sicherheit
> **Status: Stub.** Inhalte werden mit Markus erarbeitet. Struktur steht.
> Übergeordnetes Konzept: [[../kurskonzept#vier-stufen-progression]].
## Lernziel
Die SuS können:
- die 4 Drucker im Raum unterscheiden ([[architektur|wer welcher Drucker]]).
- die [[sicherheit|Sicherheits-Regeln]] benennen und einhalten.
- ein vorbereitetes Modell in [[software-bambu-studio|Bambu Studio]] öffnen und auf einen Drucker schicken.
- die [[software-bambu-handy|Bambu Handy App]] einrichten und ihren Druck verfolgen.
## Aufbau der Stunde
1. **Empfang im Druckraum** (5 Min) — Drucker zeigen, Druckraum-Regeln.
2. **Sicherheits-Lektion** (15 Min) — A1 mini-Hands-Off, PLA-only-Default, was bei Fehlern. Quelle: [[sicherheit]].
3. **Bambu Handy App einrichten** (10 Min) — App-Store, Account-Daten von Herb, Drucker hinzufügen.
4. **Vorbereitetes Modell drucken** (Rest der Stunde + läuft drüber hinaus) — bewährtes Test-Modell (Vorschlag: kleines Benchy oder Schlüsselanhänger-Rohling). SuS startet den Druck selbst, beobachtet die erste Schicht.
5. **Abholung in nächster Stunde**.
## Was die Plattform dazu liefert
- Diese Lektion als Seite mit Bambu Academy-Link, eingebettetem Sicherheits-Video, Quiz?
- Buchung des Test-Drucks als ersten [[slotsystem|Slot]] (mit Herb-Anleitung).
- Erst-Druckauftrag als ersten Eintrag in der eigenen [[datenmodell#druckauftrag|Auftrags-Liste]].
## TODO mit Markus
- [ ] Welches **Test-Modell** als "garantierter Erfolg"?
- Optionen: 3DBenchy (Standard), kleiner Schlüsselanhänger-Rohling, Pinguin von Printables
- [ ] **Sicherheits-Video von Bambu** verlinken oder eigenes drehen?
- [ ] **Quiz am Ende** (3-5 Fragen zur Sicherheit)?
- [ ] Bambu Academy-Kurs als optionale Hausaufgabe?
## Material-Bedarf
- 1 Rolle PLA pro 2-3 Test-Drucke
- SuS-Smartphones mit Internet (für Bambu Handy)
- Vorbereitetes 3MF-File von Herb für jedes Druckermodell
## Querverweise
- Nächste Lektion: [[lektion-L2-modell-drucken]]
- Software dieser Lektion: [[software-bambu-studio]], [[software-bambu-handy]]
- Grundlagen: [[sicherheit]], [[glossar]]
- Drucker-Übersicht: [[architektur]]

View File

@@ -0,0 +1,52 @@
---
type: lektion
nummer: 2
pflicht: true
titel: "Fremdes Modell wählen + drucken"
stand: stub
tags: [lektion, pflicht]
---
# L2 — Fremdes Modell wählen + drucken
> **Status: Stub.** Voraussetzung: [[lektion-L1-drucker-kennenlernen]].
## Lernziel
Die SuS können:
- ein passendes Modell auf [[software-printables|Printables]] oder [[software-makerworld|MakerWorld]] finden.
- die **Lizenz** des Modells prüfen (CC-BY, CC-BY-NC, …) und wissen, was sie damit dürfen.
- ein STL/3MF in [[software-bambu-studio|Bambu Studio]] importieren, ausrichten, slicen.
- die geschätzte Druckzeit und den Materialverbrauch lesen.
- den Druck planen und auf der Plattform als [[datenmodell#druckauftrag|Druckauftrag]] eintragen.
## Aufbau der Stunde
1. **Plattform-Rundgang** (10 Min) — [[software-printables|Printables]] zeigen, Suche, Filter, Lizenz-Hinweise.
2. **Eigene Wahl** (10 Min) — SuS sucht sich ein Modell. Tipp: erstmal klein (unter 1h Druckzeit).
3. **Slicen + Planen** (15 Min) — Modell in Bambu Studio öffnen, ausrichten (Druckbett-Orientierung!), slicen, Zeit + Material notieren.
4. **Eintragen + Buchen** (10 Min) — Druckauftrag auf der Plattform anlegen, [[slotsystem|Slot]] reservieren.
5. **Drucken** (asynchron, während der Stunde oder über Nacht).
## Was die Plattform dazu liefert
- Liste empfohlener Such-Stichwörter für [[software-printables|Printables]].
- Quick-Reference für **Lizenz-Symbole** (CC-Familie kurz erklärt).
- Vorlage für den ersten eigenen [[datenmodell#druckauftrag|Druckauftrag]].
## TODO mit Markus
- [ ] **Empfohlene Modell-Liste** auf Printables zusammenstellen? Oder freie Wahl?
- [ ] **Lizenz-Schulung**: wie tief erklären? Wir drucken nur, geben nichts weiter — Lizenz-Sorge ist gering.
- [ ] **Druckzeit-Grenze**: max. 2 h für L2? Oder offen?
## Material-Bedarf
- Wie L1, je nach SuS-Wahl 1 Rolle PLA pro 4-6 Drucke
## Querverweise
- Vorher: [[lektion-L1-drucker-kennenlernen]]
- Nachher: [[lektion-L3-customizer]]
- Software: [[software-bambu-studio]], [[software-printables]], [[software-makerworld]]
- DB: [[datenmodell#druckauftrag]]

View File

@@ -0,0 +1,53 @@
---
type: lektion
nummer: 3
pflicht: true
titel: "Customizer / parametrisches Modell"
stand: stub
tags: [lektion, pflicht]
---
# L3 — Customizer / parametrisches Modell
> **Status: Stub.** Voraussetzung: [[lektion-L2-modell-drucken]].
> **Pädagogische Brücke** zwischen "fremdes Modell drucken" und "selbst zeichnen".
## Lernziel
Die SuS können:
- den Begriff **parametrisches Modell** erklären (Maße/Texte/Optionen veränderlich).
- den [[software-makerworld#customizer|MakerWorld-Customizer]] bedienen.
- ein parametrisches Modell so anpassen, dass es ihre eigene Note bekommt (Name, Maße, Symbol).
- den Unterschied "fertig laden" vs. "selbst customizen" vs. "selbst zeichnen" erklären.
## Aufbau der Stunde
1. **Was ist parametrisch?** (5 Min) — Lehrer-Demo: Schlüsselanhänger-Generator, ein Mal mit Maximilian, ein Mal mit Lisa, ein Mal mit "Pizza".
2. **Eigene Wahl** (15 Min) — SuS sucht sich einen Customizer aus, vorzugsweise einen kleinen + schnellen.
3. **Anpassen + Slicen** (10 Min) — Werte verändern, Vorschau, dann STL/3MF exportieren und in [[software-bambu-studio|Bambu Studio]] slicen.
4. **Reflexion** (5 Min) — Was war einfach, was nicht? Wie wäre es, das **ganz von vorne** zu zeichnen? → leitet zu L4+ über.
5. **Drucken** (asynchron).
## Empfohlene Customizer für L3 (TODO mit Markus prüfen)
- [Parametric Customizable Name Keychain Creator](https://makerworld.com/en/models/1320280) — der Klassiker
- weitere folgen, sobald Markus + Herb durchgespielt haben
## Was die Plattform dazu liefert
- Anleitung "So funktioniert ein Customizer" mit Screenshots.
- Liste der empfohlenen Customizer.
- Verknüpfung zum nächsten Schritt: [[../kurskonzept#vier-stufen-progression|L4+ — eigenes Modell]].
## TODO mit Markus
- [ ] **Customizer-Liste** kuratieren: 3-5 Stück, klein + schnell + cool.
- [ ] Wie tief auf **Lizenz** beim Customizer-Output eingehen?
- [ ] **Anschluss zu L4**: lassen wir die SuS ihre Reflexion schriftlich machen oder mündlich?
## Querverweise
- Vorher: [[lektion-L2-modell-drucken]]
- Anschluss (frei): TinkerCAD → [[software-tinkercad]], OpenSCAD → [[software-openscad]]
- Tool: [[software-makerworld]]
- Konzept-Begründung "warum diese Brücke?": [[../kurskonzept#warum-diese-reihenfolge]]

99
docs/offene-fragen.md Normal file
View File

@@ -0,0 +1,99 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-24
tags: [offen, klärungsbedarf]
---
# Offene Fragen
> Wird laufend gepflegt. Wenn eine Frage entschieden ist, wandert sie nach
> [[decisions]] und wird hier gestrichen.
>
> **Geklärt am 2026-05-24:** Onboarding-Zertifizierung (selbst, E-019),
> Three.js-Dependency (ja, E-018), ZSL-Projekt-Menge (8-10, E-022),
> Slot-Granularität-Default (freie Zeitspannen, E-020 V8), Brand-Farbe
> (Teal wie Arduino für einheitliches Wirken, kein eigener Decision-Eintrag —
> ist implizit aus E-001).
## Vor Etappe 1 zu klären
### Bambu-Cloud-Account
- **Wer ist Account-Inhaber?** Schul-Account oder Herb privat?
- Hat der Account alle 4 Drucker in derselben Region (EU)?
- Brauchen wir 2FA-Bypass / App-Passwort?
→ siehe [[druckerapi#auth]]
### A1 mini Genau-Bezeichnung
- Welche Firmware-Version aktuell?
- Sind alle 4 Drucker im selben WLAN?
### Domain-Vorbereitung
- DNS-A-Record `3d.lehrstun.de → 46.225.114.15` anlegen (via [Hetzner Cloud DNS-CLI](file:///D:/Claude-Projekte/hetzner-dns-cli/))
- Port 5057 in der CLAUDE.md-Konvention reservieren (ist bereits notiert)
## Vor Etappe 6 (Selbstlern-Loop) zu klären
### Material-Tracking — eigenes Modul?
**Kontext (aus Reality-Check):** Aktuell führt Herb Material-Bestand (welche Filament-Rollen + Farben sind da, welche fast leer) im Kopf. Wenn Markus auch reviewt + ggf. nachbestellt, brauchen sie eine gemeinsame Sicht.
**Vorschlag:** Eigene `material_rolle`-Tabelle (Hersteller, Farbe, Material-Typ, Restmenge geschätzt, Standort, Notiz). Im `druckauftrag`-Modell ein optionales `material_rolle_id`-Feld → SuS oder Lehrer kann beim Druckabschluss „X Gramm verbraucht" eintragen. Admin-Übersicht zeigt Bestand.
**Optional, nicht Etappe-1-Thema.** Wenn entschieden, kommt es als Etappe 10 dazu.
### Mentor-Badge / aktive Vernetzung
**Kontext:** Variante 1 (SuS stöbert selbst) macht die Vernetzung passiv. Wenn Mias Projekt 3x als Vorlage gewählt wurde, könnte ein „Mentor"-Badge automatisch aufploppen — sichtbar im Profil und im Lehrer-Dashboard.
**Spätere Iteration**, nicht initial. Erfordert: SuS müssen einverstanden sein (kein automatisches Outing).
### Foto-Galerie pro Projekt (mehrere Fotos im Lifecycle)
Aktuell sieht das Datenmodell beliebig viele `projekt_datei` mit `art='foto'` vor — aber UI-seitig wird nur das **erste** als Cover gezeigt. Sollen wir später eine richtige Galerie bauen (Anfang/Mitte/Ende-Bilder)?
**Spätere Iteration**, kommt mit Bedarf.
## Pädagogisch (mit Markus)
### Welche 8-10 ZSL-Projekte zum Start?
Aus den 20+ ZSL-Projekten auswählen (siehe Material-Übersicht im OneDrive). Vorschlag: 3 aus Level 1 (Einsteiger), 3-4 aus Level 2 (Mittel), 2-3 aus Level 3 (Fortgeschritten).
**Heuristik für die Auswahl:**
- Druckzeit unter 4 Stunden auf P1S
- Funktioniert mit PLA
- Cover-Foto bereits vorhanden
- Keine SuS-Erfahrung von extern nötig
**Spezifische Kandidaten** (Empfehlung von Claude, nicht final):
- Level 1: Schlüsselanhänger, Teigstempel, Spielfigur
- Level 2: Faschingsbrille, Stifteigel, Smartphonehalterung (Frosch)
- Level 3: Steckklammer, Handventilator
**Markus + Herb müssen das gemeinsam durchsehen.**
### Inhalte L1-L3
- **L1:** Welches Modell als „garantierter Erfolg"? Vorschlag: kleines Benchy ODER Schlüsselanhänger-Rohling (passt zu L3-Customizer-Anschluss).
- **L2:** Empfehlen wir eine konkrete Modell-Liste auf Printables, oder freie Wahl?
- **L3:** Welcher MakerWorld-Customizer als Erstgehversuch? Vorschlag: [Parametric Name Keychain Creator](https://makerworld.com/en/models/1320280).
→ alle mit Markus besprechen, dann in [[lektion-L1-drucker-kennenlernen]] etc. einpflegen.
### Bewertung / Dokumentation für Außenwirkung
- AG ist unbenotet — aber sollen SuS-Projekte mit Bild in einer „Galerie" auf der Schul-Website oder im Jahresbericht erscheinen? Datenschutz: Eltern-OK pro Projekt nötig.
- Vorschlag: nicht initial; nach 1 Jahr AG mal mit Schulleitung quatschen, wenn etwas vorzeigbares da ist.
## Späterer Optimierungs-Bedarf
- **Speicher-Migration:** Wenn DB > 5 GB wird (~2-3 Jahre AG-Laufzeit), Migration der BLOB-Dateien auf Hetzner Object-Storage. Vorbereitet durch Abstraktion in `services/datei.py`.
- **Performance-Indexes:** Wenn Cockpit-Ladezeiten merklich werden, ggf. zusätzliche Indexes auf `check_in.besuch_datum` und `projekt.geaendert_am` setzen.
- **Bambu-API-Bruch-Plan:** Wenn die inoffizielle API länger als 1 Woche bricht, Variante (b) aus der API-Recherche aktivieren (Pi-Bridge in der Schule).
## Querverweise
- Entschiedene Punkte: [[decisions]]
- Konzept-Hauptdokument: [[../kurskonzept]]
- COCKPIT: [[../COCKPIT]]

126
docs/routen.md Normal file
View File

@@ -0,0 +1,126 @@
---
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 + 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.
```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.

176
docs/selbstlern-loop.md Normal file
View File

@@ -0,0 +1,176 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-24
tags: [konzept, selbstlern-loop, projekte, kern]
---
# Selbstlern-Loop
> **Der Kern der 3D-Druck-AG-Site.** Was uns vom Arduino-Kurs unterscheidet:
> Die Site **wächst durch die SuS selbst**. Jedes abgeschlossene Projekt landet
> nach Lehrer-Freigabe in der internen Bibliothek. Neue SuS sehen: "Bei uns
> hat das schonmal jemand gemacht — und so ging's aus." Das schlägt jeden
> externen Modell-Katalog.
Architektur-Einbettung: [[architektur]]. Datenmodell: [[datenmodell#projekt]],
[[datenmodell#projekt_datei]], [[datenmodell#projekt_tag]]. Lehrer-Sicht: [[lehrer-dashboard]].
## Der Lebenszyklus eines Projekts
```mermaid
stateDiagram-v2
[*] --> Stoebern
Stoebern --> Ausgewaehlt: SuS wählt aus Katalog (oder eigene Idee)
Ausgewaehlt --> InArbeit: Projekt angelegt im Cockpit
InArbeit --> InArbeit: Dateien hochladen, slicen, drucken, iterieren
InArbeit --> AbschlussCheckliste: Knopf "Projekt beenden"
AbschlussCheckliste --> WartetAufFreigabe: Pflicht-Checkliste erfüllt
AbschlussCheckliste --> InArbeit: Zurück (Checkliste unvollständig)
WartetAufFreigabe --> Freigegeben: Lehrer-OK
WartetAufFreigabe --> Rueckfrage: Lehrer hat Hinweis
Rueckfrage --> InArbeit: SuS bessert nach
WartetAufFreigabe --> [*]: Lehrer hart-löscht (Penismodell etc.)
Freigegeben --> [*]: Projekt im Katalog sichtbar
Freigegeben --> Stoebern: Andere SuS wählt es als Vorlage
```
## Station 1: Stöbern
**UI:** `/projekte` — Projekt-Katalog.
**Inhalt:**
- Karten mit Cover-Foto, Titel, Macher (Vorname + Tier-Icon), Selbsteinschätzung (🟢🟡🔴), Tags.
- Filter: nach Tag, Schwierigkeitslevel (Anfänger/Mittel/Fortgeschritten), Erfolgsstatus, Macher.
- Auch ZSL-Projekte (umgearbeitet, mit CC-BY-4.0-Nachweis — siehe [[../decisions#E-022]]) erscheinen als Karten.
- Suchfeld für Titel-Volltext.
**Ankerseite für die Vernetzung (Variante 1):** SuS sucht selbst, kein Auto-Match-Knopf. Wenn Mia das gleiche Projekt schon gemacht hat, sieht der neue SuS die Karte und kann sie in der AG-Stunde ansprechen.
## Station 2: Auswählen
**UI:** `/cockpit/projekt/neu`.
Drei Optionen:
1. **Aus Katalog**: SuS klickt auf eine Karte → „Sowas mache ich auch" → neues Projekt-Datensatz mit `vorlage_projekt_id` befüllt. Titel + Tags vorausgefüllt, SuS kann anpassen.
2. **Komplett eigene Idee**: leerer Titel + Beschreibung.
3. **Onboarding-Pflicht-Projekt** (z.B. L2 „erstes Modell drucken"): die Lektion legt automatisch ein Projekt an.
## Station 3: Arbeiten
**UI:** Cockpit-Karte „Eigene Projekte" mit Liste der eigenen `status_lebenszyklus='in_arbeit'`-Projekte.
**Was passiert hier:**
- Datei-Uploads (laufend oder am Ende, frei): STL, 3MF, Fotos, Sonstiges. Limit 30 MB pro Datei.
- Beschreibung pflegen (Markdown).
- Druckaufträge anlegen (`/cockpit/druckauftrag/neu`), Slots reservieren.
- Mit anderen SuS in der AG sprechen — die Site lenkt nicht aktiv.
## Station 4: Abschluss-Checkliste
**UI:** `/cockpit/projekt/<id>/abschluss`.
**Pflicht-Felder (V4, radikal kurz):**
- **Selbsteinschätzung** (Pflicht, eine Wahl):
- 🟢 Bin zufrieden, würde es so wieder machen
- 🟡 Funktioniert, aber ich würde Sachen anders machen
- 🔴 Hat nicht geklappt, aber ich habe was gelernt
- **Cover-Foto ODER STL/3MF** (mindestens eines): ein Bild, das im Katalog erscheint. Wenn nur STL vorhanden: Lehrer kann beim Review per Three.js-Vorschau einen Screenshot machen.
- **Mindestens 1 Tag** (frei wählbar oder aus kuratierter Liste).
**Optional, aber empfohlen:**
- Beschreibungs-Freitext (Markdown).
- Freitext „Was würdest du anderen mit auf den Weg geben?" — wird im Detail bei der Karte angezeigt, ist die wichtigste Lehrgeld-Quelle für nächste SuS.
- Weitere Dateien.
**Knopf „Abschicken":** ist erst aktivierbar, wenn alle Pflicht-Felder erfüllt sind.
**Nach Abschicken:** `freigabe_status = 'wartet_auf_freigabe'`, im Cockpit erscheint die Karte mit Hinweis „Wartet auf Lehrer-Freigabe (typisch 1-3 Tage)".
## Station 5: Lehrer-Review
**UI:** `/admin/projekt-freigabe` (Liste) → `/admin/projekt-freigabe/<id>` (Detail).
**Drei Aktionen (siehe [[../decisions#E-017]]):**
### A) Freigeben
- Lehrer prüft Cover-Foto, Beschreibung, Tags, Dateien.
- Darf Inline-editieren: Titel, Beschreibung, Tags (siehe [[routen#inline-edit-whitelist]]). Audit-Log dokumentiert jede Änderung.
- Optional: Three.js-Screenshot als Cover speichern, wenn SuS keines hochgeladen hat.
- Klick „Freigeben" → `freigabe_status = 'freigegeben'`, sofort im Katalog sichtbar.
### B) Rückfrage stellen
- Lehrer tippt Notiz (z.B. „Cover-Foto fehlt, mach bitte eines vor dem Drucker").
- Klick „Rückfrage" → `freigabe_status = 'rueckfrage'`, Eintrag in `projekt_rueckfrage`.
- SuS sieht beim nächsten Login **gelbes Banner ganz oben im Cockpit** (V6): „Markus hat eine Rückfrage zu deinem Projekt X: …".
- SuS bessert nach, klickt im Cockpit „Rückfrage erledigt + erneut zur Freigabe" → zurück auf `wartet_auf_freigabe`.
### C) Hart löschen
- Für Penismodelle, Copyright-Probleme, sonstige problematische Inhalte.
- Bestätigungsdialog: „Wirklich löschen? Dateien sind danach weg."
- Audit-Log behält: Datum, Lehrer-Profil-ID, SuS-Vorname + Tier, optional Grund. Dateien selbst werden physisch entfernt.
## Station 6: Im Katalog
**UI:** `/projekte` zeigt das Projekt für alle eingeloggten SuS.
**Detail-Seite `/projekte/<id>`:**
- Cover-Foto groß
- Titel + Macher (Vorname + Tier-Icon)
- Selbsteinschätzung als Badge (🟢🟡🔴)
- Tags als Chips (klickbar → Filter)
- Beschreibung
- „Was würdest du anderen mitgeben?" — als hervorgehobener Block
- Dateien-Liste mit Download-Buttons (Auth-Check: nur eingeloggte SuS)
- Three.js-Vorschau, wenn STL vorhanden
- **Knopf „Sowas mache ich auch"** → legt neues Projekt mit `vorlage_projekt_id` an
**Wichtig:** SuS kann das eigene Projekt auch nachträglich verbergen (`sichtbar_in_ag = 0`) — z.B. wenn ihm das später peinlich ist. Lehrer sieht es weiterhin im Admin.
## Vernetzung in der Praxis (Variante 1)
Die Site **vermittelt nicht aktiv**. Aber sie macht sichtbar, wer was schon gemacht hat. Drei Realsituationen:
1. **Neuer SuS sucht Projekt-Idee:** Klickt im Katalog herum, sieht „Schlüsselanhänger — Mia, 🟢". Geht in der nächsten AG zu Mia: „Wie hast du das gemacht?" Mia kann die Hilfe leisten, weil sie ihren Stand selbst dokumentiert hat.
2. **SuS-Stuck-Situation:** Tom hängt mit dem Drohnenrahmen fest. Lehrer schaut im Drill-Down-Dashboard (siehe [[lehrer-dashboard]]), sieht „Drohne — Lara, 🟡". Lehrer vermittelt: „Lara hat sowas gemacht, frag sie."
3. **Erfahrener SuS wird Mentor:** Wenn Mias Projekt 3x als Vorlage gewählt wurde (`vorlage_projekt_id` zeigt darauf), wäre denkbar, dass Mia einen „Mentor"-Badge bekommt. Aktuell nicht implementiert — als spätere Idee in [[offene-fragen]].
## ZSL-Material als Initial-Inhalt
Bei Kursstart ist die Bibliothek leer. Damit neue SuS nicht ins Nichts schauen, kommen **8-10 ZSL-Projekte** als Seed-Inhalt (siehe [[../decisions#E-022]]):
- Markus + Herb wählen Projekte gemischter Schwierigkeit aus den 20+ ZSL-Vorlagen.
- Beschreibungen werden in unser Design umgearbeitet (mit CC-BY-4.0-Nachweis pro Karte: „Vorlage: Tilo Bödigheimer, ZSL Baden-Württemberg, CC-BY-4.0").
- Bilder + STLs übernehmen wir 1:1 mit Quelle.
- Diese Projekte erscheinen als reguläre Katalog-Karten, sind aber **markiert als „Vorlagen-Projekt"** (Tag `zsl-vorlage` oder Badge).
- SuS können sie als Vorlage wählen — dadurch entstehen eigene Projekte daraus, die wiederum in den Katalog landen.
## Sichtbarkeit für SuS
- **Andere SuS sehen:** Cover, Titel, Macher, Tags, Selbsteinschätzung, Dateien, Beschreibung, „Was würdest du anderen mitgeben?".
- **Andere SuS sehen NICHT:** Druckaufträge, Slots, Stand-Notizen, Stunden-Beginn-Abfragen anderer.
- **Macher selbst:** sieht alles + kann eigene Projekte editieren (während `in_arbeit`).
- **Lehrer:** sieht alles immer, kann immer editieren (im Review-Modus oder via Admin).
Konsistent mit [[../decisions#E-004]] („Inspiration ja, Vergleich nein").
## Spätere Erweiterungen (nicht in Etappe 6)
Diese Ideen sind im Konzept dokumentiert, aber nicht zur Initial-Implementation geplant:
- **Mentor-Badge** für SuS, deren Projekte oft als Vorlage gewählt werden.
- **Kommentar-Funktion** unter Projekten („Mia, wie hast du den Support entfernt?").
- **Foto-Galerie pro Projekt** (mehrere Fotos im Lifecycle: Anfang, Mitte, Druck, Fertig).
- **Externe Veröffentlichung einzelner Projekte** auf Printables/MakerWorld (mit SuS-Zustimmung + Eltern-OK).
- **Speicher-Optimierung:** Migration der BLOB-Dateien auf Hetzner Object-Storage, sobald DB > 5 GB (siehe [[../decisions#E-016]]).
## Querverweise
- DB-Schema: [[datenmodell#projekt]], [[datenmodell#projekt_datei]], [[datenmodell#projekt_tag]], [[datenmodell#projekt_rueckfrage]]
- Routen: [[routen]]
- Lehrer-Sicht: [[lehrer-dashboard]]
- Entscheidungen: [[../decisions#E-014]] (Loop), [[../decisions#E-015]] (Feedback), [[../decisions#E-016]] (Files), [[../decisions#E-017]] (Review), [[../decisions#E-018]] (Three.js)

58
docs/sicherheit.md Normal file
View File

@@ -0,0 +1,58 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-23
tags: [konzept, sicherheit, material]
---
# Sicherheit & Druckraum
> Inhalt der [[lektion-L1-drucker-kennenlernen|Pflicht-Lektion L1]] basiert
> auf den Punkten hier.
## Setup an unserer Schule
- **Eigener Druckraum**, dauergelüftet → entspannte Ausgangslage.
- **4 Drucker**: 3× geschlossen (P1S/X1C/P2S), 1× **A1 mini (offen)**.
- **Materialien (Default):** PLA + PLA+. **Selten:** PETG, ABS (nur unter Aufsicht).
- **Andere Filamente** (Nylon, ASA, PC, TPU) werden nicht genutzt.
## Pflicht-Regeln für SuS
1. **Hände weg vom Hotend** — besonders beim A1 mini (offen).
2. **Nur freigegebene Filamente** — PLA/PLA+ jederzeit, andere nur mit Herb/Markus.
3. **Bei sichtbarem Fehler (Spaghetti, Warping, Rauchgeruch)** → Drucker per
Bambu Handy App **pausieren** + Herb/Markus rufen, nicht selbst dran drehen.
4. **Druckraum verlassen** ist OK, solange ein Drucker läuft (Drucker haben
Notabschaltung). Türen geschlossen halten wegen Lüftung.
## Materialkunde-Kurzfassung
| Material | Empfohlen? | Warum |
|---|---|---|
| **PLA** | ja, Default | Geringste UFP-Emissionen, niedrige Druck-Temp, bricht spröde (Splitter unkritisch) |
| **PLA+** | ja | Wie PLA, etwas zäher |
| **PETG** | mit Aufsicht | Höhere Temp, etwas mehr Emissionen, klebt am Bett — Lehrer hilft bei Einrichtung |
| **ABS** | mit Aufsicht | Höhere Temp, Geruchsbildung, **nur in geschlossenen Druckern** (nicht A1 mini), Lüftung wichtig |
PLA-Sicherheit basiert auf: [Ultimaker-Whitepaper (DE)](https://yop3d.de/wp-content/uploads/2020/07/3D-printer-emissions-and-indoor-air-quality-de.pdf), [Fraunhofer WKI](https://www.iaqip.wki.fraunhofer.de/de/themen/emissionen-aus-3d-druckern.html).
## Offizielle Schul-Richtlinie
[UKBW — Sicherer Umgang mit 3D-Druckern in der Schule (PDF)](https://www.ukbw.de/fileadmin/user_upload/Sicherer-Umgang-mit-3D-Druckern-in-der-Schule.pdf) — Pflichtlektüre für Herb + Markus, und Grundlage für die SuS-Lektion L1.
## Was die Plattform dazu beiträgt
- **Material-Auswahl** bei [[datenmodell#druckauftrag|Druckauftrag]] standardmäßig
auf PLA-Varianten beschränkt; PETG/ABS nur freischaltbar im
[[routen#admin|Admin]].
- **A1 mini-Drucker** im UI mit gelbem Hinweis-Banner: "offener Drucker, Hände weg".
- **L1-Lektion** als Pflicht-Lektion vor Drucker-Bedienung (Einleitung,
Sicherheits-Video von Bambu Academy, Quiz?).
## Querverweise
- Lektion: [[lektion-L1-drucker-kennenlernen]]
- A1 mini-Hinweise im UI: [[architektur]]
- Materialauswahl bei Druckauftrag: [[datenmodell#druckauftrag]]
- Entscheidung Material-Default: [[../decisions#E-008]]

100
docs/slotsystem.md Normal file
View File

@@ -0,0 +1,100 @@
---
type: konzept-modul
projekt: 3d.lehrstun.de
stand: 2026-05-23
tags: [konzept, slots, reservierung]
---
# Slot-System (Drucker-Reservierung)
> DB-Tabelle: [[datenmodell#slot]]. Routes: [[routen]]. Drucker-Status: [[druckerapi]].
## Ziel
Faire Verteilung der 4 Drucker auf 8-10 SuS, die unterschiedlich lange Drucke
fahren. Funktioniert auch bei Drucker-Ausfall ([[druckerapi]] kann brechen).
## Default: Windhund-Prinzip
- Wer zuerst kommt, bekommt den Slot.
- Jede:r SuS reserviert selbst über das Cockpit.
- Konflikt-Check: keine Überlappung mit aktiver/zukünftiger reservierter Reservierung
auf demselben Drucker.
## Override: Lehrer-Priorität
- Im [[routen#admin|Admin-Dashboard]] kann Herb/Markus pro Slot `prioritaet`
setzen (Default 0, höher = wichtiger).
- Sortierung im UI: `ORDER BY prioritaet DESC, erstellt_am ASC`.
- Bei Konflikt durch Priorisierung: Site zeigt eine Warnung, verschiebt
nichts automatisch — Herb entscheidet.
## Slot-Granularität (Entscheidung **offen**)
Drei Optionen, siehe [[offene-fragen#slot-granularität]]:
| Option | Vorteil | Nachteil |
|---|---|---|
| **Freie Zeitspannen** (Start + Dauer) | flexibel, passt zu realer Druckzeit (15 Min - 8 h) | Konflikt-Check komplexer |
| **Feste Stunden-Slots** | einfach zu buchen, kalenderartig | unflexibel — 4-h-Druck blockiert 4 Slots |
| **Tages-Slots** (Vormittag/Nachmittag/Nacht) | passt zu langen Drucken | zu grob für kurze Drucke |
Empfehlung aus Recherche: **freie Zeitspannen**, weil Druckzeit stark variiert.
## Drucker-Ausfall-Handling
Wenn [[druckerapi]] meldet `status = failed` oder `offline` für > 10 Min:
```mermaid
flowchart TB
A[Drucker fällt aus] --> B{Aktive Slots betroffen?}
B -- ja --> C[Dashboard: rote Markierung]
C --> D[Vorschlag: Slot auf anderen Drucker verschieben]
D --> E[Admin: 1-Klick-Verschieben]
E --> F[Slot.drucker_id ändern]
F --> G[Cockpit-Notiz für betroffene SuS]
B -- nein --> H[Drucker als 'Wartung nötig' markieren]
```
## Konflikt-Erkennung
```sql
-- Neue Reservierung würde mit bestehender überlappen?
SELECT COUNT(*) FROM slot
WHERE drucker_id = :drucker_id
AND status IN ('reserviert', 'aktiv')
AND start_zeit < :neue_ende
AND ende_zeit > :neue_start;
```
Falls > 0 Treffer: Reservierung abgelehnt mit Liste der Konflikte.
## UI-Skizze (Cockpit-Slot-Buchung)
```
┌─ Drucker reservieren ──────────────────────────┐
│ │
│ Drucker: [ ▼ P1S #1 ] │
│ Start: [ Heute, 14:30 ] │
│ Dauer: [ 2 h 30 m ] (Schätzung aus 3MF) │
│ │
│ ┌─ Kalender ────────────────────────────────┐ │
│ │ P1S #1 ▓▓░░░░░░░░░░░░▓▓▓▓▓░░░░░░░░░░░ │ │
│ │ P1S #2 ░░░░░▓▓▓▓░░░░░░░░░░░░░░░▓▓▓░░░ │ │
│ │ X1C ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ │
│ │ A1 mini ▓▓▓▓▓▓▓░░░░░░░░░░░▓▓░░░░░░░░░░ │ │
│ │ 09 11 13 15 17 19 21 23 │ │
│ └────────────────────────────────────────────┘ │
│ │
│ [ Reservieren ] │
└─────────────────────────────────────────────────┘
```
(Genaues Design folgt in [[etappen#etappe-6]].)
## Querverweise
- DB-Schema: [[datenmodell#slot]]
- Drucker-Live-Status (für Ausfall-Erkennung): [[druckerapi]]
- Routes: [[routen#profil]] + [[routen#admin]]
- Offene Frage zur Granularität: [[offene-fragen]]

View File

@@ -0,0 +1,39 @@
---
type: software
slug: bambu-handy
titel: Bambu Handy App
url: https://bambulab.com/de/download
plattform: [ios, android]
kosten: kostenlos
tags: [software, app, monitoring]
---
# Bambu Handy App
> SuS-Smartphone-Begleiter für den Druck. Sehen den eigenen Druck live, können
> ihn pausieren, sehen die Drucker-Kamera.
## Was es ist
Bambus offizielle Smartphone-App. iOS + Android, kostenlos. Verbindet sich
mit dem Bambu-Account und zeigt alle Drucker, die dem Account zugeordnet sind.
## Was die SuS damit machen
- Druckfortschritt + Restzeit ansehen, ohne im Raum zu sein.
- **Drucker pausieren / abbrechen**, wenn etwas schief geht (siehe [[sicherheit#pflicht-regeln-für-sus|Pflicht-Regel #3]]).
- Drucker-Kamera live ansehen (jeder Bambu-Drucker hat eine).
- Push-Benachrichtigung "Dein Druck ist fertig".
## Setup (in [[lektion-L1-drucker-kennenlernen|L1]] eingeführt)
1. App im Store suchen ("Bambu Handy"), installieren.
2. Einloggen mit Schul-Bambu-Account (Herb hat die Daten).
3. Alle 4 Drucker erscheinen automatisch.
## Querverweise
- Pendant am PC: [[software-bambu-studio]]
- Sicherheits-Pflicht: [[sicherheit]]
- Eingeführt in: [[lektion-L1-drucker-kennenlernen]]
- **Warum die Plattform diese Funktion nicht selbst hat:** [[druckerapi#was-wir-nicht-machen]] (Kamera-Streams auf Site = DSGVO-Schmerz)

View File

@@ -0,0 +1,49 @@
---
type: software
slug: bambu-studio
titel: Bambu Studio
url: https://bambulab.com/de/download/studio
plattform: [windows, mac, linux]
kosten: kostenlos
tags: [software, slicer, pflicht]
---
# Bambu Studio
> Der Pflicht-[[glossar#software-dateien|Slicer]] für unsere Drucker. Auf den
> Schul-PCs installieren, vor [[lektion-L1-drucker-kennenlernen|L1]] startklar.
## Was es ist
Bambu Labs eigene Slicer-Software, läuft lokal auf dem Schul-PC. Nimmt ein
STL- oder 3MF-Modell, zerlegt es in Schichten, generiert [[glossar#g-code|G-Code]]
und sendet ihn (über Bambu Cloud) an den ausgewählten Drucker.
## Was die SuS damit machen
- **L1:** vorbereitetes Modell öffnen, Drucker wählen, "Print" drücken.
- **L2:** eigenes Modell von [[software-printables]] importieren, slicen, drucken.
- **L3+:** eigene Modelle aus [[software-tinkercad]] / [[software-openscad]] importieren.
## Quickstart (intern, kurze Version für die Site)
1. Download von [bambulab.com/de/download/studio](https://bambulab.com/de/download/studio)
2. Installieren, beim Start "EU"-Region wählen.
3. Mit Schul-Bambu-Account einloggen (Herb hat die Zugangsdaten).
4. Drucker erscheinen automatisch in der Geräte-Liste.
5. Modell per Drag&Drop ins Fenster ziehen.
6. Drucker + Filament auswählen (PLA Default).
7. "Slice" → Druckzeit + Material werden gezeigt.
8. "Print" → Druckjob startet auf dem gewählten Drucker.
## Offizielle Doku
- [Quickstart EN (Bambu Wiki)](https://wiki.bambulab.com/en/software/bambu-studio/studio-quick-start)
- [Quickstart A1 DE (PDF)](https://cdn1.bambulab.com/documentation/quick-start-b7f4999004153/Quick%20start%20guide-A1-German%20Version.pdf)
- [Quickstart P1P DE (PDF)](https://cdn1.bambulab.com/documentation/quick-start-ae7a0e4825b43/de/QuickStart-P1P-DE.pdf)
## Querverweise
- Lektionen, die das nutzen: [[lektion-L1-drucker-kennenlernen]], [[lektion-L2-modell-drucken]], [[lektion-L3-customizer]]
- Verbunden mit: [[software-bambu-handy]] (Handy-Pendant)
- Bezug zu unserer Drucker-API: NICHTS direkt — wir greifen unabhängig auf die Cloud zu, siehe [[druckerapi]]

View File

@@ -0,0 +1,46 @@
---
type: software
slug: makerworld
titel: MakerWorld
url: https://makerworld.com
kosten: kostenlos (Konto nötig)
tags: [software, modelle, plattform, customizer, pflicht-l3]
---
# MakerWorld
> Bambu-eigene Modell-Plattform. **Stark im Customizer** — perfekt für [[lektion-L3-customizer|L3]].
> Konto-Pflicht für Download, deshalb nicht erste Wahl für L2.
## Wofür wir es nutzen
- **L3**: Customizer-Modelle (Schlüsselanhänger mit eigenem Namen, Box mit Wunschmaßen, …)
- Optional in L2 als Alternative zu [[software-printables|Printables]]
## Customizer
Das ist das Killer-Feature: Browser-basierte parametrische Modelle. SuS
verändern Werte (Name, Größe, Farbe) → MakerWorld rendert das fertige Modell
live → STL-Download → in [[software-bambu-studio|Bambu Studio]] slicen.
**Konkret für L3:**
- [Parametric Customizable Name Keychain Creator](https://makerworld.com/en/models/1320280)
- weitere Empfehlungen folgen aus dem L3-Stub: [[lektion-L3-customizer#empfohlene-customizer-für-l3-todo-mit-markus-prüfen]]
## Was die SuS dafür brauchen
- **Konto** — Herb klärt, ob jeder SuS ein eigenes anlegt oder ob alle einen
Schul-Account teilen. (→ in [[offene-fragen]] aufnehmen)
## Lizenz
MakerWorld hat eine eigene "MakerWorld License" plus CC-Optionen. Für unseren
Schulgebrauch (drucken für uns selbst) unkritisch.
## Querverweise
- Lektion: [[lektion-L3-customizer]]
- Slicer: [[software-bambu-studio]]
- Alternative Modell-Plattform: [[software-printables]]
- Bambu-Drucker-Anbindung: [[druckerapi]] (MakerWorld läuft technisch über
dieselbe Cloud, aber wir nutzen sie unabhängig)

61
docs/software-openscad.md Normal file
View File

@@ -0,0 +1,61 @@
---
type: software
slug: openscad
titel: OpenSCAD
url: https://openscad.org
plattform: [windows, mac, linux]
kosten: kostenlos (Open Source, GPL)
tags: [software, cad, parametrisch, frei-l4]
---
# OpenSCAD
> Parametrisches CAD — Modelle werden **als Code geschrieben**. Krönung der
> 4-Stufen-Progression. Brücke zwischen Mathe/Informatik und Werkstattproduktion.
## Was es ist
Statt mit der Maus zu klicken, schreiben SuS einen kurzen Code:
```scad
// Schluesselanhaenger
breite = 30;
hoehe = 15;
dicke = 4;
loch_radius = 3;
difference() {
cube([breite, hoehe, dicke]);
translate([5, hoehe/2, -1])
cylinder(h = dicke + 2, r = loch_radius);
}
```
→ OpenSCAD rendert ein 3D-Modell live → STL-Export.
**Magie:** Ändere eine Zahl, ändere das Modell. **Parametrisch im wahren Sinn.**
## Wofür in unserer AG
- L4+/L5+ als parametrischer Pfad, parallel zu [[software-tinkercad]].
- Brücke zur Informatik: SuS schreiben (kleinen) Code, sehen sofort die Wirkung.
## Empfohlene Tutorials / Quellen (DE)
Aus der Recherche:
- [inf-schule.de — OpenSCAD im 3D-Druck](https://inf-schule.de/informatiksysteme/3d_druck/grundlage_cad/openscad) — **erste Wahl, schul-erprobt**
- [Hessen-Hub OpenSCAD-Tutorial (PDF)](https://www.hessenhub.de/wp-content/uploads/2022/09/OpenScad-Tutorial.pdf)
- [Wikibooks OpenSCAD Benutzerhandbuch (DE)](https://de.wikibooks.org/wiki/OpenSCAD_Benutzerhandbuch/Kapitel_1)
- [attempto.blog — Programmieren ist das neue Modellieren](https://attempto.blog/de/2024/programming-3d-models-openscad/)
## Lehrer-Tipps
- inf-schule liefert komplette Lektionssequenzen — fast turnkey, mit Markus durchsehen.
- Erste Projekte: Schlüsselanhänger, Stiftehalter, Einkaufswagenchip — alle in inf-schule fertig.
## Querverweise
- Visuelle Alternative: [[software-tinkercad]]
- Slicer: [[software-bambu-studio]]
- Konzept-Pfad: [[../kurskonzept#vier-stufen-progression]]
- Entscheidung "warum OpenSCAD statt Fusion 360": [[offene-fragen#cad-schwerpunkt-l4]]

View File

@@ -0,0 +1,57 @@
---
type: software
slug: printables
titel: Printables.com
url: https://www.printables.com
kosten: kostenlos
tags: [software, modelle, plattform, pflicht-l2]
---
# Printables.com
> Modell-Plattform von Prusa. **Empfohlene Erst-Adresse** für SuS — werbefrei,
> sauber moderiert, deutsche UI, eigene Education-Sektion.
## Warum diese und nicht Thingiverse?
Aus der [Recherche](../README.md) hervorgegangen:
- **Thingiverse**: NSFW-Werbeanzeigen für 14-Jährige berichtet → nicht empfehlen.
- **Cults3D**: starke Bezahl-Push, viele kostenpflichtige Modelle → nicht empfehlen.
- **Printables**: kein NSFW, Education-Sektion, deutsche UI, optionaler Login.
- **MakerWorld**: gut für [[software-makerworld#customizer|Customizer]], aber Konto-Pflicht.
→ Default: Printables zuerst zeigen, MakerWorld speziell für [[lektion-L3-customizer]].
## Was die SuS damit machen
- **L2**: ein passendes Modell suchen, herunterladen, drucken.
- Inspiration sammeln für eigene Projekte (L5+).
## Quickstart
1. [printables.com](https://www.printables.com) öffnen.
2. Suchbegriff eingeben (z.B. "keychain", "phone stand").
3. Filter: "Print Time" auf "< 1h" stellen für schnelle Drucke.
4. Modell anklicken → "Download" (ohne Login bis 25 Modelle/Monat).
5. STL oder 3MF speichern, in [[software-bambu-studio|Bambu Studio]] importieren.
## Lizenz-Hinweise (Kurz für SuS)
Die meisten Modelle stehen unter **CC-BY** oder **CC-BY-NC**:
- **CC-BY** = darfst alles, musst Autor nennen.
- **CC-BY-NC** = wie oben, aber nicht kommerziell.
- **CC-BY-SA** = darfst alles, musst gleiche Lizenz weitergeben.
- **CC-BY-ND** = darfst nicht ändern.
Wir drucken nur für uns selbst → Lizenz-Sorge minimal.
## Education-Programm
[printables.com/education](https://www.printables.com/education) — kuratierte
Sammlung speziell für Schulen. Mit Markus durchsehen für L2-Empfehlungen.
## Querverweise
- Lektion: [[lektion-L2-modell-drucken]]
- Slicer für die Drucke: [[software-bambu-studio]]
- Alternative für Customizer: [[software-makerworld]]

View File

@@ -0,0 +1,57 @@
---
type: software
slug: tinkercad
titel: TinkerCAD
url: https://www.tinkercad.com
plattform: [browser]
kosten: kostenlos
tags: [software, cad, frei-l4]
---
# TinkerCAD
> Visuelles CAD im Browser von Autodesk. **Erster Schritt zu eigenem Modellieren**
> nach L3.
## Was es ist
Visuelles, klick-basiertes 3D-CAD. SuS ziehen Grundkörper (Quader, Zylinder, …)
auf die Arbeitsfläche, kombinieren sie, bohren Löcher mit "Hole"-Objekten,
exportieren STL.
## Klassenraum-Modus (DSGVO-tauglich)
- Lehrer (Herb) legt einen "Class"-Code an.
- SuS treten **ohne E-Mail-Adresse** bei, nur mit Klassencode + Spitzname.
- Keine personenbezogenen Daten an Autodesk.
Quellen:
- [Autodesk Children's Privacy Statement (DE)](https://www.autodesk.com/company/legal-notices-trademarks/privacy-statement-de/childrens-privacy-statement)
- [Beispiel-Datenschutz Dillenberg-Schule (PDF)](https://www.dillenberg-schule.de/informationen-formulare.html?file=files/Dillenberg/Downloads/Datenschutz+-+Nutzungsordnung/Datenschutz_Tinkercad.pdf)
## Wofür in unserer AG
- L4-Einstieg ins eigene Modellieren.
- Für schnelle eigene Ideen, die nicht durch [[software-openscad|OpenSCAD]] gehen müssen.
- "Komfort-CAD" — visuell, sofort sichtbar, niedrige Frustschwelle.
## Quickstart (intern, kurz)
1. [tinkercad.com](https://www.tinkercad.com)
2. Klassencode von Herb eingeben + Spitzname wählen.
3. "New 3D Design" → arbeiten.
4. "Export" → STL → in [[software-bambu-studio|Bambu Studio]] importieren.
## Empfohlen weil
- Werbefrei im Klassen-Modus.
- DSGVO-tauglich (keine SuS-Mail).
- Deutsche UI vollständig.
- Tutorials in der App eingebaut.
## Querverweise
- Freie Phase ab: [[lektion-L3-customizer]]
- Parametrische Alternative: [[software-openscad]]
- Slicer: [[software-bambu-studio]]
- Konzept: [[../kurskonzept#vier-stufen-progression]]