# Abnahmekriterien für den MVP (v0.1.0) Diese Liste wird von [#019](issues/019-betrieb-release.md) abschließend durchgegangen. Jeder Punkt ist entweder abgehakt oder hat ein Folge-Issue — nichts bleibt stillschweigend offen. ## Betrieb - [x] `docker compose up` startet App und Datenbank, Migrationen laufen automatisch - [x] Seed läuft per dokumentiertem Befehl, nicht automatisch - [x] Die Datenbank ist vom Host aus **nicht** erreichbar (`nc -z localhost 5432` schlägt fehl), aus `web` schon - [ ] Der Proxmox-One-Liner rollt einen LXC aus, in dem die App läuft und PostgreSQL nur am Unix-Socket hört - [x] Erneuter Aufruf des Skripts aktualisiert, ohne Daten oder Geheimnisse zu verlieren - [x] `shellcheck --severity=warning` über alle Skripte ohne Befund - [x] Läuft hinter einem Reverse Proxy ohne fest verdrahtete Adressen > **Zeile 4 bleibt offen, mit Ansage:** hier stand kein Proxmox-Host zur Verfügung. Belegt ist beides > drumherum — `laufzettel.sh --dry-run` und `--dry-run --aktualisieren` laufen vollständig durch, und > der Inhalt des Containers, `deploy/install.sh`, lief zweimal in `debian:13` und einmal unter echtem > systemd durch, mit `ss -ltn` ohne einen einzigen lauschenden TCP-Port. Offen ist allein die > `pct`-Schicht. Die Gegenprobe steht in [docs/betrieb/proxmox.md](betrieb/proxmox.md) („Was du beim > ersten Lauf selbst nachprüfen musst“), das Folge-Issue ist > [#024](issues/024-proxmox-echtlauf.md). Bedingung dafür: der Einzeiler lädt von `main` — er wird > erst nach dem Merge prüfbar. ## Anmeldung und Rechte - [x] Login per lokalem Konto funktioniert - [x] OIDC ist konfigurierbar und für authentik dokumentiert, inkl. Gruppen für Rollen - [x] Bei `AUTH_LOCAL_ENABLED=false` ist der lokale Login weg und der Endpunkt lehnt ab - [x] Rollenrechte: jede Rolle gegen jede Aktion getestet, Prüfung ausschließlich serverseitig - [x] Eine Rollenänderung greift ohne neue Anmeldung; ein deaktivierter Benutzer wird abgewiesen - [x] Passwörter stehen nur als argon2-Hash in der Datenbank, nie in einer API-Antwort ## Betriebsmodus - [x] Hauptablauf läuft in `INTERN` ohne jede Kundenanzeige (Ausnahme: die Einstellungsseite und der Wechsel-Dialog zeigen die eigene Organisation — dort ist sie zu pflegen) - [x] Hauptablauf läuft in `DIENSTLEISTUNG` mit Kundenwahl - [x] Wechsel `INTERN → DIENSTLEISTUNG` übernimmt alle Daten auf den ersten Kunden - [x] Wechsel zurück wird bei zwei nicht archivierten Kunden abgelehnt - [x] Im Modus `INTERN` ignoriert die Service-Schicht eine mitgeschickte `kundeId` - [x] Der Modus ist ohne Neustart umschaltbar, jeder Wechsel steht im `Protokoll` ## Vorlagen - [x] Veröffentlichte Version ist unveränderlich; „Bearbeiten“ erzeugt eine tiefe Kopie als Entwurf - [x] Höchstens ein Entwurf je Vorlage - [x] Veröffentlichen einer neuen Version verändert bestehende Läufe nicht - [x] Export und anschließender Import ergeben eine inhaltsgleiche Vorlage - [x] Unbekannte Platzhalter werden im Editor als Warnung angezeigt ## Läufe und Archiv - [x] Lauf ohne Mitarbeiter und ohne Gerät lässt sich starten, abschließen und archivieren - [x] Abschließen scheitert, solange ein Pflichtschritt offen ist - [x] `NICHT_ZUTREFFEND` und `FEHLGESCHLAGEN` verlangen eine Notiz - [x] „Abschnitt als nicht zutreffend markieren“ setzt alle Schritte mit einer Notiz - [x] Archiv-Schreibschutz greift für Kopfdaten, Schrittergebnisse und Kommentare - [x] Nur `ADMIN` holt einen archivierten Lauf zurück, mit `Protokoll`-Eintrag - [x] Im Archiv wird über Titel, Notizen, Werte und Kommentare gefunden - [x] Druckansicht eines Laufs ist sauber und hell ## Mitarbeiter, Geräte, QR - [x] Mitarbeitersuche liefert standardmäßig nur aktive, Umschalter zeigt auch deaktivierte - [x] Ein von der Geräteseite gestarteter Lauf hat den Besitzer vorbelegt - [x] `/t/LZ-7K3F9Q` ohne Anmeldung führt nach dem Login auf die Geräteseite - [x] „Vorlage zuweisen“ erzeugt einen `OFFEN`-Lauf, der unter „Zugewiesen“ erscheint; „Starten“ setzt `IN_ARBEIT` - [x] Unregistrierter Tag → Registrierformular → Geräteseite; unbekannter Tag → Hinweis - [x] `tagCode`: richtiges Alphabet, eindeutig, unveränderlich, nie wiederverwendet - [x] Etikettendruck in beiden Layouts sauber; QR maschinell zurücklesbar ## Platzhalter und Befehle - [x] Onboarding: Vorname und Nachname eingeben → UPN, `sam` und Mail werden vorgeschlagen - [x] Abteilung „Buchhaltung“ wählen → `-Path "OU=Buchhaltung,…"` und Gruppen `G-Buchhaltung, G-Alle` - [x] Kopieren liefert exakt diesen Text, zeichengenau - [x] „Jörg Müller-Lüdenscheid“ ergibt gültige Vorschläge (`joerg.mueller-luedenscheid@…`, `jmuellerluedensch`) - [x] `{{generiertes_passwort}}` erscheint im Befehl, steht aber nicht in Datenbank, Druckansicht oder `Protokoll` - [x] Werte mit Anführungszeichen werden für die jeweilige Shell korrekt maskiert - [x] „Alle Befehle als Skript kopieren“ liefert die Schritte in richtiger Reihenfolge - [x] Unbekannte Platzhalter bleiben stehen; ersetzte Werte sind HTML-escaped ## Verzeichnis (LDAP) - [x] Erster Abgleich legt Mitarbeiter an, zweiter aktualisiert sie ohne Duplikate - [x] Entfernte oder deaktivierte Konten werden `aktiv = false`, nie gelöscht - [x] `{{ou}}` wird korrekt aus dem `dn` abgeleitet - [x] Das Bind-Passwort erscheint in keiner API-Antwort und keinem Log - [x] Zwei gleichzeitige Abgleiche derselben Quelle: der zweite wird von der Sperre abgewiesen ## Oberfläche - [x] Am Handy kein horizontales Scrollen — bei 390 px auf allen Hauptseiten geprüft - [x] Gestaltung nach Vorgabe: dunkel, ein Akzent, keine Emojis, keine Schatten, keine Verläufe - [x] Version mit Git-SHA unten links ## Projektorganisation - [x] Issues für alle Phasen und MVP-Meilensteine existieren - [x] `CHANGELOG.md` und `docs/devlog.md` sind gepflegt - [ ] `v0.1.0` ist getaggt, Gitea-Release mit Changelog-Auszug - [x] `docs/anleitung/` vollständig mit Screenshots und als PDF - [x] `docs/screenshots/` enthält die Meilenstein-Bilder - [x] `pnpm lint && pnpm typecheck && pnpm test && pnpm pruefe:doku` grün