import { PrismaClient } from '@prisma/client'; import bcrypt from 'bcryptjs'; const prisma = new PrismaClient(); async function main() { console.log('Seeding database...'); // ==================== PERMISSIONS ==================== // Ressourcen mit ihren erlaubten Aktionen const resourcePermissions: Record = { // Haupt-Ressourcen (CRUD) customers: ['create', 'read', 'update', 'delete'], contracts: ['create', 'read', 'update', 'delete'], users: ['create', 'read', 'update', 'delete'], platforms: ['create', 'read', 'update', 'delete'], providers: ['create', 'read', 'update', 'delete'], tariffs: ['create', 'read', 'update', 'delete'], // Konfiguration (CRUD) 'cancellation-periods': ['create', 'read', 'update', 'delete'], 'contract-durations': ['create', 'read', 'update', 'delete'], 'contract-categories': ['create', 'read', 'update', 'delete'], 'email-providers': ['create', 'read', 'update', 'delete'], // Einstellungen (nur lesen/ändern) settings: ['read', 'update'], // Spezial-Permissions developer: ['access'], emails: ['delete'], }; const permissions: { resource: string; action: string }[] = []; for (const [resource, actions] of Object.entries(resourcePermissions)) { for (const action of actions) { permissions.push({ resource, action }); } } for (const perm of permissions) { await prisma.permission.upsert({ where: { resource_action: perm }, update: {}, create: perm, }); } console.log(`Permissions created (${permissions.length} total)`); // Get all permissions const allPermissions = await prisma.permission.findMany(); const customerReadPerm = allPermissions.find( (p) => p.resource === 'customers' && p.action === 'read' ); const contractReadPerm = allPermissions.find( (p) => p.resource === 'contracts' && p.action === 'read' ); const platformReadPerm = allPermissions.find( (p) => p.resource === 'platforms' && p.action === 'read' ); const providerReadPerm = allPermissions.find( (p) => p.resource === 'providers' && p.action === 'read' ); // Create roles // Admin - all permissions EXCEPT developer:access (that's controlled separately) const adminPermissions = allPermissions.filter( (p) => !(p.resource === 'developer' && p.action === 'access') ); const adminRole = await prisma.role.upsert({ where: { name: 'Admin' }, update: {}, create: { name: 'Admin', description: 'Voller Zugriff auf alle Funktionen', permissions: { create: adminPermissions.map((p) => ({ permissionId: p.id })), }, }, }); // Developer - ALL permissions including developer:access const developerRole = await prisma.role.upsert({ where: { name: 'Developer' }, update: {}, create: { name: 'Developer', description: 'Voller Zugriff inkl. Entwickler-Tools', permissions: { create: allPermissions.map((p) => ({ permissionId: p.id })), }, }, }); // Employee - full access to customers, contracts, read access to lookup tables const employeePermIds = allPermissions .filter( (p) => p.resource === 'customers' || p.resource === 'contracts' || // Read-only Zugriff auf Stammdaten und Konfiguration (p.action === 'read' && [ 'platforms', 'providers', 'tariffs', 'cancellation-periods', 'contract-durations', 'contract-categories', ].includes(p.resource)) ) .map((p) => p.id); const employeeRole = await prisma.role.upsert({ where: { name: 'Mitarbeiter' }, update: {}, create: { name: 'Mitarbeiter', description: 'Kann Kunden und Verträge verwalten', permissions: { create: employeePermIds.map((id) => ({ permissionId: id })), }, }, }); // Read-only employee - read access to main entities and lookup tables const readOnlyResources = [ 'customers', 'contracts', 'platforms', 'providers', 'tariffs', 'cancellation-periods', 'contract-durations', 'contract-categories', ]; const readOnlyPermIds = allPermissions .filter((p) => p.action === 'read' && readOnlyResources.includes(p.resource)) .map((p) => p.id); const readOnlyRole = await prisma.role.upsert({ where: { name: 'Mitarbeiter (Nur-Lesen)' }, update: {}, create: { name: 'Mitarbeiter (Nur-Lesen)', description: 'Kann nur lesen, keine Änderungen', permissions: { create: readOnlyPermIds.map((id) => ({ permissionId: id })), }, }, }); // Customer role - read own data only (handled in middleware) const customerRole = await prisma.role.upsert({ where: { name: 'Kunde' }, update: {}, create: { name: 'Kunde', description: 'Kann nur eigene Daten lesen', permissions: { create: readOnlyPermIds.map((id) => ({ permissionId: id })), }, }, }); console.log('Roles created'); // Create admin user const hashedPassword = await bcrypt.hash('admin', 10); const adminUser = await prisma.user.upsert({ where: { email: 'admin@admin.com' }, update: {}, create: { email: 'admin@admin.com', password: hashedPassword, firstName: 'Admin', lastName: 'User', roles: { create: [{ roleId: adminRole.id }], }, }, }); console.log('Admin user created: admin@admin.com / admin'); // Create some sales platforms const platforms = ['Moon Fachhandel', 'Verivox', 'Check24', 'Eigenvermittlung']; for (const name of platforms) { await prisma.salesPlatform.upsert({ where: { name }, update: {}, create: { name, isActive: true }, }); } console.log('Sales platforms created'); // ==================== STANDARD PROVIDERS ==================== const providers = [ { name: 'Vodafone', portalUrl: 'https://www.vodafone.de/meinvodafone/account/login', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: 'Klarmobil', portalUrl: 'https://www.klarmobil.de/login', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: 'Otelo', portalUrl: 'https://www.otelo.de/mein-otelo/login', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: 'Congstar', portalUrl: 'https://www.congstar.de/login/', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: 'Telekom', portalUrl: 'https://www.telekom.de/kundencenter/startseite', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: 'O2', portalUrl: 'https://www.o2online.de/ecare/selfcare', usernameFieldName: 'username', passwordFieldName: 'password', }, { name: '1&1', portalUrl: 'https://control-center.1und1.de/', usernameFieldName: 'username', passwordFieldName: 'password', }, ]; for (const provider of providers) { await prisma.provider.upsert({ where: { name: provider.name }, update: { portalUrl: provider.portalUrl, usernameFieldName: provider.usernameFieldName, passwordFieldName: provider.passwordFieldName, }, create: { ...provider, isActive: true }, }); } console.log('Providers created'); // Create contract categories (matching existing enum values) const contractCategories = [ { code: 'ELECTRICITY', name: 'Strom', icon: 'Zap', color: '#FFC107', sortOrder: 1 }, { code: 'GAS', name: 'Gas', icon: 'Flame', color: '#FF5722', sortOrder: 2 }, { code: 'DSL', name: 'DSL', icon: 'Wifi', color: '#2196F3', sortOrder: 3 }, { code: 'FIBER', name: 'Glasfaser', icon: 'Cable', color: '#9C27B0', sortOrder: 4 }, { code: 'CABLE', name: 'Kabel Internet (Coax)', icon: 'Cable', color: '#00BCD4', sortOrder: 5 }, { code: 'MOBILE', name: 'Mobilfunk', icon: 'Smartphone', color: '#4CAF50', sortOrder: 6 }, { code: 'TV', name: 'TV', icon: 'Tv', color: '#E91E63', sortOrder: 7 }, { code: 'CAR_INSURANCE', name: 'KFZ-Versicherung', icon: 'Car', color: '#607D8B', sortOrder: 8 }, ]; for (const category of contractCategories) { await prisma.contractCategory.upsert({ where: { code: category.code }, update: { name: category.name, icon: category.icon, color: category.color, sortOrder: category.sortOrder }, create: category, }); } console.log('Contract categories created'); // ==================== CANCELLATION PERIODS ==================== const cancellationPeriods = [ { code: '14D', description: '14 Tage' }, { code: '1M', description: '1 Monat' }, { code: '2M', description: '2 Monate' }, { code: '3M', description: '3 Monate' }, { code: '6M', description: '6 Monate' }, { code: '12M', description: '12 Monate' }, { code: '1W', description: '1 Woche' }, { code: '2W', description: '2 Wochen' }, { code: '4W', description: '4 Wochen' }, { code: '6W', description: '6 Wochen' }, ]; for (const period of cancellationPeriods) { await prisma.cancellationPeriod.upsert({ where: { code: period.code }, update: { description: period.description }, create: period, }); } console.log('Cancellation periods created'); // ==================== CONTRACT DURATIONS ==================== const contractDurations = [ { code: '1M', description: '1 Monat' }, { code: '3M', description: '3 Monate' }, { code: '6M', description: '6 Monate' }, { code: '12M', description: '12 Monate' }, { code: '24M', description: '24 Monate' }, { code: '36M', description: '36 Monate' }, { code: '1J', description: '1 Jahr' }, { code: '2J', description: '2 Jahre' }, { code: '3J', description: '3 Jahre' }, { code: '4J', description: '4 Jahre' }, { code: '5J', description: '5 Jahre' }, { code: 'UNBEFRISTET', description: 'Unbefristet' }, ]; for (const duration of contractDurations) { await prisma.contractDuration.upsert({ where: { code: duration.code }, update: { description: duration.description }, create: duration, }); } console.log('Contract durations created'); // ==================== APP SETTINGS ==================== const appSettings = [ // Cockpit-Einstellungen (Fristen-Ampel) { key: 'deadlineCriticalDays', value: '14' }, // Rot: <= 14 Tage { key: 'deadlineWarningDays', value: '42' }, // Gelb: <= 42 Tage { key: 'deadlineOkDays', value: '90' }, // Grün: <= 90 Tage // Allgemeine Einstellungen { key: 'companyName', value: 'OpenCRM' }, { key: 'defaultEmailDomain', value: 'stressfrei-wechseln.de' }, ]; for (const setting of appSettings) { await prisma.appSetting.upsert({ where: { key: setting.key }, update: {}, // Bestehende Werte nicht überschreiben create: setting, }); } console.log('App settings created'); console.log('Seeding completed!'); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });