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>
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { z } from "@/lib/validierung";
|
|
import { AustauschSchema, StrukturSchema } from "@/lib/vorlagen-format";
|
|
|
|
/**
|
|
* Zod ist in src/lib/validierung.ts auf Deutsch eingestellt (#009).
|
|
*
|
|
* Ohne diese Einstellung landen englische Standardsaetze ueber die Server
|
|
* Actions in der Oberflaeche — und zwar genau dort, wo niemand an eine eigene
|
|
* Meldung gedacht hat.
|
|
*/
|
|
describe("Deutsche Meldungen", () => {
|
|
it("meldet einen falschen Typ auf Deutsch", () => {
|
|
const ergebnis = z.object({ name: z.string() }).safeParse({ name: 42 });
|
|
expect(ergebnis.error?.issues[0]?.message).toMatch(/Ungültige Eingabe/);
|
|
});
|
|
|
|
it("meldet ein fehlendes Pflichtfeld auf Deutsch", () => {
|
|
const ergebnis = z.object({ name: z.string() }).safeParse({});
|
|
expect(ergebnis.error?.issues[0]?.message).not.toMatch(/Invalid input/);
|
|
});
|
|
|
|
it("laesst eigene Meldungen unangetastet", () => {
|
|
const ergebnis = StrukturSchema.safeParse({
|
|
abschnitte: [{ titel: "A", schritte: [{ titel: "" }] }],
|
|
});
|
|
expect(ergebnis.error?.issues[0]?.message).toBe("Ein Schritt braucht einen Titel.");
|
|
});
|
|
|
|
it("meldet ein unbekanntes Austauschformat auf Deutsch", () => {
|
|
const ergebnis = AustauschSchema.safeParse({ format: 99, name: "X", struktur: {} });
|
|
expect(ergebnis.error?.issues[0]?.message).toMatch(/Unbekanntes Format/);
|
|
});
|
|
});
|