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
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue