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:
+174
-4
File diff suppressed because one or more lines are too long
+170
-1
@@ -122,6 +122,25 @@ exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.EmailLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fromAddress: 'fromAddress',
|
||||
toAddress: 'toAddress',
|
||||
subject: 'subject',
|
||||
context: 'context',
|
||||
customerId: 'customerId',
|
||||
triggeredBy: 'triggeredBy',
|
||||
smtpServer: 'smtpServer',
|
||||
smtpPort: 'smtpPort',
|
||||
smtpEncryption: 'smtpEncryption',
|
||||
smtpUser: 'smtpUser',
|
||||
success: 'success',
|
||||
messageId: 'messageId',
|
||||
errorMessage: 'errorMessage',
|
||||
smtpResponse: 'smtpResponse',
|
||||
sentAt: 'sentAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AppSettingScalarFieldEnum = {
|
||||
id: 'id',
|
||||
key: 'key',
|
||||
@@ -138,6 +157,9 @@ exports.Prisma.UserScalarFieldEnum = {
|
||||
lastName: 'lastName',
|
||||
isActive: 'isActive',
|
||||
tokenInvalidatedAt: 'tokenInvalidatedAt',
|
||||
whatsappNumber: 'whatsappNumber',
|
||||
telegramUsername: 'telegramUsername',
|
||||
signalNumber: 'signalNumber',
|
||||
customerId: 'customerId',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
@@ -186,6 +208,7 @@ exports.Prisma.CustomerScalarFieldEnum = {
|
||||
commercialRegisterPath: 'commercialRegisterPath',
|
||||
commercialRegisterNumber: 'commercialRegisterNumber',
|
||||
privacyPolicyPath: 'privacyPolicyPath',
|
||||
consentHash: 'consentHash',
|
||||
notes: 'notes',
|
||||
portalEnabled: 'portalEnabled',
|
||||
portalEmail: 'portalEmail',
|
||||
@@ -206,6 +229,20 @@ exports.Prisma.CustomerRepresentativeScalarFieldEnum = {
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RepresentativeAuthorizationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
representativeId: 'representativeId',
|
||||
isGranted: 'isGranted',
|
||||
grantedAt: 'grantedAt',
|
||||
withdrawnAt: 'withdrawnAt',
|
||||
source: 'source',
|
||||
documentPath: 'documentPath',
|
||||
notes: 'notes',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AddressScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
@@ -267,6 +304,8 @@ exports.Prisma.EmailProviderConfigScalarFieldEnum = {
|
||||
imapEncryption: 'imapEncryption',
|
||||
smtpEncryption: 'smtpEncryption',
|
||||
allowSelfSignedCerts: 'allowSelfSignedCerts',
|
||||
systemEmailAddress: 'systemEmailAddress',
|
||||
systemEmailPasswordEncrypted: 'systemEmailPasswordEncrypted',
|
||||
isActive: 'isActive',
|
||||
isDefault: 'isDefault',
|
||||
createdAt: 'createdAt',
|
||||
@@ -335,6 +374,10 @@ exports.Prisma.MeterReadingScalarFieldEnum = {
|
||||
value: 'value',
|
||||
unit: 'unit',
|
||||
notes: 'notes',
|
||||
reportedBy: 'reportedBy',
|
||||
status: 'status',
|
||||
transferredAt: 'transferredAt',
|
||||
transferredBy: 'transferredBy',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -577,6 +620,80 @@ exports.Prisma.CarInsuranceDetailsScalarFieldEnum = {
|
||||
previousInsurer: 'previousInsurer'
|
||||
};
|
||||
|
||||
exports.Prisma.AuditLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
userId: 'userId',
|
||||
userEmail: 'userEmail',
|
||||
userRole: 'userRole',
|
||||
customerId: 'customerId',
|
||||
isCustomerPortal: 'isCustomerPortal',
|
||||
action: 'action',
|
||||
sensitivity: 'sensitivity',
|
||||
resourceType: 'resourceType',
|
||||
resourceId: 'resourceId',
|
||||
resourceLabel: 'resourceLabel',
|
||||
endpoint: 'endpoint',
|
||||
httpMethod: 'httpMethod',
|
||||
ipAddress: 'ipAddress',
|
||||
userAgent: 'userAgent',
|
||||
changesBefore: 'changesBefore',
|
||||
changesAfter: 'changesAfter',
|
||||
changesEncrypted: 'changesEncrypted',
|
||||
dataSubjectId: 'dataSubjectId',
|
||||
legalBasis: 'legalBasis',
|
||||
success: 'success',
|
||||
errorMessage: 'errorMessage',
|
||||
durationMs: 'durationMs',
|
||||
createdAt: 'createdAt',
|
||||
hash: 'hash',
|
||||
previousHash: 'previousHash'
|
||||
};
|
||||
|
||||
exports.Prisma.CustomerConsentScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
consentType: 'consentType',
|
||||
status: 'status',
|
||||
grantedAt: 'grantedAt',
|
||||
withdrawnAt: 'withdrawnAt',
|
||||
source: 'source',
|
||||
documentPath: 'documentPath',
|
||||
version: 'version',
|
||||
ipAddress: 'ipAddress',
|
||||
createdBy: 'createdBy',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.DataDeletionRequestScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
status: 'status',
|
||||
requestedAt: 'requestedAt',
|
||||
requestSource: 'requestSource',
|
||||
requestedBy: 'requestedBy',
|
||||
processedAt: 'processedAt',
|
||||
processedBy: 'processedBy',
|
||||
deletedData: 'deletedData',
|
||||
retainedData: 'retainedData',
|
||||
retentionReason: 'retentionReason',
|
||||
proofDocument: 'proofDocument',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AuditRetentionPolicyScalarFieldEnum = {
|
||||
id: 'id',
|
||||
resourceType: 'resourceType',
|
||||
sensitivity: 'sensitivity',
|
||||
retentionDays: 'retentionDays',
|
||||
description: 'description',
|
||||
legalBasis: 'legalBasis',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
@@ -625,6 +742,12 @@ exports.MeterType = exports.$Enums.MeterType = {
|
||||
GAS: 'GAS'
|
||||
};
|
||||
|
||||
exports.MeterReadingStatus = exports.$Enums.MeterReadingStatus = {
|
||||
RECORDED: 'RECORDED',
|
||||
REPORTED: 'REPORTED',
|
||||
TRANSFERRED: 'TRANSFERRED'
|
||||
};
|
||||
|
||||
exports.ContractType = exports.$Enums.ContractType = {
|
||||
ELECTRICITY: 'ELECTRICITY',
|
||||
GAS: 'GAS',
|
||||
@@ -662,7 +785,48 @@ exports.InsuranceType = exports.$Enums.InsuranceType = {
|
||||
FULL: 'FULL'
|
||||
};
|
||||
|
||||
exports.AuditAction = exports.$Enums.AuditAction = {
|
||||
CREATE: 'CREATE',
|
||||
READ: 'READ',
|
||||
UPDATE: 'UPDATE',
|
||||
DELETE: 'DELETE',
|
||||
EXPORT: 'EXPORT',
|
||||
ANONYMIZE: 'ANONYMIZE',
|
||||
LOGIN: 'LOGIN',
|
||||
LOGOUT: 'LOGOUT',
|
||||
LOGIN_FAILED: 'LOGIN_FAILED'
|
||||
};
|
||||
|
||||
exports.AuditSensitivity = exports.$Enums.AuditSensitivity = {
|
||||
LOW: 'LOW',
|
||||
MEDIUM: 'MEDIUM',
|
||||
HIGH: 'HIGH',
|
||||
CRITICAL: 'CRITICAL'
|
||||
};
|
||||
|
||||
exports.ConsentType = exports.$Enums.ConsentType = {
|
||||
DATA_PROCESSING: 'DATA_PROCESSING',
|
||||
MARKETING_EMAIL: 'MARKETING_EMAIL',
|
||||
MARKETING_PHONE: 'MARKETING_PHONE',
|
||||
DATA_SHARING_PARTNER: 'DATA_SHARING_PARTNER'
|
||||
};
|
||||
|
||||
exports.ConsentStatus = exports.$Enums.ConsentStatus = {
|
||||
GRANTED: 'GRANTED',
|
||||
WITHDRAWN: 'WITHDRAWN',
|
||||
PENDING: 'PENDING'
|
||||
};
|
||||
|
||||
exports.DeletionRequestStatus = exports.$Enums.DeletionRequestStatus = {
|
||||
PENDING: 'PENDING',
|
||||
IN_PROGRESS: 'IN_PROGRESS',
|
||||
COMPLETED: 'COMPLETED',
|
||||
PARTIALLY_COMPLETED: 'PARTIALLY_COMPLETED',
|
||||
REJECTED: 'REJECTED'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
EmailLog: 'EmailLog',
|
||||
AppSetting: 'AppSetting',
|
||||
User: 'User',
|
||||
Role: 'Role',
|
||||
@@ -671,6 +835,7 @@ exports.Prisma.ModelName = {
|
||||
UserRole: 'UserRole',
|
||||
Customer: 'Customer',
|
||||
CustomerRepresentative: 'CustomerRepresentative',
|
||||
RepresentativeAuthorization: 'RepresentativeAuthorization',
|
||||
Address: 'Address',
|
||||
BankCard: 'BankCard',
|
||||
IdentityDocument: 'IdentityDocument',
|
||||
@@ -696,7 +861,11 @@ exports.Prisma.ModelName = {
|
||||
MobileContractDetails: 'MobileContractDetails',
|
||||
SimCard: 'SimCard',
|
||||
TvContractDetails: 'TvContractDetails',
|
||||
CarInsuranceDetails: 'CarInsuranceDetails'
|
||||
CarInsuranceDetails: 'CarInsuranceDetails',
|
||||
AuditLog: 'AuditLog',
|
||||
CustomerConsent: 'CustomerConsent',
|
||||
DataDeletionRequest: 'DataDeletionRequest',
|
||||
AuditRetentionPolicy: 'AuditRetentionPolicy'
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+10649
-198
File diff suppressed because it is too large
Load Diff
+174
-4
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "prisma-client-652f85dbf9d7be282ff4b16714e4689fe4701aade21c76f6bcc5db624157e639",
|
||||
"name": "prisma-client-c6d54e22fa4d6137f643638da5d523e99ce84f9544cc793fd89163f1612953c6",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "index-browser.js",
|
||||
|
||||
+264
-16
@@ -7,6 +7,36 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ==================== EMAIL LOG ====================
|
||||
|
||||
model EmailLog {
|
||||
id Int @id @default(autoincrement())
|
||||
// Absender & Empfänger
|
||||
fromAddress String // Absender-E-Mail
|
||||
toAddress String // Empfänger-E-Mail
|
||||
subject String // Betreff
|
||||
// Versand-Kontext
|
||||
context String // z.B. "consent-link", "authorization-request", "customer-email"
|
||||
customerId Int? // Zugehöriger Kunde (falls vorhanden)
|
||||
triggeredBy String? // Wer hat den Versand ausgelöst (User-Email)
|
||||
// SMTP-Details
|
||||
smtpServer String // SMTP-Server
|
||||
smtpPort Int // SMTP-Port
|
||||
smtpEncryption String // SSL, STARTTLS, NONE
|
||||
smtpUser String // SMTP-Benutzername
|
||||
// Ergebnis
|
||||
success Boolean // Erfolgreich?
|
||||
messageId String? // Message-ID aus SMTP-Antwort
|
||||
errorMessage String? @db.Text // Fehlermeldung bei Fehler
|
||||
smtpResponse String? @db.Text // SMTP-Server-Antwort
|
||||
// Zeitstempel
|
||||
sentAt DateTime @default(now())
|
||||
|
||||
@@index([sentAt])
|
||||
@@index([customerId])
|
||||
@@index([success])
|
||||
}
|
||||
|
||||
// ==================== APP SETTINGS ====================
|
||||
|
||||
model AppSetting {
|
||||
@@ -20,18 +50,24 @@ model AppSetting {
|
||||
// ==================== USERS & AUTH ====================
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
password String
|
||||
firstName String
|
||||
lastName String
|
||||
isActive Boolean @default(true)
|
||||
isActive Boolean @default(true)
|
||||
tokenInvalidatedAt DateTime? // Zeitpunkt ab dem alle Tokens ungültig sind (für Zwangslogout bei Rechteänderung)
|
||||
customerId Int? @unique
|
||||
customer Customer? @relation(fields: [customerId], references: [id])
|
||||
roles UserRole[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Messaging-Kanäle (für Datenschutz-Link-Versand)
|
||||
whatsappNumber String?
|
||||
telegramUsername String?
|
||||
signalNumber String?
|
||||
|
||||
customerId Int? @unique
|
||||
customer Customer? @relation(fields: [customerId], references: [id])
|
||||
roles UserRole[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Role {
|
||||
@@ -97,6 +133,7 @@ model Customer {
|
||||
commercialRegisterPath String? // PDF-Pfad zum Handelsregisterauszug
|
||||
commercialRegisterNumber String? // Handelsregisternummer (Text)
|
||||
privacyPolicyPath String? // PDF-Pfad zur Datenschutzerklärung (für alle Kunden)
|
||||
consentHash String? @unique // Permanenter Hash für öffentlichen Einwilligungslink /datenschutz/<hash>
|
||||
notes String? @db.Text
|
||||
|
||||
// ===== Portal-Zugangsdaten =====
|
||||
@@ -118,6 +155,13 @@ model Customer {
|
||||
representingFor CustomerRepresentative[] @relation("RepresentativeCustomer")
|
||||
representedBy CustomerRepresentative[] @relation("RepresentedCustomer")
|
||||
|
||||
// Vollmachten
|
||||
authorizationsGiven RepresentativeAuthorization[] @relation("AuthorizationCustomer")
|
||||
authorizationsReceived RepresentativeAuthorization[] @relation("AuthorizationRepresentative")
|
||||
|
||||
// DSGVO: Einwilligungen
|
||||
consents CustomerConsent[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
@@ -140,6 +184,28 @@ model CustomerRepresentative {
|
||||
@@unique([customerId, representativeId]) // Keine doppelten Einträge
|
||||
}
|
||||
|
||||
// ==================== VOLLMACHTEN ====================
|
||||
// Vollmacht: Kunde B erteilt Kunde A die Vollmacht, seine Daten einzusehen
|
||||
// Ohne Vollmacht kann der Vertreter die Verträge des Kunden NICHT sehen
|
||||
|
||||
model RepresentativeAuthorization {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int // Der Kunde, der die Vollmacht erteilt (z.B. Mutter)
|
||||
customer Customer @relation("AuthorizationCustomer", fields: [customerId], references: [id], onDelete: Cascade)
|
||||
representativeId Int // Der Vertreter, der Zugriff bekommt (z.B. Sohn)
|
||||
representative Customer @relation("AuthorizationRepresentative", fields: [representativeId], references: [id], onDelete: Cascade)
|
||||
isGranted Boolean @default(false) // Vollmacht erteilt?
|
||||
grantedAt DateTime? // Wann erteilt
|
||||
withdrawnAt DateTime? // Wann widerrufen
|
||||
source String? // Quelle: 'portal', 'papier', 'crm-backend'
|
||||
documentPath String? // PDF-Upload der unterschriebenen Vollmacht
|
||||
notes String? @db.Text // Notizen
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([customerId, representativeId]) // Eine Vollmacht pro Paar
|
||||
}
|
||||
|
||||
// ==================== ADDRESSES ====================
|
||||
|
||||
enum AddressType {
|
||||
@@ -247,6 +313,10 @@ model EmailProviderConfig {
|
||||
smtpEncryption MailEncryption @default(SSL) // SSL, STARTTLS oder NONE
|
||||
allowSelfSignedCerts Boolean @default(false) // Selbstsignierte Zertifikate erlauben
|
||||
|
||||
// System-E-Mail für automatisierte Nachrichten (z.B. DSGVO Consent-Links)
|
||||
systemEmailAddress String? // z.B. "info@stressfrei-wechseln.de"
|
||||
systemEmailPasswordEncrypted String? // Passwort (verschlüsselt)
|
||||
|
||||
isActive Boolean @default(true)
|
||||
isDefault Boolean @default(false) // Standard-Provider
|
||||
createdAt DateTime @default(now())
|
||||
@@ -356,14 +426,25 @@ model Meter {
|
||||
}
|
||||
|
||||
model MeterReading {
|
||||
id Int @id @default(autoincrement())
|
||||
meterId Int
|
||||
meter Meter @relation(fields: [meterId], references: [id], onDelete: Cascade)
|
||||
readingDate DateTime
|
||||
value Float
|
||||
unit String @default("kWh")
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
id Int @id @default(autoincrement())
|
||||
meterId Int
|
||||
meter Meter @relation(fields: [meterId], references: [id], onDelete: Cascade)
|
||||
readingDate DateTime
|
||||
value Float
|
||||
unit String @default("kWh")
|
||||
notes String?
|
||||
// Meldung & Übertragung
|
||||
reportedBy String? // Wer hat gemeldet? (E-Mail des Portal-Kunden oder Mitarbeiter)
|
||||
status MeterReadingStatus @default(RECORDED)
|
||||
transferredAt DateTime? // Wann wurde der Stand an den Anbieter übertragen?
|
||||
transferredBy String? // Wer hat übertragen?
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
enum MeterReadingStatus {
|
||||
RECORDED // Erfasst (vom Mitarbeiter)
|
||||
REPORTED // Vom Kunden gemeldet (Portal)
|
||||
TRANSFERRED // An Anbieter übertragen
|
||||
}
|
||||
|
||||
// ==================== SALES PLATFORMS ====================
|
||||
@@ -759,3 +840,170 @@ model CarInsuranceDetails {
|
||||
policyNumber String?
|
||||
previousInsurer String?
|
||||
}
|
||||
|
||||
// ==================== AUDIT LOGGING (DSGVO) ====================
|
||||
|
||||
enum AuditAction {
|
||||
CREATE
|
||||
READ
|
||||
UPDATE
|
||||
DELETE
|
||||
EXPORT // DSGVO-Datenexport
|
||||
ANONYMIZE // Recht auf Vergessenwerden
|
||||
LOGIN
|
||||
LOGOUT
|
||||
LOGIN_FAILED
|
||||
}
|
||||
|
||||
enum AuditSensitivity {
|
||||
LOW // Einstellungen, Plattformen
|
||||
MEDIUM // Verträge, Tarife
|
||||
HIGH // Kundendaten, Bankdaten
|
||||
CRITICAL // Authentifizierung, Ausweisdokumente
|
||||
}
|
||||
|
||||
model AuditLog {
|
||||
id Int @id @default(autoincrement())
|
||||
|
||||
// Wer
|
||||
userId Int? // Staff User (null bei Kundenportal/System)
|
||||
userEmail String
|
||||
userRole String? @db.Text // Rolle zum Zeitpunkt der Aktion
|
||||
customerId Int? // Bei Kundenportal-Zugriff
|
||||
isCustomerPortal Boolean @default(false)
|
||||
|
||||
// Was
|
||||
action AuditAction
|
||||
sensitivity AuditSensitivity @default(MEDIUM)
|
||||
|
||||
// Welche Ressource
|
||||
resourceType String // Prisma Model Name
|
||||
resourceId String? // ID des Datensatzes
|
||||
resourceLabel String? // Lesbare Bezeichnung
|
||||
|
||||
// Kontext
|
||||
endpoint String // API-Pfad
|
||||
httpMethod String // GET, POST, PUT, DELETE
|
||||
ipAddress String
|
||||
userAgent String? @db.Text
|
||||
|
||||
// Änderungen (JSON, bei sensiblen Daten verschlüsselt)
|
||||
changesBefore String? @db.LongText
|
||||
changesAfter String? @db.LongText
|
||||
changesEncrypted Boolean @default(false)
|
||||
|
||||
// DSGVO
|
||||
dataSubjectId Int? // Betroffene Person (für Reports)
|
||||
legalBasis String? // Rechtsgrundlage
|
||||
|
||||
// Status
|
||||
success Boolean @default(true)
|
||||
errorMessage String? @db.Text
|
||||
durationMs Int?
|
||||
|
||||
// Unveränderlichkeit (Hash-Kette)
|
||||
createdAt DateTime @default(now())
|
||||
hash String? // SHA-256 Hash des Eintrags
|
||||
previousHash String? // Hash des vorherigen Eintrags
|
||||
|
||||
@@index([userId])
|
||||
@@index([customerId])
|
||||
@@index([resourceType, resourceId])
|
||||
@@index([dataSubjectId])
|
||||
@@index([action])
|
||||
@@index([createdAt])
|
||||
@@index([sensitivity])
|
||||
}
|
||||
|
||||
// ==================== CONSENT MANAGEMENT (DSGVO) ====================
|
||||
|
||||
enum ConsentType {
|
||||
DATA_PROCESSING // Grundlegende Datenverarbeitung
|
||||
MARKETING_EMAIL // E-Mail-Marketing
|
||||
MARKETING_PHONE // Telefon-Marketing
|
||||
DATA_SHARING_PARTNER // Weitergabe an Partner
|
||||
}
|
||||
|
||||
enum ConsentStatus {
|
||||
GRANTED
|
||||
WITHDRAWN
|
||||
PENDING
|
||||
}
|
||||
|
||||
model CustomerConsent {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
|
||||
consentType ConsentType
|
||||
status ConsentStatus @default(PENDING)
|
||||
|
||||
grantedAt DateTime?
|
||||
withdrawnAt DateTime?
|
||||
source String? // "portal", "telefon", "papier", "email"
|
||||
documentPath String? // Unterschriebenes Dokument
|
||||
version String? // Version der Datenschutzerklärung
|
||||
ipAddress String?
|
||||
|
||||
createdBy String // User der die Einwilligung erfasst hat
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([customerId, consentType])
|
||||
@@index([customerId])
|
||||
@@index([consentType])
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
// ==================== DATA DELETION REQUESTS (DSGVO) ====================
|
||||
|
||||
enum DeletionRequestStatus {
|
||||
PENDING // Anfrage eingegangen
|
||||
IN_PROGRESS // Wird bearbeitet
|
||||
COMPLETED // Abgeschlossen
|
||||
PARTIALLY_COMPLETED // Teildaten behalten (rechtliche Gründe)
|
||||
REJECTED // Abgelehnt
|
||||
}
|
||||
|
||||
model DataDeletionRequest {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
|
||||
status DeletionRequestStatus @default(PENDING)
|
||||
requestedAt DateTime @default(now())
|
||||
requestSource String // "email", "portal", "brief"
|
||||
requestedBy String // Wer hat angefragt
|
||||
|
||||
processedAt DateTime?
|
||||
processedBy String? // Mitarbeiter der bearbeitet hat
|
||||
|
||||
deletedData String? @db.LongText // JSON: Was wurde gelöscht
|
||||
retainedData String? @db.LongText // JSON: Was wurde behalten + Grund
|
||||
retentionReason String? @db.Text // Begründung für Aufbewahrung
|
||||
|
||||
proofDocument String? // Pfad zum Löschnachweis-PDF
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([customerId])
|
||||
@@index([status])
|
||||
@@index([requestedAt])
|
||||
}
|
||||
|
||||
// ==================== AUDIT RETENTION POLICIES ====================
|
||||
|
||||
model AuditRetentionPolicy {
|
||||
id Int @id @default(autoincrement())
|
||||
resourceType String // "*" für Standard, oder spezifischer Model-Name
|
||||
sensitivity AuditSensitivity?
|
||||
retentionDays Int // Aufbewahrungsfrist in Tagen (z.B. 3650 = 10 Jahre)
|
||||
description String?
|
||||
legalBasis String? // Gesetzliche Grundlage (z.B. "AO §147", "HGB §257")
|
||||
isActive Boolean @default(true)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([resourceType, sensitivity])
|
||||
}
|
||||
|
||||
+170
-1
@@ -122,6 +122,25 @@ exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.EmailLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fromAddress: 'fromAddress',
|
||||
toAddress: 'toAddress',
|
||||
subject: 'subject',
|
||||
context: 'context',
|
||||
customerId: 'customerId',
|
||||
triggeredBy: 'triggeredBy',
|
||||
smtpServer: 'smtpServer',
|
||||
smtpPort: 'smtpPort',
|
||||
smtpEncryption: 'smtpEncryption',
|
||||
smtpUser: 'smtpUser',
|
||||
success: 'success',
|
||||
messageId: 'messageId',
|
||||
errorMessage: 'errorMessage',
|
||||
smtpResponse: 'smtpResponse',
|
||||
sentAt: 'sentAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AppSettingScalarFieldEnum = {
|
||||
id: 'id',
|
||||
key: 'key',
|
||||
@@ -138,6 +157,9 @@ exports.Prisma.UserScalarFieldEnum = {
|
||||
lastName: 'lastName',
|
||||
isActive: 'isActive',
|
||||
tokenInvalidatedAt: 'tokenInvalidatedAt',
|
||||
whatsappNumber: 'whatsappNumber',
|
||||
telegramUsername: 'telegramUsername',
|
||||
signalNumber: 'signalNumber',
|
||||
customerId: 'customerId',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
@@ -186,6 +208,7 @@ exports.Prisma.CustomerScalarFieldEnum = {
|
||||
commercialRegisterPath: 'commercialRegisterPath',
|
||||
commercialRegisterNumber: 'commercialRegisterNumber',
|
||||
privacyPolicyPath: 'privacyPolicyPath',
|
||||
consentHash: 'consentHash',
|
||||
notes: 'notes',
|
||||
portalEnabled: 'portalEnabled',
|
||||
portalEmail: 'portalEmail',
|
||||
@@ -206,6 +229,20 @@ exports.Prisma.CustomerRepresentativeScalarFieldEnum = {
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RepresentativeAuthorizationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
representativeId: 'representativeId',
|
||||
isGranted: 'isGranted',
|
||||
grantedAt: 'grantedAt',
|
||||
withdrawnAt: 'withdrawnAt',
|
||||
source: 'source',
|
||||
documentPath: 'documentPath',
|
||||
notes: 'notes',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AddressScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
@@ -267,6 +304,8 @@ exports.Prisma.EmailProviderConfigScalarFieldEnum = {
|
||||
imapEncryption: 'imapEncryption',
|
||||
smtpEncryption: 'smtpEncryption',
|
||||
allowSelfSignedCerts: 'allowSelfSignedCerts',
|
||||
systemEmailAddress: 'systemEmailAddress',
|
||||
systemEmailPasswordEncrypted: 'systemEmailPasswordEncrypted',
|
||||
isActive: 'isActive',
|
||||
isDefault: 'isDefault',
|
||||
createdAt: 'createdAt',
|
||||
@@ -335,6 +374,10 @@ exports.Prisma.MeterReadingScalarFieldEnum = {
|
||||
value: 'value',
|
||||
unit: 'unit',
|
||||
notes: 'notes',
|
||||
reportedBy: 'reportedBy',
|
||||
status: 'status',
|
||||
transferredAt: 'transferredAt',
|
||||
transferredBy: 'transferredBy',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -577,6 +620,80 @@ exports.Prisma.CarInsuranceDetailsScalarFieldEnum = {
|
||||
previousInsurer: 'previousInsurer'
|
||||
};
|
||||
|
||||
exports.Prisma.AuditLogScalarFieldEnum = {
|
||||
id: 'id',
|
||||
userId: 'userId',
|
||||
userEmail: 'userEmail',
|
||||
userRole: 'userRole',
|
||||
customerId: 'customerId',
|
||||
isCustomerPortal: 'isCustomerPortal',
|
||||
action: 'action',
|
||||
sensitivity: 'sensitivity',
|
||||
resourceType: 'resourceType',
|
||||
resourceId: 'resourceId',
|
||||
resourceLabel: 'resourceLabel',
|
||||
endpoint: 'endpoint',
|
||||
httpMethod: 'httpMethod',
|
||||
ipAddress: 'ipAddress',
|
||||
userAgent: 'userAgent',
|
||||
changesBefore: 'changesBefore',
|
||||
changesAfter: 'changesAfter',
|
||||
changesEncrypted: 'changesEncrypted',
|
||||
dataSubjectId: 'dataSubjectId',
|
||||
legalBasis: 'legalBasis',
|
||||
success: 'success',
|
||||
errorMessage: 'errorMessage',
|
||||
durationMs: 'durationMs',
|
||||
createdAt: 'createdAt',
|
||||
hash: 'hash',
|
||||
previousHash: 'previousHash'
|
||||
};
|
||||
|
||||
exports.Prisma.CustomerConsentScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
consentType: 'consentType',
|
||||
status: 'status',
|
||||
grantedAt: 'grantedAt',
|
||||
withdrawnAt: 'withdrawnAt',
|
||||
source: 'source',
|
||||
documentPath: 'documentPath',
|
||||
version: 'version',
|
||||
ipAddress: 'ipAddress',
|
||||
createdBy: 'createdBy',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.DataDeletionRequestScalarFieldEnum = {
|
||||
id: 'id',
|
||||
customerId: 'customerId',
|
||||
status: 'status',
|
||||
requestedAt: 'requestedAt',
|
||||
requestSource: 'requestSource',
|
||||
requestedBy: 'requestedBy',
|
||||
processedAt: 'processedAt',
|
||||
processedBy: 'processedBy',
|
||||
deletedData: 'deletedData',
|
||||
retainedData: 'retainedData',
|
||||
retentionReason: 'retentionReason',
|
||||
proofDocument: 'proofDocument',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AuditRetentionPolicyScalarFieldEnum = {
|
||||
id: 'id',
|
||||
resourceType: 'resourceType',
|
||||
sensitivity: 'sensitivity',
|
||||
retentionDays: 'retentionDays',
|
||||
description: 'description',
|
||||
legalBasis: 'legalBasis',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
@@ -625,6 +742,12 @@ exports.MeterType = exports.$Enums.MeterType = {
|
||||
GAS: 'GAS'
|
||||
};
|
||||
|
||||
exports.MeterReadingStatus = exports.$Enums.MeterReadingStatus = {
|
||||
RECORDED: 'RECORDED',
|
||||
REPORTED: 'REPORTED',
|
||||
TRANSFERRED: 'TRANSFERRED'
|
||||
};
|
||||
|
||||
exports.ContractType = exports.$Enums.ContractType = {
|
||||
ELECTRICITY: 'ELECTRICITY',
|
||||
GAS: 'GAS',
|
||||
@@ -662,7 +785,48 @@ exports.InsuranceType = exports.$Enums.InsuranceType = {
|
||||
FULL: 'FULL'
|
||||
};
|
||||
|
||||
exports.AuditAction = exports.$Enums.AuditAction = {
|
||||
CREATE: 'CREATE',
|
||||
READ: 'READ',
|
||||
UPDATE: 'UPDATE',
|
||||
DELETE: 'DELETE',
|
||||
EXPORT: 'EXPORT',
|
||||
ANONYMIZE: 'ANONYMIZE',
|
||||
LOGIN: 'LOGIN',
|
||||
LOGOUT: 'LOGOUT',
|
||||
LOGIN_FAILED: 'LOGIN_FAILED'
|
||||
};
|
||||
|
||||
exports.AuditSensitivity = exports.$Enums.AuditSensitivity = {
|
||||
LOW: 'LOW',
|
||||
MEDIUM: 'MEDIUM',
|
||||
HIGH: 'HIGH',
|
||||
CRITICAL: 'CRITICAL'
|
||||
};
|
||||
|
||||
exports.ConsentType = exports.$Enums.ConsentType = {
|
||||
DATA_PROCESSING: 'DATA_PROCESSING',
|
||||
MARKETING_EMAIL: 'MARKETING_EMAIL',
|
||||
MARKETING_PHONE: 'MARKETING_PHONE',
|
||||
DATA_SHARING_PARTNER: 'DATA_SHARING_PARTNER'
|
||||
};
|
||||
|
||||
exports.ConsentStatus = exports.$Enums.ConsentStatus = {
|
||||
GRANTED: 'GRANTED',
|
||||
WITHDRAWN: 'WITHDRAWN',
|
||||
PENDING: 'PENDING'
|
||||
};
|
||||
|
||||
exports.DeletionRequestStatus = exports.$Enums.DeletionRequestStatus = {
|
||||
PENDING: 'PENDING',
|
||||
IN_PROGRESS: 'IN_PROGRESS',
|
||||
COMPLETED: 'COMPLETED',
|
||||
PARTIALLY_COMPLETED: 'PARTIALLY_COMPLETED',
|
||||
REJECTED: 'REJECTED'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
EmailLog: 'EmailLog',
|
||||
AppSetting: 'AppSetting',
|
||||
User: 'User',
|
||||
Role: 'Role',
|
||||
@@ -671,6 +835,7 @@ exports.Prisma.ModelName = {
|
||||
UserRole: 'UserRole',
|
||||
Customer: 'Customer',
|
||||
CustomerRepresentative: 'CustomerRepresentative',
|
||||
RepresentativeAuthorization: 'RepresentativeAuthorization',
|
||||
Address: 'Address',
|
||||
BankCard: 'BankCard',
|
||||
IdentityDocument: 'IdentityDocument',
|
||||
@@ -696,7 +861,11 @@ exports.Prisma.ModelName = {
|
||||
MobileContractDetails: 'MobileContractDetails',
|
||||
SimCard: 'SimCard',
|
||||
TvContractDetails: 'TvContractDetails',
|
||||
CarInsuranceDetails: 'CarInsuranceDetails'
|
||||
CarInsuranceDetails: 'CarInsuranceDetails',
|
||||
AuditLog: 'AuditLog',
|
||||
CustomerConsent: 'CustomerConsent',
|
||||
DataDeletionRequest: 'DataDeletionRequest',
|
||||
AuditRetentionPolicy: 'AuditRetentionPolicy'
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user