Files
Lageplan/docs/backup-und-seeding.md
Pepe Ziberi 08a66095e6
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 17m48s
chore(seed/docs): production safety, scripts audit, documentation
2026-05-20 17:32:28 +02:00

7.7 KiB

Backup & Seeding — Betriebsnotiz Lageplan

Stand: 2026-05-20 Autor: Automatisch generiert nach Produktionsvorfall

Inhalt

  1. Wichtige Regeln
  2. Backup-Strategie
  3. Seed-Skripte
  4. Post-Deploy Prüfung
  5. Notfall-Recovery
  6. Docker-Build Hinweise

Wichtige Regeln

Nie löschen

  • Keine deleteMany(), DELETE FROM, TRUNCATE oder Cascade-Resets in Production
  • Nie direkt in icon_assets, icon_categories, tenant_symbols, features, projects löschen
  • Alle Seed-Skripte müssen idempotent sein (upsert statt delete + create)
  • Vor jedem Seed/Repair in Production: Databasus-Backup erstellen

Databasus Backup

  • Databasus ist als GUI-Backup eingerichtet
  • Backups werden gespeichert unter: /volume1/docker/backups/databasus
  • Nie das Docker-Volume unter /volume1/@docker als einzige Backup-Strategie verwenden

Container-Informationen

Service Container-Name
PostgreSQL DB lageplan-db-1
Web App lageplan-web-1
DB-Name lageplan
DB-User lageplan

Backup-Strategie

Automatisch (Databasus)

  1. Databasus GUI öffnen
  2. Datenbank lageplan auswählen
  3. "Backup Now" klicken
  4. Backup wird unter /volume1/docker/backups/databasus abgelegt

Manuell (pg_dump)

# In der NAS-Shell (oder im DB-Container)
docker exec lageplan-db-1 pg_dump -U lageplan -d lageplan \
  --no-owner --no-privileges \
  > /volume1/docker/backups/databasus/lageplan-manual-$(date +%Y%m%d-%H%M%S).sql

Wiederherstellen

# 1. Backup-Datei prüfen
ls -la /volume1/docker/backups/databasus/

# 2. App stoppen
docker stop lageplan-web-1

# 3. DB zurückspielen (ACHTUNG: überschreibt aktuelle Daten!)
docker exec -i lageplan-db-1 psql -U lageplan -d lageplan \
  < /volume1/docker/backups/databasus/lageplan-backup-YYYYmmdd-HHMMSS.sql

# 4. App starten
docker start lageplan-web-1

Seed-Skripte

Übersicht

Skript Zweck Sicherheit Aufruf
prisma/seed.js Vollständiger Seed (Tenant, Users, Icons, HoseTypes, Demo-Projekt) Idempotent, nur upsert npm run db:seed oder node prisma/seed.js
prisma/seed-icons-only.js Nur Icons aus public/signaturen/*.svg Idempotent, nur upsert npm run db:seed:icons oder node prisma/seed-icons-only.js
prisma/seed.ts Legacy-TypeScript-Seed (korrigiert, aber nicht der Primary) Korrigiert Nicht direkt aufrufen
prisma/seed-symbol-templates.ts Erstellt SymbolTemplate-Einträge Nur findFirst + create (skip if exists) npx tsx prisma/seed-symbol-templates.ts
prisma/migrate-tenant-symbols.ts Migriert bestehende TenantSymbol zu neuem Schema Nur findFirst, create, update npx tsx prisma/migrate-tenant-symbols.ts
prisma/recover-symbols.js Recovery: Icons + TenantSymbols wiederherstellen Dry-Run/Apply Modus npm run recover:symbols:dry-run / npm run recover:symbols:apply
prisma/repair-features.js Repariert kaputte iconId-Referenzen in Features Dry-Run/Apply Modus + Backup npm run repair:features:dry-run / npm run repair:features:apply
prisma/migrate.js DB-Migrationen (Raw SQL, idempotent) Keine Deletes auf User-Daten Wird automatisch beim Container-Start ausgeführt

Empfohlene Seed-Strategie

  1. Neue Umgebung (erstmalig):

    node prisma/seed.js
    
  2. Nur Icons aktualisieren (z.B. nach SVG-Update):

    node prisma/seed-icons-only.js
    
  3. Recovery nach Icon-Verlust:

    # 1. Erst Databasus-Backup erstellen!
    # 2. Dann:
    node prisma/recover-symbols.js --dry-run   # Analyse
    node prisma/recover-symbols.js --apply     # Anwenden
    

Post-Deploy Prüfung

1. SVG-Dateien im Container

docker exec -it lageplan-web-1 sh -c 'find /app/public/signaturen -type f -name "*.svg" | wc -l'

Erwartung: ca. 117

2. Icons seeden

docker exec -it lageplan-web-1 node prisma/seed-icons-only.js

Erwartung:

✅ 10 icon categories upserted
✅ FKS Signaturen: X created, Y updated (117 total SVGs)

3. Datenbank-Prüfung

docker exec -it lageplan-db-1 psql -U lageplan -d lageplan -c "
SELECT 'icon_categories' AS table_name, COUNT(*) AS count FROM icon_categories
UNION ALL
SELECT 'icon_assets' AS table_name, COUNT(*) AS count FROM icon_assets
UNION ALL
SELECT 'tenant_symbols' AS table_name, COUNT(*) AS count FROM tenant_symbols
UNION ALL
SELECT 'features' AS table_name, COUNT(*) AS count FROM features
UNION ALL
SELECT 'projects' AS table_name, COUNT(*) AS count FROM projects;
"

4. Logs prüfen

docker logs --tail=100 lageplan-web-1

Keine der folgenden Fehler sollen auftreten:

  • 404 für /signaturen/*.svg
  • Prisma error wegen tenant_symbols.categoryId
  • Seed failed

Notfall-Recovery

Szenario: Symbole sind verschwunden (404)

Ursache: IconAsset-Einträge wurden gelöscht (z.B. durch altes Seed-Skript mit deleteMany)

Lösung:

# 1. Backup erstellen (Databasus GUI oder pg_dump)

# 2. Container-Status prüfen
docker exec -it lageplan-web-1 sh -c 'ls -la /app/public/signaturen/ | head -5'
# → Sollte SVG-Dateien anzeigen

# 3. Icons neu seeden (idempotent, sicher)
docker exec -it lageplan-web-1 node prisma/seed-icons-only.js

# 4. Tenant-Symbols wiederherstellen (falls auch gelöscht)
docker exec -it lageplan-web-1 node prisma/recover-symbols.js --dry-run
docker exec -it lageplan-web-1 node prisma/recover-symbols.js --apply

# 5. Prüfen
docker exec -it lageplan-web-1 node -e "
const {PrismaClient} = require('@prisma/client');
const p = new PrismaClient();
p.iconAsset.count({where:{isSystem:true}}).then(c=>console.log('System-Icons:',c));
p.tenantSymbol.count().then(c=>console.log('TenantSymbols:',c));
"

Szenario: Features haben kaputte iconId-Referenzen

Ursache: Alte iconId-UUIDs in Feature.properties zeigen auf gelöschte IconAssets

Lösung:

# 1. Dry-Run: Analyse
docker exec -it lageplan-web-1 node prisma/repair-features.js --dry-run

# 2. Apply: Reparatur (erstellt automatisch JSON-Backup)
docker exec -it lageplan-web-1 node prisma/repair-features.js --apply

Docker-Build Hinweise

public/signaturen muss im Image sein

  • public/signaturen/*.svg muss im Git-Index sein (.gitignore erlaubt es explizit)
  • .dockerignore darf public/signaturen/ nicht ausschliessen
  • Dockerfile kopiert public/ in die Runtime-Stage:
    COPY --from=builder /app/public ./public
    

Next.js standalone

  • next.config.js hat output: 'standalone'
  • Der Build erzeugt .next/standalone/ (minimaler Server)
  • public/ wird explizit in die Runtime-Stage kopiert

Multi-Stage Build

  1. deps: npm ci (nur Dependencies)
  2. builder: npm run build (inkl. Prisma Generate)
  3. runner: Runtime-Image mit public/, .next/standalone/, Prisma-Client

Änderungshistorie

Datum Änderung
2026-05-20 .gitignore korrigiert: Signaturen//Signaturen/ (Root-only), public/signaturen/*.svg erlaubt
2026-05-20 117 SVG-Dateien force-added zum Git-Index
2026-05-20 .dockerignore korrigiert: Signaturen/Signaturen/
2026-05-20 package.json: db:seed zeigt jetzt auf prisma/seed.js statt broken seed.ts
2026-05-20 seed.ts korrigiert: Role-Enums + stabile IDs für iconCategory.upsert
2026-05-20 Alle Seed-Skripte auf deleteMany-Freiheit geprüft
2026-05-20 Dokumentation docs/backup-und-seeding.md erstellt