fix: Reviewbefunde aus der Durchsicht von Phase 2 (#036, #027)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

Acht Meilensteine lagen ohne fremden Blick auf main. Ein Review mit eigener
Datenbank, Gegenproben und vollem Suitenlauf hat sie gegen die
Akzeptanzkriterien und gegen CLAUDE.md geprueft.

Die Kernregeln halten: fuenf von fuenf Gegenproben gegen Versionierung,
Mandantengrenze, Abschlussregel und Selbstauskunft wurden rot. Alle Befunde
lagen am Rand — und die drei wertvollsten waren Gegenproben, die gruen blieben.

Schwer:

- Der Link in der Mail "Verzeichnis-Abgleich fehlgeschlagen" war ein 404
  (/verwaltung/verzeichnis statt /admin/verzeichnis). Die eine Meldung, die an
  alle Administratoren geht, im Moment eines Ausfalls. Ein Test prueft jetzt
  jeden Meldungspfad gegen die vorhandenen Routen.
- Der Export eines Entwurfs mit Baustein lieferte einen leeren Abschnitt unter
  dem Platzhalter "wird ersetzt" — der Zweck des Formats ist, eine Vorlage in
  eine zweite Installation zu bringen. Bausteine werden jetzt aufgeloest.

Mittel:

- Der Anhang-Handler hatte keinen Test; die ganze Rechtepruefung liess sich
  durch einen hartcodierten ADMIN ersetzen, Suite gruen. Es ist die einzige
  Stelle, die rohe Dateibytes ausliefert. tests/anhang-route.test.ts faehrt ihn
  jetzt echt, acht Pruefungen.
- /api/scim in der Proxy-Allowlist stand in keinem Test. OEFFENTLICH ist
  exportiert, der Test vergleicht beide Richtungen: eine Liste, die nur in einer
  Richtung geprueft wird, laeuft dem Code hinterher.
- Ein offener Ereignisstrom ueberlebte Abmelden, Deaktivieren und
  Sitzungswiderruf. Der Herzschlag prueft die Sitzung jetzt nach. Dass es kein
  Test zeigte, lag an einer Attrappe `sitzung: {}` — eine Attrappe ohne die Form
  der Wirklichkeit prueft etwas anderes als die Wirklichkeit.
- README kannte MITARBEITER nicht und behauptete, unbekannte Benutzer wuerden
  angelegt. Wer auf v0.2.0 hebt und nur das README liest, haette genau diese
  Leute ausgesperrt.
- sicherung.md nannte einen Anhaenge-Pfad, den es nirgends gibt — als
  Rueckfallwert in einem Skript mit rm -rf. Jetzt bricht es ab statt zu raten.
- Attributnamen wurden nur in der Server Action geprueft, waehrend der
  Graph-Leser sich im Kommentar darauf berief.

Dazu #027: die Ende-zu-Ende-Ablaeufe raeumen jetzt zentral auf, vor und nach
dem Lauf, und ein struktureller Test bewacht es. Beim ersten echten Lauf seit
dem 26. September waren sieben Ablaeufe rot, vier Ursachen, keine ein
Produktfehler — unbemerkt, weil pnpm test:e2e in keinem Tor steht. Das ist jetzt
#038 und keine Fussnote.

Ein Befund des Reviews war falsch (der Zustands-Handler habe keinen Test; er hat
acht direkte Aufrufe). Nachgeprueft, bevor etwas geaendert wurde.

1454 Vitest-Tests (vorher 1432), 113 E2E-Ablaeufe gruen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-10-11 01:32:09 +02:00
co-authored by Claude Opus 5
parent fcd67018b8
commit 80d97467da
37 changed files with 1752 additions and 59 deletions
+41
View File
@@ -1,7 +1,9 @@
import { chromium } from "@playwright/test";
import "dotenv/config";
import { prisma } from "@/lib/db";
import { ABTEILUNGEN } from "@/../prisma/seed-daten/stammdaten";
import { anmelden, SEED_GERAET, SEED_TAG, SEED_VORLAGE } from "./helfer";
import { e2eAufraeumenMitBericht } from "./aufraeumen";
/**
* Was vor dem ersten Ablauf stimmen muss (#018).
@@ -23,6 +25,14 @@ function fehlen(was: string, abhilfe: string): never {
}
export default async function vorbereiten(): Promise<void> {
/*
* **Zuerst aufraeumen, dann pruefen** (#027). Was hier noch steht, ist der
* Rueckstand eines abgebrochenen Durchgangs: `globalTeardown` und die
* `afterAll`-Bloecke laufen bei einem Testfehler, aber nicht bei `Strg+C`.
* Ein Vorlauf laesst sich nicht ueberspringen — das ist der Unterschied.
*/
await e2eAufraeumenMitBericht("vor");
if (!process.env["SEED_ADMIN_EMAIL"] || !process.env["SEED_ADMIN_PASSWORD"]) {
fehlen(
"SEED_ADMIN_EMAIL oder SEED_ADMIN_PASSWORD fehlt.",
@@ -59,6 +69,37 @@ export default async function vorbereiten(): Promise<void> {
fehlen(`Das Beispielgerät ${SEED_GERAET} (${SEED_TAG}) fehlt.`, "pnpm db:seed laufen lassen.");
}
/*
* 2c. Stehen die **Werte** des Seed-Bestands noch, nicht nur die Zeilen?
*
* Der Onboarding-Ablauf prueft den `New-ADUser`-Befehl **zeichengenau**, und
* darin steckt die Ziel-OU der Abteilung. In der Entwicklungsdatenbank stand
* an „Buchhaltung“ `DC=firma,DC=de` statt `DC=firma,DC=local` — von Hand
* geaendert oder aus einer aelteren Seed-Fassung. Der Seed setzt bestehende
* Abteilungen absichtlich **nicht** zurueck (gepflegte Daten sollen bleiben),
* also blieb die Abweichung stehen.
*
* Der Ablauf scheiterte daran mit „expected … received …“ — einer Meldung, die
* nach einem Fehler im Befehlsbau aussieht und keiner war. Hier faellt es
* vorher auf, und die Meldung sagt, was zu tun ist (Reviewbefund zu #029).
*/
for (const vorgabe of ABTEILUNGEN) {
const abteilung = await prisma.abteilung.findFirst({
where: { name: vorgabe.name },
select: { zielOu: true, standardGruppen: true },
});
if (!abteilung) continue;
if (abteilung.zielOu !== vorgabe.zielOu) {
fehlen(
`Die Abteilung „${vorgabe.name}“ hat eine abweichende Ziel-OU: ` +
`„${abteilung.zielOu}“ statt „${vorgabe.zielOu}“.`,
"Der Onboarding-Ablauf prüft den erzeugten Befehl zeichengenau. Entweder die Ziel-OU " +
"unter Admin → Abteilungen zurückstellen, oder gegen eine frische Datenbank fahren: " +
"pnpm db:seed:reset.",
);
}
}
/*
* 2b. In welchem Betriebsmodus laeuft die Installation?
*