Files
Laufzettel/docs/abnahme-mvp.md
T
florian.wildeandClaude Opus 5 ecc3c579df
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
feat(mandant): Betriebsmodus, Kundenverwaltung und Einstellungen (#22)
Zwei Betriebsmodi, ein Codepfad. src/server/mandant.ts ist die eine Stelle,
an der die Mandantenregel steht.

Der Review fand drei Blocker: die Lesemodelle wandten die Mandantensicht nicht
an, der Protokolleintrag des Moduswechsels stand außerhalb der Transaktion, und
Prüfung und Vollzug lagen so weit auseinander, dass zwei gleichzeitige Wechsel
beide durchliefen. Alle drei geschlossen, der letzte mit einem Advisory Lock.

336 Tests.

Closes #8

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-25 05:03:11 +00:00

5.3 KiB

Abnahmekriterien für den MVP (v0.1.0)

Diese Liste wird von #019 abschließend durchgegangen. Jeder Punkt ist entweder abgehakt oder hat ein Folge-Issue — nichts bleibt stillschweigend offen.

Betrieb

  • docker compose up startet App und Datenbank, Migrationen laufen automatisch
  • Seed läuft per dokumentiertem Befehl, nicht automatisch
  • 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
  • Erneuter Aufruf des Skripts aktualisiert, ohne Daten oder Geheimnisse zu verlieren
  • shellcheck --severity=warning über alle Skripte ohne Befund
  • Läuft hinter einem Reverse Proxy ohne fest verdrahtete Adressen

Anmeldung und Rechte

  • Login per lokalem Konto funktioniert
  • OIDC ist konfigurierbar und für authentik dokumentiert, inkl. Gruppen für Rollen
  • Bei AUTH_LOCAL_ENABLED=false ist der lokale Login weg und der Endpunkt lehnt ab
  • Rollenrechte: jede Rolle gegen jede Aktion getestet, Prüfung ausschließlich serverseitig
  • Eine Rollenänderung greift ohne neue Anmeldung; ein deaktivierter Benutzer wird abgewiesen
  • Passwörter stehen nur als argon2-Hash in der Datenbank, nie in einer API-Antwort

Betriebsmodus

  • Hauptablauf läuft in INTERN ohne jede Kundenanzeige (Ausnahme: die Einstellungsseite und der Wechsel-Dialog zeigen die eigene Organisation — dort ist sie zu pflegen)
  • Hauptablauf läuft in DIENSTLEISTUNG mit Kundenwahl
  • Wechsel INTERN → DIENSTLEISTUNG übernimmt alle Daten auf den ersten Kunden
  • Wechsel zurück wird bei zwei nicht archivierten Kunden abgelehnt
  • Im Modus INTERN ignoriert die Service-Schicht eine mitgeschickte kundeId
  • Der Modus ist ohne Neustart umschaltbar, jeder Wechsel steht im Protokoll

Vorlagen

  • Veröffentlichte Version ist unveränderlich; „Bearbeiten" erzeugt eine tiefe Kopie als Entwurf
  • Höchstens ein Entwurf je Vorlage
  • Veröffentlichen einer neuen Version verändert bestehende Läufe nicht
  • Export und anschließender Import ergeben eine inhaltsgleiche Vorlage
  • Unbekannte Platzhalter werden im Editor als Warnung angezeigt

Läufe und Archiv

  • Lauf ohne Mitarbeiter und ohne Gerät lässt sich starten, abschließen und archivieren
  • Abschließen scheitert, solange ein Pflichtschritt offen ist
  • NICHT_ZUTREFFEND und FEHLGESCHLAGEN verlangen eine Notiz
  • „Abschnitt als nicht zutreffend markieren" setzt alle Schritte mit einer Notiz
  • Archiv-Schreibschutz greift für Kopfdaten, Schrittergebnisse und Kommentare
  • Nur ADMIN holt einen archivierten Lauf zurück, mit Protokoll-Eintrag
  • Im Archiv wird über Titel, Notizen, Werte und Kommentare gefunden
  • Druckansicht eines Laufs ist sauber und hell

Mitarbeiter, Geräte, QR

  • Mitarbeitersuche liefert standardmäßig nur aktive, Umschalter zeigt auch deaktivierte
  • Ein von der Geräteseite gestarteter Lauf hat den Besitzer vorbelegt
  • /t/LZ-7K3F9Q ohne Anmeldung führt nach dem Login auf die Geräteseite
  • „Vorlage zuweisen" erzeugt einen OFFEN-Lauf, der unter „Zugewiesen" erscheint; „Starten" setzt IN_ARBEIT
  • Unregistrierter Tag → Registrierformular → Geräteseite; unbekannter Tag → Hinweis
  • tagCode: richtiges Alphabet, eindeutig, unveränderlich, nie wiederverwendet
  • Etikettendruck in beiden Layouts sauber; QR maschinell zurücklesbar

Platzhalter und Befehle

  • Onboarding: Vorname und Nachname eingeben → UPN, sam und Mail werden vorgeschlagen
  • Abteilung „Buchhaltung" wählen → -Path "OU=Buchhaltung,…" und Gruppen G-Buchhaltung, G-Alle
  • Kopieren liefert exakt diesen Text, zeichengenau
  • „Jörg Müller-Lüdenscheid" ergibt gültige Vorschläge (joerg.mueller-luedenscheid@…, jmuellerluedensch)
  • {{generiertes_passwort}} erscheint im Befehl, steht aber nicht in Datenbank, Druckansicht oder Protokoll
  • Werte mit Anführungszeichen werden für die jeweilige Shell korrekt maskiert
  • „Alle Befehle als Skript kopieren" liefert die Schritte in richtiger Reihenfolge
  • Unbekannte Platzhalter bleiben stehen; ersetzte Werte sind HTML-escaped

Verzeichnis (LDAP)

  • Erster Abgleich legt Mitarbeiter an, zweiter aktualisiert sie ohne Duplikate
  • Entfernte oder deaktivierte Konten werden aktiv = false, nie gelöscht
  • {{ou}} wird korrekt aus dem dn abgeleitet
  • Das Bind-Passwort erscheint in keiner API-Antwort und keinem Log
  • Zwei gleichzeitige Abgleiche derselben Quelle: der zweite wird von der Sperre abgewiesen

Oberfläche

  • Am Handy kein horizontales Scrollen — bei 390 px auf allen Hauptseiten geprüft
  • Gestaltung nach Vorgabe: dunkel, ein Akzent, keine Emojis, keine Schatten, keine Verläufe
  • Version mit Git-SHA unten links

Projektorganisation

  • Issues für alle Phasen und MVP-Meilensteine existieren
  • CHANGELOG.md und docs/devlog.md sind gepflegt
  • v0.1.0 ist getaggt, Gitea-Release mit Changelog-Auszug
  • docs/anleitung/ vollständig mit Screenshots und als PDF
  • docs/screenshots/ enthält die Meilenstein-Bilder
  • pnpm lint && pnpm typecheck && pnpm test && pnpm pruefe:doku grün