docs: Factory-Defaults Import/Export-Anleitung in READMEs
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) <noreply@anthropic.com>
This commit is contained in:
parent
60dc98e265
commit
109f774d62
117
README.md
117
README.md
|
|
@ -916,6 +916,123 @@ Folgende Felder werden in Audit-Logs gefiltert:
|
||||||
- API-Response wird nicht blockiert
|
- API-Response wird nicht blockiert
|
||||||
- Before/After-Werte über Prisma Middleware
|
- 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
|
## Lizenz
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|
|
||||||
|
|
@ -3,43 +3,254 @@
|
||||||
Dieser Ordner enthält **Stammdaten-Kataloge**, die beim Initialisieren einer neuen
|
Dieser Ordner enthält **Stammdaten-Kataloge**, die beim Initialisieren einer neuen
|
||||||
OpenCRM-Installation automatisch eingespielt werden können.
|
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.**
|
## Inhalt
|
||||||
Dafür gibt es den separaten Datenbank-Backup-Export.
|
|
||||||
|
|
||||||
## Wie nutze ich das?
|
```
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
### Export (aus bestehender Installation)
|
**Was NICHT enthalten ist:** Kundendaten, Verträge, Dokumente, E-Mails, SMTP-Einstellungen,
|
||||||
In den CRM-Einstellungen → Factory-Defaults → „Exportieren" → ZIP herunterladen
|
Datenschutzerklärungen oder andere AppSettings. Dafür gibt es den separaten
|
||||||
und den Inhalt in diesen Ordner entpacken.
|
**Datenbank-Backup-Export** (Einstellungen → Datenbank & Zurücksetzen).
|
||||||
|
|
||||||
### Import
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
```
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
```bash
|
||||||
|
cd backend
|
||||||
npm run seed:defaults
|
npm run seed:defaults
|
||||||
```
|
```
|
||||||
|
4. **Ausgabe prüfen** – bei Erfolg:
|
||||||
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).
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
Beispiel:
|
|
||||||
```
|
```
|
||||||
|
📦 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/
|
providers/
|
||||||
verivox.json
|
verivox.json # 40 Anbieter aus dem Verivox-Paket
|
||||||
check24.json
|
check24.json # 30 Anbieter aus dem Check24-Paket
|
||||||
eigene.json
|
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
|
||||||
```
|
```
|
||||||
Alle drei werden eingespielt, gleiche Anbieter werden über den `name` gemerged.
|
|
||||||
|
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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue