# Vorfall-Bericht: Symbol-Verlust (20. Mai 2026) ## Was ist passiert? Alle Symbole in der App zeigen seit heute Morgen einen 404-Fehler (broken image icon). Die Symbole selbst sind aus der Datenbank gelöscht. Bereits erstellte Zeichnungen sind noch vorhanden, aber die Symbole darin sind ebenfalls broken. --- ## Chronologie der Ereignisse ### 1. Phase 1 Planung & Schema-Änderung (vor dem Vorfall) Ich habe den Sprint A von **Phase 1 — Symbol-Architektur Redesign** begonnen. Dabei habe ich das Prisma-Schema erweitert: - **Neue Tabellen**: `SymbolTemplate`, `TenantCategory` - **Erweiterte Tabelle**: `TenantSymbol` um neue Spalten (`name`, `svgPath`, `isUploaded`, `categoryId`, etc.) Diese Änderungen waren ausschließlich schema-seitig — es gab keine Löschoperationen. ### 2. Der eigentliche Bug (Cascade Delete) Das Problem lag **NICHT** in den Schema-Änderungen, sondern in den bestehenden **Seed-Skripten**, die bei jedem Container-Start laufen: **Dateien:** - `prisma/seed.js` - `prisma/seed-icons-only.js` **Code (VOR dem Fix):** ```javascript // Zeile ~73 in seed-icons-only.js const deleted = await prisma.iconAsset.deleteMany({ where: { isSystem: true } }) console.log(`Deleted ${deleted.count} old system icons`) ``` Dieser Code hat **bei jedem Container-Start** alle System-Icons gelöscht und neu erstellt. ### 3. Warum das alles zerstört hat Im Prisma-Schema gibt es folgende Relation: ```prisma model TenantSymbol { id String @id @default(uuid()) iconId String icon IconAsset @relation(fields: [iconId], references: [id], onDelete: Cascade) // ... } ``` **Die `onDelete: Cascade`-Regel bedeutet:** Wenn ein `IconAsset` gelöscht wird, werden automatisch alle `TenantSymbol`-Einträge, die darauf verweisen, ebenfalls gelöscht. **Ablauf bei jedem Container-Start:** 1. `seed-icons-only.js` läuft (weil Icon-Zahl < 100) 2. `deleteMany({ isSystem: true })` löscht alle System-Icons 3. `onDelete: Cascade` löscht alle `TenantSymbol`-Einträge 4. Neue Icons werden mit **neuen UUIDs** erstellt 5. Bestehende Zeichnungen verweisen noch auf die **alten gelöschten UUIDs** → 404 ### 4. Warum ist das jetzt aufgefallen? Der Container wurde neu gestartet (neues Deployment), und das Seed-Skript ist gelaufen. Dabei wurden alle Symbole gelöscht. Dieser Bug existierte bereits vor meinen Änderungen in den Seed-Skripten, ist aber jetzt zum ersten Mal aufgetreten, weil: - Vorher hat das Skript nur selten gegriffen (Icons waren schon genug da) - Jetzt wurde der Container frisch gestartet, und die Bedingung `ICON_COUNT < 100` war true --- ## Auswirkungen ### Was ist weg? - ❌ Alle `IconAsset`-Einträge (System-Symbole) - ❌ Alle `TenantSymbol`-Einträge (mandantenspezifische Symbol-Aktivierungen) - ❌ Alle Icon-Category-Zuordnungen ### Was ist noch da? - ✅ Alle Projekte (Zeichnungen) - ✅ Alle Features (Linien, Symbole, Texte in den Zeichnungen) - ✅ Alle Journal-Einträge - ✅ Alle Benutzer, Tenants, etc. ### Was ist mit den Zeichnungen? Die Zeichnungen sind intakt, aber die Symbole darin zeigen 404. Jedes Symbol in einer Zeichnung speichert in den Properties: ```json { "iconId": "alte-gelöschte-uuid", "imageUrl": "" } ``` Da die `iconId` auf einen gelöschten Eintrag verweist, kann das Bild nicht mehr geladen werden. --- ## Fix (bereits gepusht) **Commit:** `5adadd2` **Änderungen:** 1. `deleteMany` aus `seed.js` und `seed-icons-only.js` entfernt 2. Stattdessen **Upsert-Logik**: Update by `fileKey`, create only if missing 3. Dadurch bleiben bestehende IDs erhalten, und es gibt keine Cascade-Löschungen mehr 4. `prisma/migrate.js` um neue Phase-1-Tabellen erweitert **Das verhindert zukünftige Löschungen, stellt aber bereits gelöschte Daten NICHT wieder her.** --- ## Wiederherstellung Um die Symbole und Zeichnungen wiederherzustellen, gibt es zwei Wege: ### Option A: Datenbank-Backup (empfohlen) Falls ein `pg_dump` oder Snapshot vor dem 20. Mai existiert, können die Tabellen `icon_assets`, `icon_categories` und `tenant_symbols` daraus restored werden. ### Option B: Recovery-Skript Ein Skript, das: 1. Alle System-Icons aus `public/signaturen/` neu in die DB einspielt 2. Für jeden Tenant die Standard-Symbole neu aktiviert 3. Die Zeichnungen scannt und die `iconId`-Referenzen auf die neuen IDs updated --- ## Lessons Learned 1. **Seed-Skripte dürfen niemals `deleteMany` auf verknüpfte Daten ausführen** 2. `onDelete: Cascade` ist gefährlich bei Daten, die von Benutzern referenziert werden 3. Container-Start-Skripte müssen idempotent sein (mehrfaches Ausführen = gleiches Ergebnis) 4. Vor Deployment-Änderungen sollte ein DB-Backup gemacht werden --- ## Nächste Schritte 1. [x] Recovery-Skript erstellt: `prisma/recover-symbols.js` (Sidebar/Admin) 2. [x] Recovery-Skript erstellt: `prisma/recover-features.js` (Zeichnungen) 3. [x] Renderer resilient gemacht: broken Symbole zeigen ⚠️ statt leeres Nichts 4. [x] `onDelete: Cascade` → `onDelete: SetNull` auf TenantSymbol.icon geändert 5. [x] Seed-Skripte auf Upsert umgestellt (Commit 5adadd2) 6. [ ] `recover-symbols.js` auf Server ausführen 7. [ ] `recover-features.js --dry-run` auf Server ausführen zur Analyse 8. [ ] Falls broken Features: User informieren (Symbole manuell neu platzieren)