gdpr audit implemented, email log, vollmachten, pdf delete cancel data privacy and vollmachten, removed message no id card in engergy car, and other contracts that are not telecom contracts, added insert counter for engery
This commit is contained in:
+148
-4
@@ -1,5 +1,6 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import crypto from 'crypto';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -26,6 +27,9 @@ async function main() {
|
||||
// Spezial-Permissions
|
||||
developer: ['access'],
|
||||
emails: ['delete'],
|
||||
// DSGVO & Audit
|
||||
audit: ['read', 'export', 'admin'],
|
||||
gdpr: ['export', 'delete', 'admin'],
|
||||
};
|
||||
|
||||
const permissions: { resource: string; action: string }[] = [];
|
||||
@@ -60,10 +64,42 @@ async function main() {
|
||||
(p) => p.resource === 'providers' && p.action === 'read'
|
||||
);
|
||||
|
||||
// Helper: Sync permissions for a role (adds missing, removes excess)
|
||||
async function syncRolePermissions(roleId: number, permissionIds: number[]) {
|
||||
const existing = await prisma.rolePermission.findMany({
|
||||
where: { roleId },
|
||||
select: { permissionId: true },
|
||||
});
|
||||
const existingIds = new Set(existing.map((e) => e.permissionId));
|
||||
const targetIds = new Set(permissionIds);
|
||||
|
||||
// Add missing permissions
|
||||
const missing = permissionIds.filter((id) => !existingIds.has(id));
|
||||
if (missing.length > 0) {
|
||||
await prisma.rolePermission.createMany({
|
||||
data: missing.map((permissionId) => ({ roleId, permissionId })),
|
||||
skipDuplicates: true,
|
||||
});
|
||||
console.log(` → ${missing.length} Permissions hinzugefügt für Rolle #${roleId}`);
|
||||
}
|
||||
|
||||
// Remove excess permissions
|
||||
const excess = existing.filter((e) => !targetIds.has(e.permissionId)).map((e) => e.permissionId);
|
||||
if (excess.length > 0) {
|
||||
await prisma.rolePermission.deleteMany({
|
||||
where: { roleId, permissionId: { in: excess } },
|
||||
});
|
||||
console.log(` → ${excess.length} Permissions entfernt für Rolle #${roleId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Create roles
|
||||
// Admin - all permissions EXCEPT developer:access (that's controlled separately)
|
||||
// Admin - all permissions EXCEPT developer:access and audit/gdpr (controlled separately via checkboxes)
|
||||
const adminPermissions = allPermissions.filter(
|
||||
(p) => !(p.resource === 'developer' && p.action === 'access')
|
||||
(p) =>
|
||||
!(p.resource === 'developer' && p.action === 'access') &&
|
||||
p.resource !== 'audit' &&
|
||||
p.resource !== 'gdpr'
|
||||
);
|
||||
const adminRole = await prisma.role.upsert({
|
||||
where: { name: 'Admin' },
|
||||
@@ -76,8 +112,10 @@ async function main() {
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(adminRole.id, adminPermissions.map((p) => p.id));
|
||||
|
||||
// Developer - ALL permissions including developer:access
|
||||
// Developer - ALL permissions (developer:access + alles andere)
|
||||
const developerPermissions = allPermissions;
|
||||
const developerRole = await prisma.role.upsert({
|
||||
where: { name: 'Developer' },
|
||||
update: {},
|
||||
@@ -85,10 +123,28 @@ async function main() {
|
||||
name: 'Developer',
|
||||
description: 'Voller Zugriff inkl. Entwickler-Tools',
|
||||
permissions: {
|
||||
create: allPermissions.map((p) => ({ permissionId: p.id })),
|
||||
create: developerPermissions.map((p) => ({ permissionId: p.id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(developerRole.id, developerPermissions.map((p) => p.id));
|
||||
|
||||
// DSGVO - audit and gdpr permissions (hidden role, controlled via hasGdprAccess)
|
||||
const gdprPermissions = allPermissions.filter(
|
||||
(p) => p.resource === 'audit' || p.resource === 'gdpr'
|
||||
);
|
||||
const gdprRole = await prisma.role.upsert({
|
||||
where: { name: 'DSGVO' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'DSGVO',
|
||||
description: 'DSGVO-Zugriff: Audit-Logs und Datenschutz-Verwaltung',
|
||||
permissions: {
|
||||
create: gdprPermissions.map((p) => ({ permissionId: p.id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(gdprRole.id, gdprPermissions.map((p) => p.id));
|
||||
|
||||
// Employee - full access to customers, contracts, read access to lookup tables
|
||||
const employeePermIds = allPermissions
|
||||
@@ -119,6 +175,7 @@ async function main() {
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(employeeRole.id, employeePermIds);
|
||||
|
||||
// Read-only employee - read access to main entities and lookup tables
|
||||
const readOnlyResources = [
|
||||
@@ -146,6 +203,7 @@ async function main() {
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(readOnlyRole.id, readOnlyPermIds);
|
||||
|
||||
// Customer role - read own data only (handled in middleware)
|
||||
const customerRole = await prisma.role.upsert({
|
||||
@@ -159,6 +217,7 @@ async function main() {
|
||||
},
|
||||
},
|
||||
});
|
||||
await syncRolePermissions(customerRole.id, readOnlyPermIds);
|
||||
|
||||
console.log('Roles created');
|
||||
|
||||
@@ -346,6 +405,91 @@ async function main() {
|
||||
|
||||
console.log('App settings created');
|
||||
|
||||
// ==================== AUDIT RETENTION POLICIES (DSGVO) ====================
|
||||
// Standard-Policy (ohne Sensitivity)
|
||||
const existingDefault = await prisma.auditRetentionPolicy.findFirst({
|
||||
where: { resourceType: '*', sensitivity: null },
|
||||
});
|
||||
if (!existingDefault) {
|
||||
await prisma.auditRetentionPolicy.create({
|
||||
data: {
|
||||
resourceType: '*',
|
||||
sensitivity: null,
|
||||
retentionDays: 3650, // 10 Jahre
|
||||
description: 'Standard-Aufbewahrungsfrist',
|
||||
legalBasis: 'AO §147, HGB §257',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Spezifische Policies mit Sensitivity
|
||||
const specificPolicies = [
|
||||
{
|
||||
resourceType: 'Authentication',
|
||||
sensitivity: 'CRITICAL' as const,
|
||||
retentionDays: 730, // 2 Jahre
|
||||
description: 'Login-Versuche und Authentifizierung',
|
||||
legalBasis: 'Sicherheitsanforderungen',
|
||||
},
|
||||
{
|
||||
resourceType: 'Customer',
|
||||
sensitivity: 'HIGH' as const,
|
||||
retentionDays: 3650, // 10 Jahre
|
||||
description: 'Kundendaten-Zugriffe',
|
||||
legalBasis: 'Steuerrecht (AO §147)',
|
||||
},
|
||||
{
|
||||
resourceType: 'Contract',
|
||||
sensitivity: 'MEDIUM' as const,
|
||||
retentionDays: 3650, // 10 Jahre
|
||||
description: 'Vertragsdaten-Zugriffe',
|
||||
legalBasis: 'Steuerrecht (AO §147)',
|
||||
},
|
||||
{
|
||||
resourceType: 'AppSetting',
|
||||
sensitivity: 'LOW' as const,
|
||||
retentionDays: 1095, // 3 Jahre
|
||||
description: 'Allgemeine Einstellungen',
|
||||
legalBasis: 'Verjährungsfrist (BGB §195)',
|
||||
},
|
||||
];
|
||||
|
||||
for (const policy of specificPolicies) {
|
||||
await prisma.auditRetentionPolicy.upsert({
|
||||
where: {
|
||||
resourceType_sensitivity: {
|
||||
resourceType: policy.resourceType,
|
||||
sensitivity: policy.sensitivity,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
retentionDays: policy.retentionDays,
|
||||
description: policy.description,
|
||||
legalBasis: policy.legalBasis,
|
||||
},
|
||||
create: policy,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Audit retention policies created');
|
||||
|
||||
// ==================== CONSENT HASH FÜR BESTEHENDE KUNDEN ====================
|
||||
const customersWithoutHash = await prisma.customer.findMany({
|
||||
where: { consentHash: null },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
for (const c of customersWithoutHash) {
|
||||
await prisma.customer.update({
|
||||
where: { id: c.id },
|
||||
data: { consentHash: crypto.randomUUID() },
|
||||
});
|
||||
}
|
||||
|
||||
if (customersWithoutHash.length > 0) {
|
||||
console.log(`ConsentHash für ${customersWithoutHash.length} Kunden generiert`);
|
||||
}
|
||||
|
||||
console.log('Seeding completed!');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user