feat(vorlagen): Versionierung, Unveraenderlichkeit und JSON-Austausch #23

Merged
florian.wilde merged 1 commits from feat/9-vorlagen-versionierung into main 2026-09-25 06:10:02 +00:00
Owner

Schließt #9.

Eine veröffentlichte Vorlagen-Version ist für immer unveränderlich — daran hängt, dass ein archivierter Lauf in zehn Jahren noch genau die Schritte zeigt, mit denen er gestartet wurde.

Die Regel steht zweimal

Im Service, der die verständliche Meldung gibt, und in der Datenbank, die die Garantie gibt. Vier Trigger fangen Schreibzugriffe ab, die nicht durch den Service kommen — Migrationen, psql, der Seed und ab Phase 4 die Connectoren — und versperren den Rückweg VEROEFFENTLICHT → ENTWURF, der alles andere ausgehebelt hätte.

Weil Prisma für handgeschriebene Datenbankobjekte bei jeder künftigen Migration DROP-Anweisungen erzeugt, zählt tests/datenbankregeln.test.ts sie jetzt namentlich auf: Trigger, zusammengesetzte Fremdschlüssel, Trigramm-Indizes, partielle Eindeutigkeitsindizes und alle zwölf Prüfbedingungen. Ein übersehener DROP macht die Suite rot, statt still die Mandantengrenze zu entfernen.

Was dazugekommen ist

  • Service: anlegen, Kopfdaten bearbeiten, Entwurf als tiefe Kopie der letzten veröffentlichten Version, speichern, veröffentlichen, verwerfen, duplizieren, archivieren
  • Höchstens ein Entwurf je Vorlage, durchgesetzt vom partiellen Index. Zwei gleichzeitige Klicks auf „Bearbeiten“ bekommen denselben Entwurf statt eines Fehlers, den niemand versteht
  • Optimistisches Sperren über geaendertAm: wer auf einem überholten Stand speichert, wird abgewiesen statt die Arbeit des anderen spurlos zu ersetzen — Entwürfe werden bewusst nicht protokolliert, sie wäre nicht wiederherstellbar
  • JSON-Export und -Import, Format in docs/vorlagen-format.md. Der Export ist nachsichtig (unbekannte konfig-Schlüssel überleben), der Import streng (eine unbekannte shell wird laut abgewiesen, weil sie über die Maskierung entscheidet)
  • src/lib/validierung.ts als einzige Zod-Quelle mit deutschen Meldungen, per ESLint-Regel erzwungen

Der Review

Drei Blocker, alle an derselben Stelle: den Lesemodellen.

  • Der Suchfilter brachte einen zweiten OR-Schlüssel in dasselbe Objekt; in JavaScript gewinnt der letzte. Ein Buchstabe im Suchfeld gab einem gebundenen Techniker alle Vorlagen aller Kunden
  • versionsHistorie und versionMitAufbau filterten überhaupt nicht — Abschnittstitel, Schritte und PowerShell-Befehle fremder Kunden lagen offen
  • Ursache: zu src/server/queries/vorlagen.ts gab es keinen einzigen Test. Es gibt jetzt tests/vorlagen-sicht.test.ts, und die Kundenbedingung liegt in einem AND-Eintrag, wo kein weiterer Filter sie erreicht

Dazu acht weitere Befunde, alle abgearbeitet — unter anderem ein javascript:-Doku-Link, den das Schema annahm, und ein Export, der bei jeder Beanstandung das ganze konfig verwarf.

Prüfung

pnpm lint && pnpm typecheck && pnpm test && pnpm pruefe:doku grün, 428 Tests (vorher 336).

🤖 Generated with Claude Code

Schließt #9. Eine veröffentlichte Vorlagen-Version ist für immer unveränderlich — daran hängt, dass ein archivierter Lauf in zehn Jahren noch genau die Schritte zeigt, mit denen er gestartet wurde. ## Die Regel steht zweimal Im Service, der die verständliche Meldung gibt, **und** in der Datenbank, die die Garantie gibt. Vier Trigger fangen Schreibzugriffe ab, die nicht durch den Service kommen — Migrationen, `psql`, der Seed und ab Phase 4 die Connectoren — und versperren den Rückweg `VEROEFFENTLICHT → ENTWURF`, der alles andere ausgehebelt hätte. Weil Prisma für handgeschriebene Datenbankobjekte bei **jeder** künftigen Migration `DROP`-Anweisungen erzeugt, zählt `tests/datenbankregeln.test.ts` sie jetzt namentlich auf: Trigger, zusammengesetzte Fremdschlüssel, Trigramm-Indizes, partielle Eindeutigkeitsindizes und alle zwölf Prüfbedingungen. Ein übersehener `DROP` macht die Suite rot, statt still die Mandantengrenze zu entfernen. ## Was dazugekommen ist - Service: anlegen, Kopfdaten bearbeiten, Entwurf als tiefe Kopie der letzten veröffentlichten Version, speichern, veröffentlichen, verwerfen, duplizieren, archivieren - Höchstens ein Entwurf je Vorlage, durchgesetzt vom partiellen Index. Zwei gleichzeitige Klicks auf „Bearbeiten“ bekommen denselben Entwurf statt eines Fehlers, den niemand versteht - Optimistisches Sperren über `geaendertAm`: wer auf einem überholten Stand speichert, wird abgewiesen statt die Arbeit des anderen spurlos zu ersetzen — Entwürfe werden bewusst nicht protokolliert, sie wäre nicht wiederherstellbar - JSON-Export und -Import, Format in `docs/vorlagen-format.md`. Der Export ist nachsichtig (unbekannte `konfig`-Schlüssel überleben), der Import streng (eine unbekannte `shell` wird laut abgewiesen, weil sie über die Maskierung entscheidet) - `src/lib/validierung.ts` als einzige Zod-Quelle mit deutschen Meldungen, per ESLint-Regel erzwungen ## Der Review Drei Blocker, alle an derselben Stelle: den Lesemodellen. - Der Suchfilter brachte einen zweiten `OR`-Schlüssel in dasselbe Objekt; in JavaScript gewinnt der letzte. Ein Buchstabe im Suchfeld gab einem gebundenen Techniker alle Vorlagen aller Kunden - `versionsHistorie` und `versionMitAufbau` filterten überhaupt nicht — Abschnittstitel, Schritte und PowerShell-Befehle fremder Kunden lagen offen - Ursache: zu `src/server/queries/vorlagen.ts` gab es keinen einzigen Test. Es gibt jetzt `tests/vorlagen-sicht.test.ts`, und die Kundenbedingung liegt in einem `AND`-Eintrag, wo kein weiterer Filter sie erreicht Dazu acht weitere Befunde, alle abgearbeitet — unter anderem ein `javascript:`-Doku-Link, den das Schema annahm, und ein Export, der bei jeder Beanstandung das ganze `konfig` verwarf. ## Prüfung `pnpm lint && pnpm typecheck && pnpm test && pnpm pruefe:doku` grün, **428 Tests** (vorher 336). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
florian.wilde added 1 commit 2026-09-25 06:09:48 +00:00
feat(vorlagen): Versionierung, Unveraenderlichkeit und JSON-Austausch
Prüfung / pruefung (push) Canceled after 0s
Prüfung / pruefung (pull_request) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
Prüfung / e2e (pull_request) Canceled after 0s
abacad1cb7
Eine veroeffentlichte Vorlagen-Version ist fuer immer unveraenderlich — daran
haengt, dass ein archivierter Lauf in zehn Jahren noch genau die Schritte zeigt,
mit denen er gestartet wurde. Die Regel steht deshalb zweimal: im Service, der
die verstaendliche Meldung gibt, und in der Datenbank, die die Garantie gibt.
Vier Trigger fangen Schreibzugriffe ab, die nicht durch den Service kommen —
Migrationen, psql, der Seed und ab Phase 4 die Connectoren — und versperren den
Rueckweg nach ENTWURF, der alles andere ausgehebelt haette.

- Service: anlegen, Kopfdaten bearbeiten, Entwurf als tiefe Kopie der letzten
  veroeffentlichten Version, speichern, veroeffentlichen, verwerfen,
  duplizieren, archivieren
- Hoechstens ein Entwurf je Vorlage, durchgesetzt vom partiellen Index; zwei
  gleichzeitige Klicks auf „Bearbeiten“ bekommen denselben Entwurf statt eines
  Fehlers
- Optimistisches Sperren ueber geaendertAm: wer auf einem ueberholten Stand
  speichert, wird abgewiesen statt die Arbeit des anderen spurlos zu ersetzen
- JSON-Export und -Import samt Format-Dokumentation; der Export ist nachsichtig,
  der Import streng
- src/lib/validierung.ts als einzige Zod-Quelle mit deutschen Meldungen, per
  ESLint-Regel erzwungen

Der unabhaengige Review fand drei Blocker, alle an der Mandantengrenze: der
Suchfilter brachte ein zweites OR mit und ueberschrieb die Kundenbedingung,
Historie und Aufbau einer Version filterten gar nicht. Zu queries/vorlagen.ts
gab es keinen Test — jetzt gibt es tests/vorlagen-sicht.test.ts.

428 Tests gruen (vorher 336).

Schliesst #009

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
florian.wilde merged commit d8d5444e9f into main 2026-09-25 06:10:02 +00:00
florian.wilde deleted branch feat/9-vorlagen-versionierung 2026-09-25 06:10:02 +00:00
Sign in to join this conversation.