From 109f774d620afc37949fa27248c437fb640bc7f8 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Thu, 23 Apr 2026 14:19:02 +0200 Subject: [PATCH] docs: Factory-Defaults Import/Export-Anleitung in READMEs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Haupt-README.md: neuer Abschnitt mit Abgrenzung zu Datenbank-Backup, Schritt- für-Schritt-Anleitung für Export und Import, Idempotenz-Hinweis, Berechtigungen. backend/factory-defaults/README.md: ausführliche Referenz mit Struktur-Beispielen aller JSON-Dateien (Provider, CancellationPeriod, ContractDuration, ContractCategory, PdfTemplate), Teil-Import-Anleitung, Merge-Beispiele. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 117 +++++++++++++ backend/factory-defaults/README.md | 271 +++++++++++++++++++++++++---- 2 files changed, 358 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index a0d8a3a4..1359ec9d 100644 --- a/README.md +++ b/README.md @@ -916,6 +916,123 @@ Folgende Felder werden in Audit-Logs gefiltert: - API-Response wird nicht blockiert - Before/After-Werte über Prisma Middleware +## Factory-Defaults: Stammdaten-Kataloge teilen + +Das **Factory-Defaults**-System erlaubt den Export und Import von +Stammdaten-Katalogen (Anbieter, Tarife, PDF-Vorlagen usw.) zwischen verschiedenen +OpenCRM-Installationen. Es ist bewusst **streng abgegrenzt** zu Datenbank-Backups: + +### Abgrenzung + +| | Factory-Defaults | Datenbank-Backup | +|---|---|---| +| Anbieter, Tarife, Kündigungsfristen, Laufzeiten, Kategorien | ✅ | ✅ | +| PDF-Auftragsvorlagen (inkl. Dateien + Feldzuordnungen) | ✅ | ✅ | +| **Kundendaten, Verträge, Dokumente** | ❌ | ✅ | +| **Emails, SMTP-/IMAP-Zugangsdaten** | ❌ | ✅ | +| **System-Einstellungen, Datenschutzerklärungen, Impressum** | ❌ | ✅ | +| Zwischen verschiedenen Installationen teilbar | ✅ | ❌ (zu firmen-spezifisch) | + +> **Kurz:** Factory-Defaults = reine Kataloge, Backup = alles. + +### Export (Installation A → ZIP) + +1. **Einstellungen** → **Factory-Defaults** öffnen +2. Übersicht prüfen (Anzahl pro Kategorie) +3. Button **„Factory-Defaults exportieren"** klicken +4. ZIP wird als `factory-defaults-YYYY-MM-DD.zip` heruntergeladen + +**ZIP-Struktur:** +``` +factory-defaults-2026-04-23.zip +├── manifest.json # Version + Datum + Counts +├── providers/ +│ └── providers.json # Anbieter inkl. zugehöriger Tarife +├── contract-meta/ +│ ├── cancellation-periods.json # Kündigungsfristen (Code + Beschreibung) +│ ├── contract-durations.json # Laufzeiten (Code + Beschreibung) +│ └── contract-categories.json # Kategorien (Strom, Gas, DSL, ...) +└── pdf-templates/ + ├── pdf-templates.json # Vorlagen-Metadaten + Feldzuordnungen + └── *.pdf # Die eigentlichen PDF-Dateien +``` + +Die ZIP kann an andere Installationen weitergegeben werden +(Partner, Test-System, neue Installation). + +### Import (ZIP → Installation B) + +1. ZIP herunterladen bzw. erhalten +2. Inhalt nach `backend/factory-defaults/` entpacken (Unterordnerstruktur beibehalten) +3. Im Backend-Verzeichnis ausführen: + ```bash + npm run seed:defaults + ``` + +**Beispiel-Output:** +``` +📦 Factory-Defaults werden eingespielt... + + ✓ Anbieter: 7, Tarife: 12 + ✓ Kündigungsfristen: 5 + ✓ Laufzeiten: 4 + ✓ Vertragskategorien: 8 + ✓ PDF-Vorlagen: 3 + +✅ Factory-Defaults erfolgreich eingespielt. +``` + +### Mehrere ZIPs kombinieren + +Du kannst mehrere Exporte in `backend/factory-defaults/` übereinanderlegen – +JSON-Dateien werden automatisch gemerged: + +``` +backend/factory-defaults/ + providers/ + verivox.json # 40 Anbieter aus Verivox-Paket + check24.json # 30 Anbieter aus Check24-Paket + eigene.json # 5 eigene Anbieter +``` + +Das Import-Script liest **alle** `*.json` im jeweiligen Unterordner und merged per +unique Key (letzter Eintrag gewinnt). Duplikate sind also unproblematisch. + +### Idempotenz + +Das Script nutzt ausschließlich Prisma `upsert`: +- **Neue Einträge** werden angelegt +- **Bestehende Einträge** (per unique Key: `name`, `code`) werden aktualisiert +- Nichts wird gelöscht + +Du kannst `npm run seed:defaults` also beliebig oft ausführen, ohne Datenverlust +oder Duplikate. + +### PDF-Dateien beim Import + +Beim Import werden PDF-Vorlagen aus `factory-defaults/pdf-templates/*.pdf` nach +`uploads/pdf-templates/` kopiert und die Pfade in der DB entsprechend gesetzt. +Beim Re-Import wird die alte Datei in `uploads/` entsorgt und durch die neue +ersetzt. + +### Berechtigungen + +| Aktion | Berechtigung | +|--------|--------------| +| Factory-Defaults Vorschau | `settings:read` | +| Factory-Defaults Export | `settings:update` | +| Factory-Defaults Import (CLI) | Server-Zugang (SSH/Shell) | + +### Typischer Einsatzzweck + +- **Neue Installation aufsetzen**: Eine Kollegen-ZIP importieren und sofort mit + gepflegtem Anbieter- und Vorlagenkatalog loslegen +- **Vorlagen-Paket teilen**: Eine ZIP mit nur PDF-Vorlagen weitergeben + (die anderen Ordner einfach aus der ZIP entfernen vor dem Entpacken) +- **Anbieter-Paket teilen**: ZIP mit nur `providers/` weitergeben +- **Versionskontrolle**: Die entpackten JSON-Dateien unter Versionskontrolle + stellen (außerhalb von `backend/factory-defaults/`, da der Ordner gitignored ist) + ## Lizenz MIT diff --git a/backend/factory-defaults/README.md b/backend/factory-defaults/README.md index b48e50e0..d2e52a60 100644 --- a/backend/factory-defaults/README.md +++ b/backend/factory-defaults/README.md @@ -3,43 +3,254 @@ Dieser Ordner enthält **Stammdaten-Kataloge**, die beim Initialisieren einer neuen OpenCRM-Installation automatisch eingespielt werden können. -## Was ist drin? +Siehe auch den Abschnitt „Factory-Defaults" in der Haupt-[README.md](../../README.md) +für einen Gesamtüberblick und die Abgrenzung zum Datenbank-Backup. -- `providers.json` – Anbieter inkl. zugehöriger Tarife -- `cancellation-periods.json` – Kündigungsfristen (z.B. "14 Tage", "1 Monat") -- `contract-durations.json` – Vertragslaufzeiten (z.B. "12 Monate", "24 Monate") -- `contract-categories.json` – Vertragskategorien (Strom, Gas, DSL …) -- `pdf-templates.json` + `pdf-templates/*.pdf` – PDF-Auftragsvorlagen mit Feldzuordnungen +--- -**NICHT enthalten sind Kundendaten, Verträge, Dokumente, E-Mails oder SMTP-Einstellungen.** -Dafür gibt es den separaten Datenbank-Backup-Export. +## Inhalt -## Wie nutze ich das? - -### Export (aus bestehender Installation) -In den CRM-Einstellungen → Factory-Defaults → „Exportieren" → ZIP herunterladen -und den Inhalt in diesen Ordner entpacken. - -### Import -```bash -npm run seed:defaults +``` +backend/factory-defaults/ +├── providers/ +│ └── providers.json # Anbieter inkl. Tarife +├── contract-meta/ +│ ├── cancellation-periods.json # Kündigungsfristen +│ ├── contract-durations.json # Vertragslaufzeiten +│ └── contract-categories.json # Vertragskategorien (Strom/Gas/DSL/...) +└── pdf-templates/ + ├── pdf-templates.json # Metadaten + Feldzuordnungen + └── *.pdf # PDF-Vorlagen-Dateien ``` -Das Script liest alle Dateien aus diesem Ordner, merged mehrere JSONs automatisch -per unique-name und spielt sie per Prisma `upsert` ein. Kann mehrfach ausgeführt -werden (idempotent). +**Was NICHT enthalten ist:** Kundendaten, Verträge, Dokumente, E-Mails, SMTP-Einstellungen, +Datenschutzerklärungen oder andere AppSettings. Dafür gibt es den separaten +**Datenbank-Backup-Export** (Einstellungen → Datenbank & Zurücksetzen). -## Mehrere Export-Dateien mergen +--- -Wenn du mehrere ZIPs entpackst (z.B. Provider-Pakete von verschiedenen Quellen), -kannst du die JSON-Dateien frei umbenennen – das Script liest alle `*.json` im -jeweiligen Unterordner und merged den Inhalt zusammen. +## Export (aus einer bestehenden Installation) + +1. Im CRM als Admin einloggen +2. **Einstellungen** → **Factory-Defaults** +3. Auf **„Factory-Defaults exportieren"** klicken +4. Die heruntergeladene ZIP (`factory-defaults-YYYY-MM-DD.zip`) speichern + +### Inhalt der ZIP -Beispiel: ``` -providers/ - verivox.json - check24.json - eigene.json +factory-defaults-2026-04-23.zip +├── manifest.json # Version, Datum, Einträge pro Kategorie +├── providers/providers.json +├── contract-meta/cancellation-periods.json +├── contract-meta/contract-durations.json +├── contract-meta/contract-categories.json +├── pdf-templates/pdf-templates.json +└── pdf-templates/*.pdf ``` -Alle drei werden eingespielt, gleiche Anbieter werden über den `name` gemerged. + +Die ZIP kann an andere Installationen weitergegeben werden – z.B. für Test-Systeme, +neue Installationen oder Partner-Setups. + +--- + +## Import (in eine andere Installation) + +### Schritt-für-Schritt + +1. **ZIP herunterladen** (aus einer Export-Installation oder von einer Vorlage) +2. **Inhalt entpacken** in diesen Ordner (`backend/factory-defaults/`), + Unterordnerstruktur beibehalten +3. **Script ausführen:** + ```bash + cd backend + npm run seed:defaults + ``` +4. **Ausgabe prüfen** – bei Erfolg: + ``` + 📦 Factory-Defaults werden eingespielt... + + ✓ Anbieter: 7, Tarife: 12 + ✓ Kündigungsfristen: 5 + ✓ Laufzeiten: 4 + ✓ Vertragskategorien: 8 + ✓ PDF-Vorlagen: 3 + + ✅ Factory-Defaults erfolgreich eingespielt. + ``` + +### Idempotenz + +Das Script nutzt ausschließlich `upsert`: +- **Neue Einträge** werden angelegt +- **Bestehende Einträge** (match per unique key: `name` / `code`) werden aktualisiert +- Nichts wird gelöscht + +Du kannst `npm run seed:defaults` **beliebig oft ausführen** – kein Datenverlust, +keine Duplikate. + +### Was passiert mit den PDF-Dateien? + +Die PDFs aus `pdf-templates/*.pdf` werden beim Import nach +`backend/uploads/pdf-templates/` kopiert (mit eindeutigem Zeitstempel-Suffix). +Die Pfade in der DB werden automatisch auf die neue Kopie gesetzt. + +Beim Re-Import einer bereits existierenden Vorlage wird die alte Datei in `uploads/` +entsorgt und durch die neue ersetzt. + +--- + +## Mehrere Exporte mergen + +Wenn du mehrere ZIPs hast (z.B. "Verivox-Paket", "Check24-Paket", "eigene"), kannst +du die JSON-Dateien frei benennen und in einen Ordner legen. Das Script liest +alle `*.json` im jeweiligen Unterordner und merged den Inhalt zusammen. + +**Beispiel:** +``` +backend/factory-defaults/ + providers/ + verivox.json # 40 Anbieter aus dem Verivox-Paket + check24.json # 30 Anbieter aus dem Check24-Paket + eigene.json # 5 eigene, firmenspezifische Anbieter + contract-meta/ + standard.json # Standard-Kündigungsfristen + Laufzeiten + Kategorien + pdf-templates/ + ewe-paket.json # EWE-Vorlage + moon-paket.json # Moon-Vorlage + ewe-auftrag.pdf + moon-formular.pdf +``` + +Bei gleichem Unique-Key (z.B. `providers.name: "EWE"` in mehreren Dateien) gewinnt +der zuletzt gelesene Eintrag. + +--- + +## Teil-Import (nur Kategorien auswählen) + +Falls du nur einen Teil importieren willst (z.B. nur PDF-Vorlagen ohne Anbieter), +lösche oder verschiebe einfach die nicht gewünschten JSON-Dateien, bevor du das +Script ausführst. Das Script überspringt Kategorien ohne Dateien ohne Fehler. + +**Beispiel: nur PDF-Vorlagen:** +``` +backend/factory-defaults/ + pdf-templates/ # nur diesen Ordner behalten + pdf-templates.json + *.pdf +``` + +--- + +## Struktur-Referenz (für manuelle Pflege) + +### `providers/providers.json` + +Array von Providern, jeweils inkl. zugehöriger Tarife: + +```json +[ + { + "name": "EWE", + "portalUrl": "https://www.ewe.de/privatkunden/meine-ewe/login", + "usernameFieldName": "username", + "passwordFieldName": "password", + "isActive": true, + "tariffs": [ + { "name": "EWE Zuhause Strom", "isActive": true }, + { "name": "EWE Zuhause Gas", "isActive": true } + ] + } +] +``` + +**Unique Key:** `name` + +### `contract-meta/cancellation-periods.json` + +```json +[ + { "code": "14T", "description": "14 Tage", "isActive": true }, + { "code": "1M", "description": "1 Monat", "isActive": true }, + { "code": "3M", "description": "3 Monate", "isActive": true } +] +``` + +**Unique Key:** `code` + +### `contract-meta/contract-durations.json` + +```json +[ + { "code": "12M", "description": "12 Monate", "isActive": true }, + { "code": "24M", "description": "24 Monate", "isActive": true } +] +``` + +**Unique Key:** `code` + +### `contract-meta/contract-categories.json` + +```json +[ + { + "code": "ELECTRICITY", + "name": "Strom", + "icon": "Zap", + "color": "#FFC107", + "sortOrder": 1, + "isActive": true + } +] +``` + +**Unique Key:** `code` + +### `pdf-templates/pdf-templates.json` + +```json +[ + { + "name": "EWE Auftragsformular", + "description": "Auftrag für Glasfaser-Anschluss", + "providerName": "EWE", + "originalName": "EWE-Auftrag-Privat.pdf", + "fieldMapping": { + "Vorname": "customer.firstName", + "Nachname": "customer.lastName", + "Strasse": "address.streetFull", + "PLZ": "address.postalCode", + "Ort": "address.city" + }, + "phoneFieldPrefix": "Rufnummer", + "maxPhoneFields": 8, + "isActive": true, + "pdfFilename": "EWE_Auftragsformular.pdf" + } +] +``` + +**Unique Key:** `name` +**Wichtig:** Die `pdfFilename` muss zu einer PDF-Datei im selben Ordner passen. + +--- + +## Berechtigungen + +| Aktion | Berechtigung | +|--------|--------------| +| Factory-Defaults Vorschau | `settings:read` | +| Factory-Defaults Export (UI) | `settings:update` | +| Factory-Defaults Import (CLI) | Server-Zugang (SSH/Shell) | + +--- + +## Git & Versionierung + +Dieser Ordner ist in `.gitignore` eingetragen (außer `.gitkeep` und `README.md`), +damit firmen-spezifische Exporte nicht versehentlich ins Repo kommen. + +Wenn du **öffentlich teilbare Katalog-Pakete** versionieren willst, lege sie +außerhalb dieses Ordners ab (z.B. in einem eigenen Repository) und kopiere sie +bei Bedarf hierher.