feat(vorlagen): bedingte Abschnitte und Schritte (#039)
Ein Abschnitt oder ein einzelner Schritt erscheint nur, wenn seine Bedingung zutrifft — abhaengig von einer Variable des Laufs oder vom Zustand eines anderen Schritts. Der echte Fall steht im Seed: "Mitarbeiter-Onboarding" traegt beide Konto-Abschnitte, fuenf AD-Schritte und vier fuer Entra ID, und `konto_typ` sagt beim Start, welcher gilt. Bisher klickte ein Techniker die anderen neun bei jedem Onboarding weg. Entscheidungen, alle im Issue begruendet: - Laufend ausgewertet, nicht beim Start festgeschrieben. Fuer die Abteilungsabschnitte (#031) ist Festschreiben richtig; fuer Bedingungen nicht — die Antwort auf "ist Pruefen fehlgeschlagen?" entsteht erst waehrend der Arbeit. Ein struktureller Test prueft, dass alle drei Schichten (Abschlussregel, Abarbeitung, Druck) die Auswertung rufen. - Nicht entscheidbar heisst: gilt. Ein Lauf ohne konto_typ zeigt beide Abschnitte — genau wie vorher. Ein Abschnitt zu viel ist sichtbar und korrigierbar, ein fehlender faellt niemandem auf. - OFFEN ist eine Antwort, keine Luecke: waere es unentscheidbar, waere ein bedingter Abschnitt von Anfang an sichtbar. - Eine Bedingung, kein Ausdrucksbaum. Kein und, kein oder. - Verwiesen wird ueber Titel-Pfade, nicht ueber Kennungen: vier Wege schreiben eine Struktur neu und geben neue Kennungen. Zwei stille Datenverluste gefunden, der zweite aelter als dieser Meilenstein: - Der Import verwarf `nurFuerAbteilungen`. Der Export schreibt es seit #031, das Schema nimmt es an, der Import setzte es nicht — eine exportierte Vorlage verlor ihre Abteilungsabschnitte und galt dort fuer alle. - Die tiefe Kopie verwarf es ebenfalls, womit jedes "Bearbeiten" einer Vorlage alle Einschraenkungen verlor. Ursache war ein von Hand getippter Zwischentyp, der weniger Felder nannte als die Abfrage liefert; jetzt aus Prisma abgeleitet, beide Kopierwege teilen eine Stelle, und ein Test vergleicht Kopie und Original Feld fuer Feld. Gefunden hat beides die Klickprobe am gebauten Stand, nicht die Suite: im Editor stand "Bedingung gesetzt", nach "Bearbeiten" war sie weg. Dreizehn Gegenproben liefen, alle wurden rot — und der teuerste Befund lag ausserhalb von allen. 1499 Vitest-Tests (vorher 1457), 115 E2E-Ablaeufe gruen. Closes #39 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2f247b3617
commit
a2330ef682
+40
-6
@@ -150,13 +150,47 @@ describe("Die sieben Vorlagen", () => {
|
||||
expect(gruppen).toContain('-Members "{{sam}}"');
|
||||
});
|
||||
|
||||
it("enthaelt beide Konto-Abschnitte des Onboardings", () => {
|
||||
// Bedingte Abschnitte kommen erst in Phase 3; bis dahin wird der nicht
|
||||
// zutreffende als Ganzes auf „nicht zutreffend“ gesetzt.
|
||||
it("enthaelt beide Konto-Abschnitte des Onboardings – jeden mit seiner Bedingung", () => {
|
||||
/*
|
||||
* **Der Fall, für den #039 gebaut wurde.** Beide Abschnitte bleiben in der
|
||||
* Vorlage — sie schließen sich über `konto_typ` gegenseitig aus. Bis Phase 3
|
||||
* standen sie ohne Bedingung drin, und ein Techniker setzte den nicht
|
||||
* zutreffenden von Hand auf „nicht zutreffend“: neun Schritte bei jedem
|
||||
* Onboarding.
|
||||
*
|
||||
* Geprüft wird hier die **Vorlage**; dass die Auswertung greift, steht in
|
||||
* `tests/bedingte-laeufe.test.ts`.
|
||||
*/
|
||||
const onboarding = VORLAGEN.find((eintrag) => eintrag.dokument.name === "Mitarbeiter-Onboarding");
|
||||
const titel = (onboarding?.dokument.struktur.abschnitte ?? []).map((abschnitt) => abschnitt.titel);
|
||||
expect(titel).toContain("Konto anlegen (Active Directory)");
|
||||
expect(titel).toContain("Konto anlegen (Entra ID)");
|
||||
const abschnitte = onboarding?.dokument.struktur.abschnitte ?? [];
|
||||
const nach = (titel: string) => abschnitte.find((abschnitt) => abschnitt.titel === titel);
|
||||
|
||||
const optionen =
|
||||
onboarding?.dokument.struktur.variablen.find((variable) => variable.schluessel === "konto_typ")
|
||||
?.optionen ?? [];
|
||||
|
||||
for (const [titel, wert] of [
|
||||
["Konto anlegen (Active Directory)", "Active Directory"],
|
||||
["Konto anlegen (Entra ID)", "Entra ID"],
|
||||
] as const) {
|
||||
const abschnitt = nach(titel);
|
||||
expect(abschnitt, titel).toBeDefined();
|
||||
expect(abschnitt?.bedingung, titel).toEqual({
|
||||
art: "variable",
|
||||
schluessel: "konto_typ",
|
||||
operator: "ist",
|
||||
wert,
|
||||
});
|
||||
/*
|
||||
* **Der Wert muss eine der Optionen sein.** Ein Tippfehler hier wäre
|
||||
* stillschweigend: die Bedingung träfe nie zu, der Abschnitt erschiene
|
||||
* nie, und die Hälfte der Checkliste fehlte — ohne Fehlermeldung.
|
||||
*/
|
||||
expect(optionen, `${titel}: „${wert}“ ist keine Option von konto_typ`).toContain(wert);
|
||||
}
|
||||
|
||||
// Und der gemeinsame Abschnitt hat keine: er gilt immer.
|
||||
expect(nach("Konto, gemeinsam")?.bedingung).toBeUndefined();
|
||||
});
|
||||
|
||||
it("speichert nirgends ein Passwort im Klartext", () => {
|
||||
|
||||
Reference in New Issue
Block a user