import "dotenv/config"; import { PrismaClient } from "@prisma/client"; import { PrismaPg } from "@prisma/adapter-pg"; import { hashPassword } from "../src/server/password"; import { PERMISSIONS, type RoleKey } from "../src/server/rbac"; 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). * * Idempotent (upserts) — beliebig oft ausführbar. Passwort: SEED_PASSWORD oder Default. */ const prisma = new PrismaClient({ adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }), }); const DEMO_PASSWORD = process.env.SEED_PASSWORD || "Demo1234!"; async function ensureMember(tenantId: string, u: { email: string; name: string; roles: RoleKey[] }, passwordHash: string) { // Globale Identity (Anmeldung) + Mitgliedschaft (User) im Mandanten. const identity = await prisma.identity.upsert({ where: { email: u.email }, update: {}, create: { email: u.email, passwordHash }, }); const user = await prisma.user.upsert({ where: { tenantId_email: { tenantId, email: u.email } }, update: { identityId: identity.id, name: u.name }, create: { tenantId, identityId: identity.id, email: u.email, name: u.name }, }); const roles = await prisma.role.findMany({ where: { tenantId, key: { in: u.roles } } }); for (const r of roles) { await prisma.userRole.upsert({ where: { userId_roleId: { userId: user.id, roleId: r.id } }, update: {}, create: { userId: user.id, roleId: r.id }, }); } return user; } async function main() { const passwordHash = await hashPassword(DEMO_PASSWORD); // 1. Mandant „demo" (provisioniert Permissions, Rollen, Einstellungen, Module, Admin) const demo = await provisionTenant(prisma, { name: "Musterbau Haustechnik GmbH", slug: "demo", short: "Musterbau", sector: "Sanitär, Heizung, Klima", admin: { email: "admin@demo.example", name: "Anna Admin", password: DEMO_PASSWORD }, }); await prisma.tenantSettings.update({ where: { tenantId: demo.id }, data: { address: "Hafenstraße 12, 20457 Hamburg", phone: "+49 40 123456-0", email: "info@musterbau.example", }, }); const demoUsers: { email: string; name: string; roles: RoleKey[] }[] = [ { email: "admin@demo.example", name: "Anna Admin", roles: ["tenant-admin"] }, { 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"] }, ]; for (const u of demoUsers) await ensureMember(demo.id, u, passwordHash); 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. const demo2 = await provisionTenant(prisma, { name: "Nordlicht Elektro GmbH", slug: "demo2", short: "Nordlicht", sector: "Elektro", admin: { email: "admin2@demo.example", name: "Zoe Zweitadmin", password: DEMO_PASSWORD }, }); console.log(`✔ Mandant "demo2" mit Admin admin2@demo.example`); // 3. Multi-Membership-Fixture: eine Identity in ZWEI Mandanten mit je anderer Rolle. const multi = { email: "multi@demo.example", name: "Mika Multi" }; await ensureMember(demo.id, { ...multi, roles: ["technician"] }, passwordHash); await ensureMember(demo2.id, { ...multi, roles: ["tenant-admin"] }, passwordHash); console.log(`✔ Multi-Membership-Fixture multi@demo.example (demo: Monteur, demo2: Mandantenadministrator)`); // 4. Plattform-Admin (getrennter Store, Login unter /platform/login). await prisma.platformAdmin.upsert({ where: { email: "platform@demo.example" }, update: { name: "Paula Plattform", status: "ACTIVE" }, create: { email: "platform@demo.example", name: "Paula Plattform", passwordHash, status: "ACTIVE" }, }); console.log(`✔ Plattform-Admin platform@demo.example (/platform/login)`); } main() .then(() => prisma.$disconnect()) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); });