feat(seed): sieben Vorlagen, Beispielbestand und Demo-Kunden
Die sieben Ablaeufe des Hauses liegen nach dem Seed als veroeffentlichte Version 1 bereit: 36 Abschnitte, 155 Schritte, 28 Variablen, jeder Schritt mit Hilfetext. Sie stehen als JSON im Austauschformat unter prisma/seed-daten/vorlagen/ und werden beim Einrichten gegen dasselbe Schema geprueft wie ein Import. Der Seed richtet ein, er raeumt nicht auf: jede Zeile hat einen sprechenden Schluessel, und was es schon gibt, bleibt unberuehrt. Erst Entwurf, dann veroeffentlichen - die Trigger aus #010 lassen keinen anderen Weg zu. Im Modus DIENSTLEISTUNG haengt der Beispielbestand an der Musterfirma, LZ-7K3F9Q fuehrt also auf MUS-PC-001. Dazu zwei Zusagen eingeloest, die niemand deckte: {{ou_gesperrt}} kommt jetzt wirklich aus den Einstellungen, und Titel und Hilfetext eines Laufs bekommen dasselbe generierte Passwort wie der Befehl daneben - vorher stand im Befehl A und im Hilfetext B. Closes #17 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ae290345b7
commit
5c81a62cfd
@@ -27,10 +27,33 @@ async function anmelden(seite: Page) {
|
||||
await Promise.all([seite.waitForURL("**/"), seite.click('button[type="submit"]')]);
|
||||
}
|
||||
|
||||
/** Die Vorlage aus `pnpm beispiel:vorlage` – diese Ablaeufe arbeiten mit ihr. */
|
||||
const BEISPIEL_VORLAGE = "PC-Neuinstallation (Beispiel)";
|
||||
|
||||
/** Legt einen Lauf an und gibt seine Adresse zurueck. */
|
||||
async function laufStarten(seite: Page, titel: string): Promise<string> {
|
||||
await seite.goto("/laeufe/starten");
|
||||
await seite.selectOption('select[name="vorlagenVersionId"]', { index: 1 });
|
||||
|
||||
/*
|
||||
* Die Vorlage wird **am Namen** gewaehlt und nicht ueber `index: 1`. Seit dem
|
||||
* Seed der sieben Vorlagen (#017) steht dort an erster Stelle, was die
|
||||
* Sortierung gerade nach vorn stellt — bei einer frisch eingerichteten
|
||||
* Installation etwa „Mitarbeiter-Offboarding“ mit Pflichtangaben, die dieser
|
||||
* Helfer nicht kennt. Der Ablauf lief dann in den Zeitablauf, und die Meldung
|
||||
* sagte nichts ueber die Ursache.
|
||||
*/
|
||||
const vorlagen = await seite
|
||||
.locator('select[name="vorlagenVersionId"] option')
|
||||
.evaluateAll((liste) =>
|
||||
liste
|
||||
.filter((option): option is HTMLOptionElement => option instanceof HTMLOptionElement)
|
||||
.map((option) => ({ wert: option.value, text: option.textContent })),
|
||||
);
|
||||
const beispiel = vorlagen.find((eintrag) => (eintrag.text ?? "").includes(BEISPIEL_VORLAGE));
|
||||
if (!beispiel) {
|
||||
throw new Error(`Die Vorlage „${BEISPIEL_VORLAGE}“ fehlt. Erst „pnpm beispiel:vorlage“ laufen lassen.`);
|
||||
}
|
||||
await seite.selectOption('select[name="vorlagenVersionId"]', beispiel.wert);
|
||||
await seite.selectOption('select[name="geraetId"]', { index: 1 });
|
||||
await seite.locator("details summary", { hasText: "Titel, Ticket" }).click();
|
||||
await seite.getByLabel("Titel", { exact: true }).fill(titel);
|
||||
@@ -42,6 +65,13 @@ async function laufStarten(seite: Page, titel: string): Promise<string> {
|
||||
for (const feld of await seite.locator('fieldset input[type="number"]').all()) {
|
||||
await feld.fill("16");
|
||||
}
|
||||
for (const feld of await seite.locator('fieldset input[type="date"]').all()) {
|
||||
await feld.fill("2026-10-01");
|
||||
}
|
||||
for (const feld of await seite.locator('fieldset input[type="text"]').all()) {
|
||||
// Nur leere Felder: die Namensvorschlaege sollen stehen bleiben.
|
||||
if ((await feld.inputValue()) === "") await feld.fill("E2E");
|
||||
}
|
||||
|
||||
await seite.getByRole("button", { name: "Lauf anlegen" }).click();
|
||||
await seite.waitForURL(/\/laeufe\/(?!starten)[^/]+$/, { timeout: 30_000 });
|
||||
|
||||
Reference in New Issue
Block a user