Files
Laufzettel/docs/issues/017-seed-sieben-vorlagen.md
florian.wilde 9bd198a531
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
feat(seed): sieben Vorlagen, Beispielbestand und Demo-Kunden (#33)
2026-09-26 03:26:58 +00:00

105 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# #017 M12 – Seed der sieben Vorlagen
**Status:** erledigt
**Meilenstein:** v0.1.0
**Labels:** phase-1, backend
**Geschätzt:** 8 h **Tatsächlich:** 1 h 30 min
## Ziel
Die App ist nach dem Seed fachlich sofort brauchbar: sieben vollständige, fachlich korrekte Vorlagen als veröffentlichte Version 1.
## Aufgaben
- [x] Vorlage 1 „PC Neuinstallation“ (Client), Variablen `os_version`, `join_typ`; Abschnitte Vorbereitung, Installation, Einbindung, Software, Sicherheit, Benutzer, Abschluss
- [x] Vorlage 2 „Mitarbeiter-Onboarding“ (Benutzer), Variablen `konto_typ`, `vorname`, `nachname`, `upn`, `sam`, `mail`, `abteilung`, `ou`, `gruppen`, `eintrittsdatum`, `vorgesetzter`; **beide** Konto-Abschnitte (AD und Entra ID), weil bedingte Abschnitte erst Phase 3 sind
- [x] Vorlage 3 „Mitarbeiter-Offboarding“ (Benutzer), Variablen `austrittsdatum`, `ou_gesperrt`, `postfach_verbleib`, `vertreter`
- [x] Vorlage 4 „Server-Inbetriebnahme Windows-VM“ (Server), Variablen `vmid`, `ip_adresse`, `vlan`, `rolle`, `os_version`
- [x] Vorlage 5 „Firewall-Rollout OPNsense“ (Netzwerk), Variablen `wan_typ`, `lan_netz`, `vpn_typ`
- [x] Vorlage 6 „Monatlicher Patchday“ (Wartung), Variable `monat`
- [x] Vorlage 7 „Backup-Restore-Test“ (Wartung), Variablen `system`, `restore_typ`
- [x] Alle Schritte wortgetreu nach Auftrag mit Typ, Pflichtkennzeichen und `konfig`; die im Auftrag genannten Hilfetexte übernehmen, die übrigen fachlich korrekt und kurz ergänzen
- [x] 5 Mitarbeiter, darunter „Maria Huber“, `m.huber@firma.example`, `sam` `mhuber`, Abteilung Buchhaltung, Vorgesetzte „Petra Klein“ — **teilweise:** Petra Klein ist angelegt, die Zuordnung selbst lässt sich nicht speichern (siehe Ergebnis)
- [x] 3 Abteilungen: Buchhaltung → `OU=Buchhaltung,OU=Benutzer,DC=firma,DC=local` mit Gruppen `G-Buchhaltung, G-Alle`; Vertrieb; IT
- [x] Eine **deaktivierte** `Verzeichnisquelle` als Beispielkonfiguration
- [x] Geräte `PC-001` (PC, `LZ-7K3F9Q`, Besitzerin Maria Huber) und `NB-001` (Notebook, `LZ-M2XH4T`), dazu 5 unregistrierte Tags
- [x] `GeraetetypVorlage`: PC und NOTEBOOK → „PC Neuinstallation“; SERVER → „Server-Inbetriebnahme Windows-VM“ und „Backup-Restore-Test“; FIREWALL → „Firewall-Rollout OPNsense“
- [x] `SEED_MODE=DIENSTLEISTUNG` (Alias `SERVICE`) erzeugt stattdessen „Musterfirma GmbH“ (`MUS`) und „Bäckerei Reiter“ (`REI`) mit je einer Person, einer Abteilung und einem Gerät
- [x] Alles idempotent über stabile Schlüssel — **nicht** über `upsert`, sondern nachsehen und nur anlegen (siehe Ergebnis)
## Akzeptanzkriterien
- [x] `pnpm db:seed` zweimal hintereinander: keine Fehler, keine Duplikate, keine geänderten Zeilen
- [x] Alle sieben Vorlagen liegen als `VEROEFFENTLICHT`, Version 1 vor
- [x] Im Onboarding-Lauf steht im Schritt „Konto anlegen“ der vollständige `New-ADUser`-Befehl mit Name, UPN, `-Path "OU=Buchhaltung,OU=Benutzer,DC=firma,DC=local"` und der Gruppen-Befehl mit `G-Buchhaltung, G-Alle`
- [x] `SEED_MODE=SERVICE` erzeugt `MUS-PC-001` gemäß Hostname-Regel `{kundenkuerzel}-PC-{nnn}`
- [x] Die Beispiel-Verzeichnisquelle ist deaktiviert und löst keinen Abgleich aus
- [x] Kein Seed-Datensatz enthält ein Klartext-Passwort außer dem Admin-Passwort aus der Umgebung, und das nur als argon2-Hash
## Ergebnis
Erledigt am 2026-09-26. **1129 Tests** (vorher 1098), Screenshots in `docs/screenshots/m12/`.
Die sieben Vorlagen liegen als JSON im [Austauschformat](../vorlagen-format.md) unter
`prisma/seed-daten/vorlagen/` — 36 Abschnitte, 155 Schritte, 28 Variablen, jeder Schritt mit
Hilfetext. Ein maschineller Abgleich gegen den Auftragstext (Titel, Pflichtkennzeichen, Typ,
Reihenfolge, Position für Position) meldet **eine** Abweichung, und die ist eine Auslegung: „Zeitzone
korrekt, [COMMAND] Zeitsynchronisation prüfen" steht im Auftrag als *ein* Aufzählungspunkt mit der
Typangabe mitten in der Zeile und wurde ein Befehlsschritt statt zweier Schritte.
Zwei Punkte weichen bewusst vom Wortlaut der Aufgabenliste ab:
- **Idempotenz ohne `upsert`.** Ein `upsert` mit gefülltem `update` schriebe bei jedem Lauf zurück,
was im Betrieb geändert wurde. Der Seed sieht stattdessen nach und legt nur an, was fehlt.
- **Die Vorgesetzte lässt sich nicht speichern.** Petra Klein ist als Person angelegt, die Zuordnung
„Maria Huber → Petra Klein" aber nicht: `vorgesetzterExterneId` zeigt auf die `externeId`
derselben Verzeichnisquelle, und eine von Hand angelegte Person hat beides nicht — beide Lesepfade
(`src/server/queries/mitarbeiter.ts`, `src/server/services/platzhalter.ts`) steigen ohne `quelleId`
aus. Einen Wert zu schreiben, den niemand liest, wäre schlechter als die Lücke. Sie gehört in ein
eigenes Issue.
### Der unabhängige Review
Zwei Blocker, neun Befunde, sieben Anmerkungen — die wichtigsten:
- **Blocker: zwei verschiedene Passwörter auf einer Seite.** Die Hilfetexte des Onboardings trugen
`{{generiertes_passwort}}`, und `src/server/queries/laeufe.ts` löste Hilfetexte **ohne** das
Passwort des Seitenaufbaus auf — im Befehl stand A, im Hilfetext daneben B. Wer B in den
Passwortmanager legt, sperrt den neuen Mitarbeiter aus. Genau davor warnt
`src/lib/platzhalter-werte.ts` in Regel 4 seiner eigenen Kopfdokumentation. Behoben an beiden
Enden: Titel und Hilfetext bekommen jetzt dasselbe Passwort wie der Befehl, und die Hilfetexte
nennen es gar nicht mehr.
- **Blocker: der Seed vergab einen verbrannten Tag-Code neu.** Er fragte nur nach dem Gerät, nicht
nach dem Vergabebuch. Wer den Beispiel-PC endgültig gelöscht hatte, bekam beim nächsten Lauf
denselben Code auf einem neuen Gerät — und der alte Aufkleber im Regal zeigte auf ein fremdes
Objekt. Jetzt werden beide Bücher gefragt, wie im Gerätedienst.
- **„Stattdessen" hieß „zusätzlich".** Im Modus DIENSTLEISTUNG hing der Beispielbestand weiter an
der eigenen Organisation, `LZ-7K3F9Q` führte also auf `PC-001` statt auf `MUS-PC-001` — das
Abnahmekriterium des Auftrags wäre in **keinem** Modus erfüllt gewesen. Jetzt bekommt die
Musterfirma den vollen Bestand, die Bäckerei den kleinen, die eigene Organisation keinen.
- **Der Seed schrieb in fremde Kundendaten.** Die Demo-Kunden wurden nur am Kürzel erkannt: ein
echter Kunde „Muster und Söhne KG" mit dem Kürzel MUS bekam eine erfundene Person, eine erfundene
Ziel-OU und ein Gerät — und die Ausgabe sagte „vorhanden".
- **Der Seed stürzte ab**, wenn eine Vorlage gleichen Namens nur als Entwurf existierte — also genau
dann, wenn jemand eine der sieben Dateien eingespielt und noch nicht veröffentlicht hatte.
- **Zwei falsche Zusagen in Hilfetexten:** „vorbelegt aus der Abteilung" (nichts wird vorbelegt; die
leeren Felder fallen auf die Abteilung zurück) und „das Passwort beendet die bestehenden
Anmeldungen" (ein Reset im AD verhindert nur die erneute Anmeldung).
- **Keine Namensregeln im Seed.** „Namen aus den Regeln vorschlagen" antwortete nach einem frischen
Seed mit „keine Namensregeln hinterlegt" — das MVP-Kriterium war nicht vorführbar. Jetzt legt der
Seed die Regeln an, die zu seinen eigenen Daten passen, und die Sperr-OU fürs Offboarding dazu.
- **Ein Test, der nicht scheitern konnte** (schon vor dem Review selbst gefunden und behoben): die
Suche nach Klartextpasswörtern lief gegen `JSON.stringify`, wo vor jedem Anführungszeichen ein
Backslash steht.
Die drei Skripte `pnpm beispiel:vorlage`, `beispiel:stammdaten` und `beispiel:lauf` tragen im Kopf
„Mit #017 wird das Skript gelöscht". Sie bleiben, und der Kopf ist berichtigt: der Seed richtet eine
**Installation** ein, die Skripte stellen her, was **Screenshots und Abläufe** brauchen — einen
offenen Entwurf, einen halb abgearbeiteten Lauf, eine Person aus dem Verzeichnis. Das in den Seed zu
legen hieße, jeder frischen Installation Demo-Läufe mitzugeben, die dort niemand bestellt hat. Die
Zusammenführung dieser Fixtures steht in [#018](018-e2e-anleitung-pdf.md).
Offen geblieben und bewusst nicht behoben: wird eine Seed-Vorlage **umbenannt**, legt der nächste
Lauf sie erneut an — der Seed kennt sie nur an ihrem Namen. Ein stabiler Schlüssel dafür gehört ins
Austauschformat und damit in ein eigenes Issue.