added backup and email client

This commit is contained in:
2026-02-01 00:02:35 +01:00
parent ff857be01a
commit e4fdfbc95f
210 changed files with 24211 additions and 742 deletions
+108 -24
View File
@@ -20,17 +20,18 @@ model AppSetting {
// ==================== USERS & AUTH ====================
model User {
id Int @id @default(autoincrement())
email String @unique
password String
firstName String
lastName String
isActive Boolean @default(true)
customerId Int? @unique
customer Customer? @relation(fields: [customerId], references: [id])
roles UserRole[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id Int @id @default(autoincrement())
email String @unique
password String
firstName String
lastName String
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
}
model Role {
@@ -216,6 +217,13 @@ enum EmailProviderType {
DIRECTADMIN
}
// Verschlüsselungstyp für E-Mail-Verbindungen
enum MailEncryption {
SSL // Implicit SSL/TLS (Ports 465/993) - Verschlüsselung von Anfang an
STARTTLS // STARTTLS (Ports 587/143) - Startet unverschlüsselt, dann Upgrade
NONE // Keine Verschlüsselung (Ports 25/143)
}
model EmailProviderConfig {
id Int @id @default(autoincrement())
name String @unique // z.B. "Plesk Hauptserver"
@@ -226,6 +234,18 @@ model EmailProviderConfig {
passwordEncrypted String? // Passwort (verschlüsselt)
domain String // Domain für E-Mails (z.B. stressfrei-wechseln.de)
defaultForwardEmail String? // Standard-Weiterleitungsadresse (unsere eigene)
// IMAP/SMTP-Server für E-Mail-Client (optional, default: mail.{domain})
imapServer String? // z.B. "mail.stressfrei-wechseln.de"
imapPort Int? @default(993)
smtpServer String?
smtpPort Int? @default(465)
// Verschlüsselungs-Einstellungen
imapEncryption MailEncryption @default(SSL) // SSL, STARTTLS oder NONE
smtpEncryption MailEncryption @default(SSL) // SSL, STARTTLS oder NONE
allowSelfSignedCerts Boolean @default(false) // Selbstsignierte Zertifikate erlauben
isActive Boolean @default(true)
isDefault Boolean @default(false) // Standard-Provider
createdAt DateTime @default(now())
@@ -235,19 +255,82 @@ model EmailProviderConfig {
// ==================== STRESSFREI-WECHSELN EMAIL ADDRESSES ====================
model StressfreiEmail {
id Int @id @default(autoincrement())
customerId Int
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
email String // Die Weiterleitungs-E-Mail-Adresse
platform String? // Für welche Plattform (z.B. "Freenet", "Klarmobil")
notes String? @db.Text // Optionale Notizen
isActive Boolean @default(true)
isProvisioned Boolean @default(false) // Wurde bei Provider angelegt?
provisionedAt DateTime? // Wann wurde provisioniert?
provisionError String? @db.Text // Fehlermeldung falls Provisionierung fehlschlug
contracts Contract[] // Verträge die diese E-Mail als Benutzername verwenden
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id Int @id @default(autoincrement())
customerId Int
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
email String // Die Weiterleitungs-E-Mail-Adresse
platform String? // Für welche Plattform (z.B. "Freenet", "Klarmobil")
notes String? @db.Text // Optionale Notizen
isActive Boolean @default(true)
isProvisioned Boolean @default(false) // Wurde bei Provider angelegt?
provisionedAt DateTime? // Wann wurde provisioniert?
provisionError String? @db.Text // Fehlermeldung falls Provisionierung fehlschlug
// Mailbox-Zugangsdaten (für IMAP/SMTP-Zugang)
hasMailbox Boolean @default(false) // Hat echte Mailbox (nicht nur Weiterleitung)?
emailPasswordEncrypted String? // Verschlüsseltes Mailbox-Passwort (AES-256-GCM)
contracts Contract[] // Verträge die diese E-Mail als Benutzername verwenden
cachedEmails CachedEmail[] // Gecachte E-Mails aus dieser Mailbox
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// ==================== CACHED EMAILS (E-Mail-Client) ====================
enum EmailFolder {
INBOX
SENT
}
model CachedEmail {
id Int @id @default(autoincrement())
stressfreiEmailId Int
stressfreiEmail StressfreiEmail @relation(fields: [stressfreiEmailId], references: [id], onDelete: Cascade)
// Ordner (Posteingang oder Gesendet)
folder EmailFolder @default(INBOX)
// IMAP-Identifikation
messageId String // RFC 5322 Message-ID
uid Int // IMAP UID (für Synchronisierung, bei SENT = 0)
// E-Mail-Metadaten
subject String?
fromAddress String
fromName String?
toAddresses String @db.Text // JSON Array
ccAddresses String? @db.Text // JSON Array
receivedAt DateTime
// Inhalt
textBody String? @db.LongText
htmlBody String? @db.LongText
hasAttachments Boolean @default(false)
attachmentNames String? @db.Text // JSON Array
// Vertragszuordnung
contractId Int?
contract Contract? @relation(fields: [contractId], references: [id], onDelete: SetNull)
assignedAt DateTime?
assignedBy Int? // User ID der die Zuordnung gemacht hat
isAutoAssigned Boolean @default(false) // true = automatisch beim Senden aus Vertrag
// Flags
isRead Boolean @default(false)
isStarred Boolean @default(false)
// Papierkorb
isDeleted Boolean @default(false) // Im Papierkorb?
deletedAt DateTime? // Wann gelöscht?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([stressfreiEmailId, messageId, folder]) // Folder hinzugefügt: gleiche MessageID kann in INBOX und SENT existieren
@@index([contractId])
@@index([stressfreiEmailId, folder, receivedAt])
@@index([stressfreiEmailId, isDeleted]) // Für Papierkorb-Abfragen
}
// ==================== METERS (Energy) ====================
@@ -465,6 +548,7 @@ model Contract {
carInsuranceDetails CarInsuranceDetails?
tasks ContractTask[]
assignedEmails CachedEmail[] // Zugeordnete E-Mails aus dem E-Mail-Client
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt