|
|
||
|---|---|---|
| backend | ||
| docker | ||
| frontend | ||
| plesktest | ||
| .dockerignore | ||
| README.md | ||
| docker-compose.yml | ||
| test pdf datei.pdf | ||
README.md
OpenCRM
Web-basiertes CRM-System für Kundenverwaltung mit Verträgen (Energie, Telekommunikation, KFZ-Versicherung).
Features
- Kundenverwaltung: Privat- und Geschäftskunden mit Stammdaten
- Adressen: Mehrere Liefer-/Melde- und Rechnungsadressen pro Kunde
- Bankkarten: Mit Ablaufdatum, Aktiv-Status und Dokument-Upload (PDF)
- Ausweise: Personalausweis, Reisepass, etc. mit Ablaufdatum und Dokument-Upload (PDF)
- Zähler: Strom-/Gaszähler mit Zählerstandhistorie
- Rechnungen: Rechnungsverwaltung für Energieverträge mit Dokumenten-Upload
- Vertrags-Cockpit: Dashboard zur Überwachung offener Aufgaben (fehlende Dokumente, Rechnungen)
- Verträge:
- Energie (Strom, Gas)
- Telekommunikation (DSL, Glasfaser, Mobilfunk, TV)
- KFZ-Versicherung
- Folgeverträge: Automatische Datenübernahme bei Anbieterwechsel
- Vertriebsplattformen: Verwaltbar über WebUI
- Email-Provisionierung: Automatische E-Mail-Weiterleitung bei Plesk/cPanel/DirectAdmin
- Berechtigungssystem: Admin, Mitarbeiter, Nur-Lesen, Kundenportal
- Verschlüsselte Zugangsdaten: Portal-Passwörter AES-256-GCM verschlüsselt
- Developer-Tools: Datenbank-Browser und interaktives ER-Diagramm
Tech Stack
- Frontend: React 18, TypeScript, Tailwind CSS, React Query
- Backend: Node.js, Express 4.x, TypeScript
- Datenbank: MariaDB
- ORM: Prisma
- Auth: JWT mit Rollen-basierter Zugriffskontrolle
Hinweis zu Express 5: Das Projekt verwendet bewusst Express 4.x (nicht 5.x). Express 5 ist seit Jahren in der Beta-Phase und noch nicht offiziell stable. Bei der Installation darauf achten, dass
@types/expresszur Express-Version passt:
- Express 4.x →
@types/express@^4.17.x- Express 5.x →
@types/express@^5.x(erst bei offiziellem Release empfohlen)
Voraussetzungen
- Node.js 18+ (empfohlen: 20+)
- Docker & Docker Compose
- npm
Installation
1. Repository klonen
git clone <repository-url>
cd opencrm
2. MariaDB-Datenbank starten
docker-compose up -d
Dies startet einen MariaDB-Container mit:
- Port: 3306
- Datenbank: opencrm
- Root-Passwort: rootpassword
- Benutzer: opencrm / opencrm123
Warte ca. 10 Sekunden bis die Datenbank bereit ist.
3. Backend einrichten
cd backend
# Dependencies installieren
npm install
# .env-Datei erstellen (falls noch nicht vorhanden)
cp .env.example .env
Die .env-Datei sollte folgende Werte enthalten:
# Database
DATABASE_URL="mysql://root:rootpassword@localhost:3306/opencrm"
# JWT
JWT_SECRET="change-this-to-a-very-long-random-secret-in-production"
JWT_EXPIRES_IN="7d"
# Encryption (for portal credentials) - generate with: openssl rand -hex 32
ENCRYPTION_KEY="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
# Server
PORT=3001
NODE_ENV=development
4. Datenbank initialisieren
# Prisma Client generieren und Migrationen ausführen
npx prisma migrate dev
# Seed-Daten einspielen (Admin-User, Rollen, Berechtigungen)
npm run db:seed
5. Frontend einrichten
cd ../frontend
# Dependencies installieren
npm install
Anwendung starten
Backend starten (Terminal 1)
cd backend
npm run dev
Das Backend läuft auf http://localhost:3001
Frontend starten (Terminal 2)
cd frontend
npm run dev
Das Frontend läuft auf http://localhost:5173
Erster Login
Nach dem Seed sind folgende Zugangsdaten verfügbar:
- E-Mail: admin@admin.com
- Passwort: admin
Developer-Tools aktivieren
Die Developer-Tools (Datenbankstruktur, ER-Diagramm) sind standardmäßig für Admins verfügbar. Falls der Menüpunkt nicht erscheint:
- Einmalig im Browser-Console ausführen:
fetch('/api/developer/setup', { method: 'POST' }) - Ausloggen und neu einloggen
Alternativ können Developer-Rechte pro Benutzer vergeben werden:
- Benutzer bearbeiten > "Entwicklerzugriff" aktivieren
Email-Provisionierung
Das System unterstützt die automatische Erstellung von E-Mail-Weiterleitungen auf Hosting-Servern für Stressfrei-Wechseln Adressen.
Unterstützte Provider
- Plesk (implementiert)
- cPanel (vorbereitet)
- DirectAdmin (vorbereitet)
Konfiguration
- Einstellungen → Email-Provisionierung öffnen
- Neuen Provider hinzufügen:
- Name: Bezeichnung (z.B. "Plesk Hauptserver")
- Typ: Plesk/cPanel/DirectAdmin
- API-URL: Server-URL (z.B.
https://server.de:8443) - Benutzername/Passwort: API-Zugangsdaten
- Domain: E-Mail-Domain (z.B.
stressfrei-wechseln.de) - Standard-Weiterleitung: Zusätzliche Weiterleitungsadresse (optional)
- Provider als "Standard" und "Aktiv" markieren
- Verbindung testen
Verwendung
Beim Anlegen einer Stressfrei-Wechseln Adresse im Kundenbereich erscheint die Checkbox "Beim E-Mail-Provider anlegen", wenn:
- Ein aktiver Standard-Provider konfiguriert ist
- Der Kunde eine E-Mail-Adresse hat
Bei aktivierter Checkbox wird automatisch:
- Geprüft, ob die E-Mail-Adresse bereits existiert
- Falls nicht: E-Mail-Adresse beim Provider angelegt mit Weiterleitung an:
- Kunden-E-Mail-Adresse
- Standard-Weiterleitungsadresse (falls konfiguriert)
Befehle
Backend
npm run dev # Entwicklungsserver starten
npm run build # Produktions-Build erstellen
npm run db:studio # Prisma Studio (Datenbank-GUI)
npm run db:migrate # Neue Migration erstellen
npm run db:seed # Seed erneut ausführen
Frontend
npm run dev # Entwicklungsserver starten
npm run build # Produktions-Build erstellen
npm run preview # Build-Vorschau
Docker
docker-compose up -d # Container starten
docker-compose down # Container stoppen
docker-compose down -v # Container stoppen + Daten löschen
docker-compose logs -f # Logs anzeigen
Projektstruktur
opencrm/
├── backend/
│ ├── src/
│ │ ├── controllers/ # Request-Handler
│ │ ├── middleware/ # Auth, Validation
│ │ ├── routes/ # API-Endpunkte
│ │ ├── services/ # Business-Logik
│ │ ├── types/ # TypeScript-Typen
│ │ └── index.ts # Server-Einstiegspunkt
│ ├── prisma/
│ │ ├── schema.prisma # Datenbank-Schema
│ │ └── seed.ts # Seed-Daten
│ ├── uploads/ # Hochgeladene Dokumente
│ │ ├── bank-cards/ # Bankkarten-Dokumente
│ │ ├── documents/ # Ausweis-Scans
│ │ ├── invoices/ # Rechnungsdokumente (Strom/Gas)
│ │ ├── business-registrations/ # Gewerbeanmeldungen
│ │ ├── commercial-registers/ # Handelsregisterauszüge
│ │ ├── privacy-policies/ # Datenschutzerklärungen
│ │ ├── cancellation-letters/ # Kündigungsschreiben
│ │ ├── cancellation-confirmations/ # Kündigungsbestätigungen
│ │ └── cancellation-*-options/ # Kündigungsdokumente Optionen
│ └── package.json
├── frontend/
│ ├── src/
│ │ ├── components/ # UI-Komponenten
│ │ ├── pages/ # Seiten
│ │ ├── hooks/ # Custom Hooks
│ │ ├── services/ # API-Client
│ │ ├── types/ # TypeScript-Typen
│ │ └── App.tsx # Haupt-Komponente
│ └── package.json
├── docker-compose.yml # MariaDB-Container
└── README.md
Berechtigungen
| Rolle | Kunden | Verträge | Benutzer | Plattformen | Developer |
|---|---|---|---|---|---|
| Admin | CRUD | CRUD | CRUD | CRUD | Optional |
| Mitarbeiter | CRUD | CRUD | - | Lesen | - |
| Mitarbeiter (Lesen) | Lesen | Lesen | - | Lesen | - |
| Kunde | Eigene | Eigene | - | - | - |
Troubleshooting
Datenbank-Verbindungsfehler
- Prüfe ob Container läuft:
docker ps - Prüfe die DATABASE_URL in
.env - Warte nach Container-Start ca. 10 Sekunden
Prisma-Fehler
# Prisma Client neu generieren
npx prisma generate
# Schema zur Datenbank pushen (ohne Migration)
npx prisma db push
Port bereits belegt
- Backend:
PORTin.envändern - Frontend: In
vite.config.tsanpassen
Developer-Menü fehlt
# In der Browser-Console:
fetch('/api/developer/setup', { method: 'POST' }).then(r => r.json()).then(console.log)
# Danach ausloggen und neu einloggen
Vertragstypen
Standard-Vertragstypen
Folgende Vertragstypen werden bei Installation/Factory-Reset automatisch angelegt:
| Code | Name | Icon | Farbe |
|---|---|---|---|
| ELECTRICITY | Strom | Zap | #FFC107 |
| GAS | Gas | Flame | #FF5722 |
| DSL | DSL | Wifi | #2196F3 |
| FIBER | Glasfaser | Cable | #9C27B0 |
| CABLE | Kabel Internet (Coax) | Cable | #00BCD4 |
| MOBILE | Mobilfunk | Smartphone | #4CAF50 |
| TV | TV | Tv | #E91E63 |
| CAR_INSURANCE | KFZ-Versicherung | Car | #607D8B |
Hinweis: Vertragstypen können nur von Benutzern mit Entwicklerzugriff geändert werden, da Änderungen auch Anpassungen an den Formularen erfordern.
Vertragstyp-spezifische Felder
Je nach Vertragstyp werden unterschiedliche Felder im Formular angezeigt:
Strom & Gas (ELECTRICITY, GAS)
- Zähler-Auswahl
- Jahresverbrauch (kWh/m³)
- Grundpreis, Arbeitspreis
- Bonus
- Vorversorger, Kundennummer beim Vorversorger
Internet (DSL, CABLE, FIBER)
- Download/Upload (Mbit/s)
- Router Modell, Seriennummer
- Installationsdatum
- Benutzername, Passwort
- Rufnummern mit SIP-Zugangsdaten
| Vertragstyp | Zusatzfeld |
|---|---|
| Glasfaser (FIBER) | Home-ID |
Mobilfunk (MOBILE)
- Datenvolumen (GB)
- Inklusiv-Minuten, Inklusiv-SMS
- Gerät-Modell, IMEI
- Multisim-Checkbox
- SIM-Karten (dynamisch erweiterbar):
- Rufnummer, SIM-Kartennummer (ICCID)
- PIN, PUK (verschlüsselt)
- Multisim-Flag, Hauptkarte-Flag
Hinweis Multisim: Nicht buchbar bei Klarmobil, Congstar, Otelo. Benötigt Freenet oder vergleichbar.
TV
- Receiver Modell
- Smartcard-Nummer
- Paket/Angebot
KFZ-Versicherung (CAR_INSURANCE)
- Kennzeichen, HSN, TSN, FIN/VIN
- Fahrzeugtyp, Erstzulassung
- SF-Klasse (Schadenfreiheitsklasse)
- Versicherungsart (Haftpflicht/Teilkasko/Vollkasko)
- Selbstbeteiligungen (Teilkasko, Vollkasko)
- Versicherungsscheinnummer
- Vorversicherer
Standard-Anbieter
Folgende Anbieter werden bei Installation/Factory-Reset automatisch angelegt:
| Anbieter | Portal-URL |
|---|---|
| Vodafone | https://www.vodafone.de/meinvodafone/account/login |
| Klarmobil | https://www.klarmobil.de/login |
| Otelo | https://www.otelo.de/mein-otelo/login |
| Congstar | https://www.congstar.de/login/ |
| Telekom | https://www.telekom.de/kundencenter/startseite |
| O2 | https://www.o2online.de/ecare/selfcare |
| 1&1 | https://control-center.1und1.de/ |
Anbieter-spezifische Felder
Einige Felder werden nur bei bestimmten Anbietern angezeigt:
| Anbieter | Vertragstyp | Zusatzfeld |
|---|---|---|
| Vodafone | DSL, Kabel Internet | Aktivierungscode |
Hinweis Multisim: Bei Klarmobil, Congstar und Otelo ist Multisim nicht buchbar. Dafür wird Freenet oder ein vergleichbarer Anbieter benötigt.
Rechnungsverwaltung (Energieverträge)
Für Strom- und Gas-Verträge können Rechnungen verwaltet werden, um den Abrechnungsstatus zu tracken.
Rechnungstypen
| Typ | Beschreibung |
|---|---|
| Zwischenrechnung (INTERIM) | Reguläre Jahresrechnung während der Vertragslaufzeit |
| Schlussrechnung (FINAL) | Endabrechnung nach Vertragskündigung/Deaktivierung |
| Nicht verfügbar (NOT_AVAILABLE) | Rechnung ist nicht mehr zu bekommen (z.B. Anbieter existiert nicht mehr) |
Funktionen
- Rechnungen hinzufügen/bearbeiten/löschen in der Vertragsdetailansicht
- Dokument-Upload (PDF) - Pflicht, außer bei Typ "Nicht verfügbar"
- Statusanzeige: Grünes Badge bei Schlussrechnung, Orange bei fehlender Schlussrechnung
- E-Mail-Anhänge als Rechnung speichern: Direkt aus dem E-Mail-Client
E-Mail-Integration
Bei E-Mails, die einem Energievertrag zugeordnet sind:
- Toggle zwischen "Als Dokument" und "Als Rechnung" im Speichern-Dialog
- Rechnungsdatum und Typ auswählen
- Anhang wird automatisch als Rechnungsdokument gespeichert
Vertrags-Cockpit
Dashboard zur Überwachung offener Aufgaben und fehlender Dokumente.
Kategorien
| Kategorie | Prüfungen |
|---|---|
| Fehlende Dokumente | Kündigungsschreiben, Kündigungsbestätigung (wenn Kündigung markiert) |
| Fehlende Rechnungen | Schluss-/Zwischenrechnungen für Energieverträge |
| Ablaufende Dokumente | Ausweise, Bankkarten (nächste 30 Tage) |
Rechnungsprüfung für Energieverträge
Schlussrechnung (gekündigte/deaktivierte Verträge)
| Status | Prüfung |
|---|---|
| CANCELLED / DEACTIVATED | Schlussrechnung oder "Nicht verfügbar" erforderlich |
Zwischenrechnung (laufende Verträge)
| Bedingung | Warnung |
|---|---|
| Vertrag > 12 Monate alt, keine Rechnung | "Zwischenrechnung fehlt" |
| Letzte Rechnung > 12 Monate her | "Zwischenrechnung überfällig" |
Hinweis Status-Logik:
- EXPIRED = Laufzeit abgelaufen, aber Vertrag läuft ohne Kündigung weiter → Zwischenrechnung prüfen
- CANCELLED = Aktive Kündigung → Schlussrechnung prüfen
- DEACTIVATED = Manuell beendet → Schlussrechnung prüfen
Vertrag zurückstellen (Snooze)
Wenn ein Vertrag EXPIRED ist (Laufzeit vorbei, läuft aber weiter), erscheint er im Cockpit. Manchmal ist Bleiben günstiger als Wechseln - aber der Vertrag soll nicht dauerhaft im Cockpit erscheinen.
Lösung: Vertrag temporär zurückstellen mit Datum für erneute Prüfung.
Snooze aktivieren
Im Cockpit hat jeder Vertrag einen Snooze-Button (Glocke mit Uhr). Optionen:
- +3 Monate
- +6 Monate (Empfohlen)
- +12 Monate
- Eigenes Datum (Datepicker)
Unterdrückte Warnungen (bei aktivem Snooze)
| Warnung | Beschreibung |
|---|---|
| Kündigungsfrist | Frist läuft ab |
| Vertrag läuft ab | Enddatum naht |
| Kündigungsschreiben fehlt | Bei markierter Kündigung |
| Kündigungsbestätigung fehlt | Bei markierter Kündigung |
NICHT unterdrückte Warnungen
Diese Warnungen werden auch bei aktivem Snooze angezeigt:
| Warnung | Beschreibung |
|---|---|
| Schlussrechnung fehlt | Beendeter Vertrag ohne Endabrechnung |
| Zwischenrechnung fehlt/überfällig | Laufender Vertrag ohne Jahresrechnung |
| Zählerstand fehlt | Fehlende Zählerstände bei Energieverträgen |
| Zugangsdaten fehlen | Portal-Passwort, SIP-Daten, etc. |
Snooze aufheben
Im Cockpit: Bei Verträgen in der Kategorie "Erneute Prüfung fällig" erscheint ein "Snooze aufheben"-Button.
In Vertragsdetails: Bei zurückgestellten Verträgen erscheint ein bernsteinfarbenes Badge "Zurückgestellt bis [Datum]" mit X-Button zum Aufheben.
Erneute Prüfung fällig
Wenn das Snooze-Datum in der Vergangenheit liegt, erscheint der Vertrag in der neuen Kategorie "Erneute Prüfung fällig" mit Angabe, seit wie vielen Tagen die Prüfung fällig ist.
Status-Info Modal
An verschiedenen Stellen (Vertragsformular, Vertragsdetails, Vertragsübersicht, Kundenansicht) zeigt ein ℹ-Icon neben dem Status eine Erklärung aller Vertragsstatus:
| Status | Bedeutung |
|---|---|
| Entwurf | Vertrag wird noch vorbereitet |
| Ausstehend | Wartet auf Aktivierung |
| Aktiv | Vertrag läuft normal |
| Abgelaufen | Laufzeit vorbei, läuft aber ohne Kündigung weiter |
| Gekündigt | Aktive Kündigung eingereicht, Vertrag endet |
| Deaktiviert | Manuell beendet/archiviert |
E-Mail-Client
Ein vollständig integrierter E-Mail-Client pro Kunde mit IMAP-Empfang und SMTP-Versand.
Funktionen
E-Mails lesen & verwalten
- E-Mail-Tab in Kundenansicht mit Ordnern: Posteingang, Gesendet, Papierkorb
- Mehrere E-Mail-Konten pro Kunde (Dropdown zur Auswahl)
- E-Mail-Detailansicht mit HTML/Text-Body, Absender, Empfänger, CC, Datum
- Gelesen/Ungelesen markieren
- Favoriten (Stern) für wichtige E-Mails
- Papierkorb mit Wiederherstellen und endgültigem Löschen
E-Mails schreiben
- Neue E-Mail verfassen mit An, CC, Betreff, Text
- Antworten mit zitiertem Originaltext
- Dateianhänge (max. 10 MB pro Datei, 25 MB gesamt)
- SMTP-Versand über die gewählte StressfreiEmail-Adresse
Vertragszuordnung
- E-Mails zu Verträgen zuordnen für bessere Nachverfolgung
- E-Mail-Tab in Vertragsansicht zeigt nur zugeordnete E-Mails
- Automatische Zuordnung bei Versand aus Vertragskontext
- Manuelle Zuordnung über Suchfeld und Vertragsauswahl
Anhänge
- Anhangsliste in E-Mail-Detail
- Download einzelner Anhänge
- Inline-Ansicht (im Browser öffnen)
Technische Details
Backend-Services
| Service | Beschreibung |
|---|---|
imapService.ts |
IMAP-Client (ImapFlow) für E-Mail-Empfang |
smtpService.ts |
SMTP-Client (Nodemailer) für E-Mail-Versand |
cachedEmail.service.ts |
E-Mail-Caching, Synchronisation, Zuordnung |
API-Endpunkte
GET /api/customers/:id/emails # E-Mails für Kunde
GET /api/contracts/:id/emails # E-Mails für Vertrag
GET /api/emails/:id # Einzelne E-Mail mit Body
POST /api/stressfrei-emails/:id/sync # IMAP-Synchronisation
POST /api/stressfrei-emails/:id/send # E-Mail senden
POST /api/emails/:id/assign # Vertrag zuordnen
DELETE /api/emails/:id/assign # Zuordnung aufheben
PATCH /api/emails/:id/read # Gelesen/Ungelesen
POST /api/emails/:id/star # Favorit umschalten
DELETE /api/emails/:id # In Papierkorb
POST /api/emails/:id/restore # Aus Papierkorb wiederherstellen
DELETE /api/emails/:id/permanent # Endgültig löschen
GET /api/emails/:id/attachments/:filename # Anhang herunterladen
# Rechnungen (Invoices)
GET /api/invoices/ecd/:ecdId # Rechnungen für EnergyContractDetails
POST /api/invoices/ecd/:ecdId # Rechnung hinzufügen
PUT /api/invoices/ecd/:ecdId/:invoiceId # Rechnung bearbeiten
DELETE /api/invoices/ecd/:ecdId/:invoiceId # Rechnung löschen
POST /api/invoices/:invoiceId/upload # Rechnungsdokument hochladen
# Cockpit
GET /api/contracts/cockpit # Offene Aufgaben abrufen
Datenbank-Modell
model CachedEmail {
id Int @id @default(autoincrement())
stressfreiEmailId Int
stressfreiEmail StressfreiEmail @relation(...)
folder String // INBOX, SENT
messageId String // RFC 5322 Message-ID
uid Int // IMAP UID
subject String?
fromAddress String
fromName String?
toAddresses String @db.Text // JSON Array
ccAddresses String? @db.Text
receivedAt DateTime
textBody String? @db.LongText
htmlBody String? @db.LongText
hasAttachments Boolean @default(false)
attachmentNames String? @db.Text // JSON Array
contractId Int? // Vertragszuordnung
assignedAt DateTime?
assignedBy Int?
isAutoAssigned Boolean @default(false)
isRead Boolean @default(false)
isStarred Boolean @default(false)
isDeleted Boolean @default(false)
deletedAt DateTime?
@@unique([stressfreiEmailId, messageId, folder])
}
Sicherheit
- Passwort-Verschlüsselung: AES-256-GCM für Mailbox-Passwörter
- Passwort-Reset: Neues Passwort generieren und beim Provider setzen
- Verschlüsselungsmodi: SSL, STARTTLS, oder unverschlüsselt
- Selbstsignierte Zertifikate: Konfigurierbar pro Provider
Berechtigungen
| Aktion | Berechtigung |
|---|---|
| E-Mails lesen | customers:read |
| E-Mails senden, markieren | customers:update |
| Anhänge in Dokumente speichern | customers:update |
| Vertrag zuordnen | contracts:update |
| Löschen, Papierkorb | emails:delete |
Frontend-Komponenten
| Komponente | Beschreibung |
|---|---|
EmailClientTab.tsx |
Haupt-Tab mit Konto-Auswahl und Ordnern |
EmailList.tsx |
E-Mail-Liste mit Aktionen |
EmailDetail.tsx |
E-Mail-Ansicht mit Anhängen |
ComposeEmailModal.tsx |
Neue E-Mail / Antworten |
TrashEmailList.tsx |
Papierkorb-Verwaltung |
AssignToContractModal.tsx |
Vertragszuordnung |
ContractEmailsSection.tsx |
E-Mails in Vertragsansicht |
SaveAttachmentModal.tsx |
Anhänge in Dokumentfelder speichern |
SaveEmailAsPdfModal.tsx |
E-Mail als PDF in Dokumentfelder speichern |
InvoicesSection.tsx |
Rechnungsverwaltung in Vertragsdetails |
Anhänge als Dokumente speichern
E-Mail-Anhänge können direkt in Dokumentfelder des CRM gespeichert werden. Über den blauen Speichern-Button (💾) neben jedem Anhang öffnet sich ein Modal mit allen verfügbaren Zielen.
Verfügbare Ziele
| Kategorie | Dokumentfelder |
|---|---|
| Kunde | Datenschutzerklärung |
| Kunde (Gewerbe) | + Gewerbeanmeldung, Handelsregisterauszug |
| Ausweisdokumente | Dokumentscan (pro Ausweis) |
| Bankkarten | Kartenscan (pro Karte) |
| Vertrag | Kündigungsschreiben, Kündigungsbestätigung, Kündigungsschreiben (Optionen), Kündigungsbestätigung (Optionen) |
Hinweis: Vertragsdokumente sind nur verfügbar, wenn die E-Mail einem Vertrag zugeordnet ist.
Dynamische Konfiguration
Die Dokumentziele werden zentral in backend/src/config/documentTargets.config.ts konfiguriert. Neue Dokumentfelder werden automatisch im Modal angezeigt, ohne Frontend-Änderungen.
// Beispiel: Neues Feld hinzufügen
{
key: 'newDocument',
label: 'Neues Dokument',
field: 'newDocumentPath', // Prisma-Feld
condition: null, // oder 'BUSINESS' für Geschäftskunden
directory: 'new-documents' // Upload-Verzeichnis
}
Warnung bei Überschreiben
Wenn bereits ein Dokument im Zielfeld vorhanden ist, wird eine Warnung angezeigt. Das vorhandene Dokument wird beim Speichern automatisch ersetzt und die alte Datei gelöscht.
Vertragszuordnung aufheben (X-Button)
Der X-Button zum Aufheben der Vertragszuordnung erscheint nur bei manuell zugeordneten E-Mails. E-Mails, die direkt aus dem Vertragskontext gesendet wurden (isAutoAssigned = true), bleiben dauerhaft mit dem Vertrag verknüpft.
| Ansicht | Vertrags-Badge | X-Button sichtbar |
|---|---|---|
| Kundenakte - Posteingang | ✅ | ✅ immer |
| Kundenakte - Gesendet | ✅ | nur manuell zugeordnet |
| Kundenakte - Papierkorb | ✅ | je nach Original-Ordner |
| Vertrag - Posteingang | ✅ | ✅ immer |
| Vertrag - Gesendet | ✅ | nur manuell zugeordnet |
| Vertrag - Papierkorb | ✅ | je nach Original-Ordner |
| Detail-Ansicht (beide) | ✅ | nur manuell zugeordnet |
Hinweis: Bei gesendeten E-Mails gilt:
isAutoAssigned = true: E-Mail wurde direkt aus dem Vertragskontext gesendet → X-Button ausgeblendetisAutoAssigned = false: E-Mail wurde manuell dem Vertrag zugeordnet → X-Button sichtbar
Vertragsbaum in Kundenansicht
In der Kundendetailansicht werden Verträge als Baumstruktur mit Vorgänger-Verknüpfung dargestellt:
▼ GAS-ML781A4FYXU │ Gas │ ACTIVE │ 01.01.2025 - 31.12.2026
└─ GAS-ML24GKR...│ Gas │ EXPIRED│ 05.05.2023 - 05.05.2025 (Vorgänger)
└─ GAS-OLD123 │ Gas │ EXPIRED│ 01.01.2021 - 04.05.2023 (Vorgänger)
▶ MOB-ML77W560A73 │ Mobil│ DRAFT │ 02.01.2024 - 02.01.2026
Funktionsweise:
- Aktuellste Verträge oben - Verträge ohne Nachfolger werden als Wurzelknoten angezeigt
- Standardmäßig eingeklappt - Klick auf ▶ zeigt die Vorgängerkette
- Vorgänger eingerückt - Mit grauem Rand und "(Vorgänger)" Label
- Verknüpfung über
previousContractId- Wird beim Erstellen eines Folgevertrags automatisch gesetzt
Hinweis: In der Hauptvertragsliste (
/contracts) wird weiterhin die flache Ansicht ohne Baumstruktur verwendet.
Lizenz
MIT