L10a Qualität & Abnahmetests: Demo-Seed (Teams, Kunden, Objekte, 20 Aufträge, Berichte, Notdienst, demo2)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 17:58:22 +02:00
co-authored by Claude Opus 5
parent a7d4b02a13
commit 1a75c28bb4
2 changed files with 446 additions and 3 deletions
+36 -3
View File
@@ -8,7 +8,9 @@ import { provisionTenant } from "../src/server/provision";
/**
* Craftvia-Demo-Seed (Fundament): Plattform-Admin + Mandant `demo` mit je einem Nutzer
* pro Standardrolle + zweiter Mandant `demo2` (Isolations-/Tenant-Switch-Tests) +
* Multi-Membership-Fixture. KEINE Fachdaten (Kunden/Aufträge liefern die Module).
* Multi-Membership-Fixture. Fachliche Demo-Daten (Teams, Kunden, Objekte, Aufträge, Berichte,
* Notdienst) kommen aus scripts/lib/demo-seed.ts — nur mit SEED_DEMO=true oder außerhalb von
* Production (SEED_DEMO=false schaltet sie ab).
*
* Idempotent (upserts) — beliebig oft ausführbar. Passwort: SEED_PASSWORD oder Default.
*/
@@ -66,8 +68,13 @@ async function main() {
{ email: "backoffice@demo.example", name: "Bernd Backoffice", roles: ["backoffice"] },
{ email: "teamleiter@demo.example", name: "Tina Teamleiter", roles: ["team-lead"] },
{ email: "monteur@demo.example", name: "Max Monteur", roles: ["technician"] },
// L10a Demo-Teams: Team Nord (Tina + Max + Nora), Team Süd (Sven + Paul)
{ email: "teamleiter2@demo.example", name: "Sven Südfeld", roles: ["team-lead"] },
{ email: "monteur2@demo.example", name: "Nora Nordmann", roles: ["technician"] },
{ email: "monteur3@demo.example", name: "Paul Petersen", roles: ["technician"] },
];
for (const u of demoUsers) await ensureMember(demo.id, u, passwordHash);
const members: Record<string, string> = {};
for (const u of demoUsers) members[u.email] = (await ensureMember(demo.id, u, passwordHash)).id;
console.log(`✔ Mandant "demo" (${PERMISSIONS.length} Permissions) mit ${demoUsers.length} Nutzern (Passwort: ${DEMO_PASSWORD})`);
// 2. Zweiter Mandant „demo2" — Grundlage für Isolations- und Tenant-Switch-Tests.
@@ -93,10 +100,36 @@ async function main() {
create: { email: "platform@demo.example", name: "Paula Plattform", passwordHash, status: "ACTIVE" },
});
console.log(`✔ Plattform-Admin platform@demo.example (/platform/login)`);
// 5. L10a: fachliche Demo-Daten (Teams, Kunden, Objekte, 20 Aufträge, Berichte, Notdienst).
// Nur mit SEED_DEMO=true oder außerhalb von Production; SEED_DEMO=false schaltet sie ab.
const demoData = process.env.SEED_DEMO === "true" || (process.env.NODE_ENV !== "production" && process.env.SEED_DEMO !== "false");
if (demoData) {
const { seedDemoTenant, seedDemo2Tenant, closeDemoSeed } = await import("../scripts/lib/demo-seed");
const res = await seedDemoTenant(demo.id, {
admin: members["admin@demo.example"],
backoffice: members["backoffice@demo.example"],
lead: members["teamleiter@demo.example"],
lead2: members["teamleiter2@demo.example"],
tech: members["monteur@demo.example"],
tech2: members["monteur2@demo.example"],
tech3: members["monteur3@demo.example"],
});
const admin2 = await prisma.user.findUniqueOrThrow({ where: { tenantId_email: { tenantId: demo2.id, email: "admin2@demo.example" } } });
await seedDemo2Tenant(demo2.id, admin2.id);
await closeDemoSeed();
console.log(`✔ Demo-Fachdaten: ${res.orders} Demo-Aufträge in "demo" (${res.created} neu angelegt), 1 Auftrag in "demo2"`);
} else {
console.log("• Demo-Fachdaten übersprungen (SEED_DEMO=false bzw. Production ohne SEED_DEMO=true)");
}
}
main()
.then(() => prisma.$disconnect())
.then(async () => {
await prisma.$disconnect();
// Services may leave queue/redis handles open (events, image jobs) — end the seed explicitly.
process.exit(0);
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();