Files
Hosting-Backoffice/reviews/claude-critical-risks.md
2026-05-18 04:37:23 +00:00

313 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kritische Risiken und Refactoring-Gefahren
**Stand:** 15. Mai 2026
**Reviewer:** Claude
**Bezug:** Hosting-Backoffice v0.1 (vollständiger Basisbestand)
Jedes Risiko ist mit Schweregrad, Zeitpunkt und konkreter Empfehlung markiert.
**Legende:**
- Schweregrad: `LOW` / `MEDIUM` / `HIGH` / `CRITICAL`
- Zeitpunkt: `NOW` (vor Codebeginn) / `V1` / `V2` / `V3` / `LATER`
---
## R-01 — Mandantenfähigkeit ist Absichtserklärung, kein Design
- **Schweregrad:** `CRITICAL`
- **Zeitpunkt:** `NOW`
- **Problem:** Die Multi-Tenancy-Strategie listet Ziele, keinen Mechanismus. V1 läuft als Single-Tenant mit zwei ungeklärten ID-Spalten (`tenant_id`, `organisation_id`). Wenn V1 ohne Tenant-Scope-Enforcement deployt wird, ist V2/V3-Reseller-Fähigkeit ein Komplett-Refactor jeder Query, Policy, Job-Payload, Cache-Key und Webhook-Definition.
- **Empfehlung:** Tenancy-Modell jetzt entscheiden und in ADR festschreiben. Vorschlag: Shared Database, `tenant_id`-Scope, Postgres Row-Level Security als zweite Verteidigungsschicht. Eloquent Global Scope von Tag 1 auf allen mandantenscoped Modellen. Statische Analyse oder Runtime-Assertion in CI gegen ungescopte Queries. `organisation_id` vs. `tenant_id` mit ER-Modell klären oder eine der beiden Spalten streichen.
---
## R-02 — Anbieterlogik im Core-Datenmodell bricht das eigene Adapter-Pattern
- **Schweregrad:** `CRITICAL`
- **Zeitpunkt:** `NOW`
- **Problem:** `Server.KeyHelp-Referenz` und `Rechnung.externes System` stehen im Core-Datenmodell. Das widerspricht direkt dem Integration-Adapter-Pattern, das „Core kennt keine direkte Anbieterlogik" als Grundprinzip formuliert. Sobald V1 mit dieser Schema-Form deployt wird, ist das Adapter-Pattern in der Praxis tot, und jedes neue Hostingpanel braucht Core-Schema-Änderungen.
- **Empfehlung:** Vor dem ersten Migration-File ein generisches External-Reference-Pattern einführen, z. B. Tabelle `external_references(id, owner_type, owner_id, adapter_id, external_id, metadata, last_synced_at)`. Im Core nur diese Tabelle, keine anbieter-spezifischen Felder.
---
## R-03 — Daten im Core, Logik in Modulen (Billing-Anti-Pattern)
- **Schweregrad:** `CRITICAL`
- **Zeitpunkt:** `NOW`
- **Problem:** `Rechnung` und `Zahlung` sind im Core-Datenmodell. Billing-Logik ist als Integrationsmodul gedacht (Lexware, Invoice Ninja). Konsequenz: Module schreiben in Core-Tabellen, kennen das Core-Schema, jede Schema-Änderung im Core bricht potenziell mehrere Module. Genau die Konstruktion, in der „modularer Aufbau" zum erweiterten Monolithen wird.
- **Empfehlung:** Billing als eigene Bounded-Context-Domäne (Service-Modul) etablieren. Core kennt höchstens `InvoiceReference` mit Adapter-ID und externer ID, nicht aber `Rechnung.Betrag`. Eigenes Datenmodell pro Modul, Kommunikation per definierten Service-Contract.
---
## R-04 — Modulstruktur und Modul-Dokumente widersprechen sich
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** `module-structure-v0.1.md` listet weder Billing noch Customer Portal, obwohl beide eigene Modul-Beschreibungen haben. KeyHelp und Registrar sind als Modul-Doks vorhanden einer ist Integrationsmodul, der andere möglicherweise eine Mischform. Solange diese drei verschiedenen „Wahrheiten" parallel existieren, gibt es kein gemeinsames Architekturverständnis.
- **Empfehlung:** Modulstruktur als alleinige Wahrheit etablieren. Jedes Modul-Dokument muss in der Modul-Struktur gelistet sein, oder es existiert nicht. Inkonsistenzen vor Codebeginn beheben.
---
## R-05 — Secrets-Management vollständig undefiniert
- **Schweregrad:** `CRITICAL`
- **Zeitpunkt:** `NOW`
- **Problem:** `Registrar-Account.Zugangsdaten/API-Referenzen` impliziert Credentials im Datenmodell. Im gesamten Bestand findet sich kein Wort zu Vault, Verschlüsselung, Key Rotation, KMS, HSM oder Mandanten-Isolation der Schlüssel. Bei kompromittierter DB hätte ein Angreifer Zugriff auf Registrar-Accounts aller Mandanten das wäre ein Vorfall mit Branchenrelevanz.
- **Empfehlung:** Externes Secret-Management (HashiCorp Vault, AWS Secrets Manager, Bitwarden Secrets Manager) oder mindestens Envelope-Encryption mit pro-Mandant abgeleiteten Schlüsseln und externem KMS. Datenmodell darf keine Credentials enthalten, nur Referenzen in den Vault. Vor V1-Codebeginn entscheiden.
---
## R-06 — Core ist zu groß, Monolith-Pfad voraussehbar
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** Core enthält 13 Bereiche, davon mindestens 6 mit eigener Geschäftslogik (Domains, Hostingpakete, Server, Dokumente, Notifications, Produkte). Diese Konstellation produziert einen Bounded Context für die gesamte Anwendung und macht den Modul-Ansatz architektonisch wirkungslos.
- **Empfehlung:** Core auf Identity, RBAC, Audit, Settings, Module-Registry, Event-Routing, Tenant-Scope reduzieren. Domains, Hostingpakete, Server, Dokumente, Notifications-Channels in eigene Service-Module auslagern. Adapter-Pattern und Modul-Contract als verbindliche Grenze.
---
## R-07 — GoBD-Verantwortlichkeit nicht entschieden
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `V1`
- **Problem:** `Rechnung.externes System` impliziert, dass Lexware/Invoice Ninja der Beleg-Originalspeicher ist. Die GoBD-Archive-Strategie sagt aber gleichzeitig „PDFs archivieren, Hashes speichern, Audit-Logs schreiben" das klingt nach lokalem Originalspeicher. Wenn Hosting-Backoffice der Originalspeicher ist, gelten harte GoBD-Anforderungen (unveränderbare Belege, lückenlose Nummernkreise pro Mandant, 10-Jahres-Retention, Z3-Export). Aktuell ist das nicht entschieden.
- **Empfehlung:** Klärungs-ADR. Empfehlung: Lexware/Invoice Ninja als Original, Hosting-Backoffice als Referenz-/Spiegel-System mit Archivkopie und Hash. Audit-Logs intern, aber keine GoBD-Originalrolle.
---
## R-08 — DSGVO-Löschung vs. GoBD-Retention nicht modelliert
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `V1`
- **Problem:** Endkunde verlangt Löschung nach DSGVO Art. 17, gleichzeitig müssen Rechnungsbelege 10 Jahre aufbewahrt werden. Diese Spannung muss technisch abgebildet sein. Im aktuellen Datenmodell gibt es weder Soft-Delete-Modell noch Pseudonymisierungs-Strategie noch Tombstone-Mechanismus.
- **Empfehlung:** Tombstone- und Pseudonymisierungs-Modell entwerfen. Pflicht: Trennung von Personen-Stammdaten (löschbar/pseudonymisierbar) und Beleg-Inhalt (retentionspflichtig). Konkrete Felder definieren, was bei „Löschung" mit der Person passiert (z. B. `Anonymized<UUID>` als Name).
---
## R-09 — API-Auth-Strategie unentschieden
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** „Tokenbasiert, später OAuth/Sanctum möglich" mischt Konzeptebenen. Das WordPress-Plugin und das Customer Portal können nicht entwickelt werden, bevor entschieden ist, welcher Auth-Mechanismus für welchen Client-Typ gilt.
- **Empfehlung:** ADR. Vorschlag für V1: Sanctum Personal Access Tokens (M2M, einfache Clients) plus Sanctum SPA-Mode (eigenes Frontend, falls vorhanden). V2: Passport/OAuth2 für WordPress-Plugin und Drittanbieter-Apps.
---
## R-10 — Datenbankwahl offen
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** „MariaDB oder PostgreSQL" als Nicht-Entscheidung. Postgres bietet Row-Level Security (relevant für Tenancy als Defense-in-Depth), JSONB mit Indizes, transaktionales DDL, partielle Indizes. MariaDB nicht in gleichem Umfang. „Später entscheiden" ist faktisch eine Festlegung auf den kleinsten gemeinsamen Nenner.
- **Empfehlung:** ADR. Vorschlag: PostgreSQL 15+, mit expliziter Begründung an Tenancy-, Audit-, JSON- und Performance-Anforderungen.
---
## R-11 — KI-Modul in V1 birgt DSGVO-Sprengstoff
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW` (Scope-Entscheidung) / `V2` (technisch)
- **Problem:** KI-Funktionen verarbeiten potenziell personenbezogene Support-Ticket-Inhalte über US-Provider, was Auftragsverarbeitungsvertrag, SCC, Drittlandtransfer-Risikobewertung, Subprozessor-Transparenz und Endkunden-Information erfordert. Für V1 (35 Pilotkunden, „Ordnung schaffen") ist das Aufwand ohne Geschäftswert.
- **Empfehlung:** KI-Modul aus V1 entfernen, in V2 wieder aufnehmen. Bis dahin: Subprozessor-Strategie, DPA-Vorlage, Datenklassifikation und Mensch-im-Loop-Konzept ausarbeiten.
---
## R-12 — SEPA-Lastschrift ohne SEPA-Modell
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** Payment Policy listet Lastschrift als V1-Zahlungsart. SEPA-Lastschrift erfordert Mandate (UMR, Mandatsdatum, Mandatstext), Pre-Notification (mind. 1 Tag), IBAN-Speicherung (personenbezogen + sicherheitsrelevant), Mandatsänderungs-Historie. Davon ist nichts modelliert.
- **Empfehlung:** Entweder Lastschrift aus V1 entfernen, oder SEPA-Mandat-Modell vollständig spezifizieren (eigene Tabellen, Statusmaschine, Verschlüsselung der IBAN, Audit-Log).
---
## R-13 — V1-Scope intern widersprüchlich
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** Mehrere Dokumente erzählen unterschiedliche V1-Geschichten: KI in V1 vs. V2, Customer Portal in V1 vs. nicht in MVP, Kundenzahl 1500 vs. 150. Das macht den V1-Scope unentscheidbar und damit das Erfolgsversprechen unprüfbar.
- **Empfehlung:** V1-Scope-Liste als einzelne Quelle der Wahrheit etablieren. Empfehlung: KI raus, Customer Portal raus oder mit reduziertem Umfang, Kundenzahl auf 150 festgelegt. Alle Dokumente daran ausrichten.
---
## R-14 — Audit-Log-Unveränderbarkeit als Wunsch, kein Mechanismus
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** „Logs dürfen nicht manipulierbar sein" steht als Anforderung, aber kein Mechanismus ist beschrieben. Eine normale DB-Tabelle ist manipulierbar.
- **Empfehlung:** Mindestens Append-only-Tabelle ohne UPDATE/DELETE-Berechtigung des App-Users, Hash-Chain der Einträge, regelmäßiger Export in WORM-Storage oder externes Audit-Sink. ADR.
---
## R-15 — Tenant-Offboarding und Datenexport nicht definiert
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `V2`
- **Problem:** Wenn ein Mandant das System verlässt, muss er DSGVO-konform seine Daten erhalten (Datenportabilität) und der Plattformbetreiber muss löschen. Kein Konzept im Bestand.
- **Empfehlung:** Tenant-Lifecycle-Domäne entwerfen. Export-Format: maschinenlesbar (JSON Lines, oder pro-Tenant DB-Dump bei DB-per-Tenant-Modell). Aufbewahrungspflichten der GoBD beachten.
---
## R-16 — Steuer-/MwSt-Logik komplett fehlend
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `V1`
- **Problem:** Im gesamten Bestand kein Wort zu MwSt-Sätzen, OSS (One-Stop-Shop für EU-B2C), Reverse Charge B2B EU, oder MwSt-Befreiungen. Eine Rechnungs-Software ohne Steuermodell ist nicht produktiv einsetzbar.
- **Empfehlung:** Minimal-Modell für V1: deutscher Standardfall (19%/7%/0%), B2B/B2C-Flag pro Kunde, Erweiterbarkeit für OSS in V2. ADR + Daten-Modell-Update.
---
## R-17 — Reseller-Hierarchie V3 ohne V1-Vorbereitung
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `NOW`
- **Problem:** V3 verspricht „Resellerstrukturen" und „tiefere Mandantenfähigkeit". Das setzt mindestens dreistufige Hierarchie (Plattform → Reseller → Endkunde) voraus. V1 plant zweistufig oder einstufig (siehe R-01). Ohne saubere Hierarchie-Definition heute wird V3 ein Modellbruch.
- **Empfehlung:** Hierarchie als Datenmodell-Entscheidung heute festlegen (selbst wenn V1 nur eine Ebene aktiv nutzt). ADR. Tabelle `tenants` mit `parent_tenant_id` als Vorbereitung.
---
## R-18 — Fehlerresilienz für Integrationen nicht entworfen
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** Adapter-Anforderungen sagen „Fehlerbehandlung" aber Retry-Strategie, Backoff, Circuit Breaker, Dead-Letter-Queue, Reconciliation bei inkonsistentem Zustand sind nicht beschrieben. Bei Domain-Renewal kann ein nicht behandelter Adapter-Fehler einen geschäftskritischen Datenverlust bedeuten.
- **Empfehlung:** Standardpattern für alle Adapter: Retry mit exponentiellem Backoff, Circuit Breaker, Dead Letter, Reconciliation-Job nightly. Job-Status sichtbar im UI.
---
## R-19 — API-Versionierungsstrategie unvollständig
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** Nur Pfad-Versionierung (`/api/v1/`) ohne Deprecation/Sunset/Compatibility-Strategie. Bei API-first-Anspruch zu wenig.
- **Empfehlung:** ADR mit klaren Regeln: Breaking Changes nur über neue Major-Version, Minor-Changes additiv, Deprecation-Header (`Deprecation`, `Sunset`), Mindest-Support-Zeitraum für ältere Versionen.
---
## R-20 — Nummernkreise pro Mandant ohne Mechanismus
- **Schweregrad:** `HIGH`
- **Zeitpunkt:** `V1`
- **Problem:** Rechnungsnummern müssen lückenlos sein und pro Mandant separat. Kunden-, Vertrags-, Rechnungsnummern: pro Mandant? Global? Konfigurierbar? Aktuell nicht modelliert.
- **Empfehlung:** Dedicate Sequence-Tabelle pro Mandant und pro Nummernkreis. Atomic-Increment mit DB-Lock. Konfigurierbares Format (Präfix, Padding, Reset-Verhalten). Pflicht für GoBD-Konformität.
---
## R-21 — Personen-/Adressmodell als undifferenziertes Bündel
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `NOW`
- **Problem:** `Kunde` enthält „Stammdaten + Ansprechpartner + Kontaktdaten" als monolithisches Objekt. Klassisches Anti-Pattern. Erschwert DSGVO-Auskunft/Löschung, B2B-Modell, Mehrfach-Ansprechpartner, getrennte Rechnungs-/Postanschriften.
- **Empfehlung:** Trennung in `Party` (Person oder Organisation) + `Address` (mit Verwendungszweck: Rechnung/Post/Rechtssitz) + `ContactPoint` (Mail/Tel/etc. mit Verwendungszweck). N:M zwischen Customer und Party für Ansprechpartner.
---
## R-22 — WordPress-Plugin als zweite Sicherheitsdomäne
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V2`
- **Problem:** Plugin ist API-Client mit eigener Session-Domäne, eigenem Update-Lifecycle, eigener Plugin-Ökosystem-Risikofläche. Wenn die WP-Site kompromittiert ist, sind die API-Tokens des Plugins gefährdet. Aktuell ist nicht definiert, welche Scopes das Plugin erhält und wie kompromittierte Tokens rotiert werden.
- **Empfehlung:** Plugin nur mit minimal-Scope-Token. Token-Revocation aus Admin-UI. Lifetime begrenzen. Audit-Log bei jeder Plugin-API-Nutzung. Strategie für Sandbox-Tests bei kompromittiertem WP-Setup.
---
## R-23 — Frontend-Strategie offen widerspricht API-first-Anspruch
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `NOW`
- **Problem:** „Blade oder später Vue/Nuxt" lässt eine fundamentale Architekturentscheidung offen. Klassischer Laravel-Monolith mit angeflanschter API ist eine andere Architekturklasse als ein API-first-System mit echtem SPA-Client.
- **Empfehlung:** ADR. Entweder Blade-als-API-Konsument (Blade-Views rufen interne API auf, kein direkter DB-Zugriff aus Views) oder Vue-/Nuxt-SPA. Nicht „später".
---
## R-24 — BFSG / Barrierefreiheit für Customer Portal
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1` (falls Portal in V1) / `V2`
- **Problem:** Seit 28. Juni 2025 sind in der EU kommerzielle digitale Dienste an Verbraucher barrierefrei zu gestalten (BFSG, Umsetzung der EU-Richtlinie 2019/882). Customer Portal fällt darunter.
- **Empfehlung:** UI-Komponenten und Frontend-Stack barrierefrei gestalten (WCAG 2.1 AA als Ziel). Wenn Portal aus V1 raus ist (R-13), entschärft sich das auf V2.
---
## R-25 — Modul-Lifecycle (Deinstallation, Datenreferenzen) ungeklärt
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** Module sollen aktivierbar/deaktivierbar sein. Was passiert mit referenzierten Daten in anderen Modulen, wenn ein Modul deinstalliert wird? Was passiert bei Re-Installation? Diese Semantik ist nirgendwo beschrieben.
- **Empfehlung:** Modul-Lifecycle definieren: aktivieren / deaktivieren (Daten bleiben) / deinstallieren (Daten archivieren, optional löschen). Dependencies zwischen Modulen explizit deklarieren. Migrations-Strategie bei Re-Installation.
---
## R-26 — Logging-/Audit-Sink-Architektur unspezifiziert
- **Schweregrad:** `MEDIUM`
- **Zeitpunkt:** `V1`
- **Problem:** Logging-Strategie sagt was geloggt werden soll, aber nicht wohin oder wie. App-Logs vs. Audit-Logs sind getrennt, aber Speicherort, Retention, Mandantenscope, Integritätsschutz fehlen.
- **Empfehlung:** Drei getrennte Senken: App-Logs (lokal, kurzfristig, optional externer Aggregator wie Loki/Sentry), Audit-Logs (DB-Append-only, langfristig, pro Mandant), Security-Logs (Login, Auth-Fehler, Admin-Aktionen, separat).
---
## R-27 — „Vorbereitende" Felder ohne Verwendung in V1
- **Schweregrad:** `LOW`
- **Zeitpunkt:** `NOW`
- **Problem:** Mehrfach „… später möglich" als Feld-Anmerkung (Server.Rollen später, Hostingpaket.Ressourcen später, Gebührenregeln später). Erfahrung: solche Felder werden entweder nie genutzt oder mit Bedeutung versehen, die nicht zur ursprünglichen Form passt.
- **Empfehlung:** „Später"-Felder aus dem v0.1-Datenmodell entfernen. Wenn ein Feld V1 nicht braucht, wird es V1 nicht migriert. Bei Bedarf später eigene Migration.
---
## R-28 — Mehrere parallele Single Sources of Truth
- **Schweregrad:** `LOW` (organisatorisch) / `HIGH` (in Konsequenz)
- **Zeitpunkt:** `NOW`
- **Problem:** Strategie-Dokumente, Modul-Dokumente, Roadmap und MVP-Liste enthalten sich widersprechende Aussagen (siehe R-04, R-13). Ohne klare Hierarchie zwischen den Dokumenten wird im Code-Schritt jede Person eine andere Variante implementieren.
- **Empfehlung:** Dokumenthierarchie festlegen: ADRs > Strategie-Dokumente > Modul-Beschreibungen > Roadmap. Konflikte werden in dieser Reihenfolge aufgelöst. Bei Konflikt: ADR ergänzen oder Strategie-Doc aktualisieren, untere Ebenen nachziehen.
---
## Zusammenfassende Priorisierung
**CRITICAL / NOW** (vor Codebeginn unverzichtbar):
- R-01 Mandantenfähigkeits-Mechanismus
- R-02 Anbieterlogik aus Core entfernen
- R-03 Billing aus Core entfernen
- R-05 Secrets-Management
**HIGH / NOW** (vor Codebeginn entscheiden):
- R-04 Modulstruktur als einzige Wahrheit
- R-06 Core verkleinern
- R-09 API-Auth-Strategie
- R-10 Datenbank-Engine
- R-11 KI-Scope-Entscheidung
- R-13 V1-Scope vereinheitlichen
- R-17 Reseller-Hierarchie-Vorbereitung
- R-21 Personen-/Adressmodell
- R-23 Frontend-Strategie
- R-28 Dokumenten-Hierarchie
**HIGH / V1** (muss in V1 enthalten sein):
- R-07 GoBD-Verantwortlichkeit
- R-08 DSGVO-Löschung-Modell
- R-16 Steuer-/MwSt-Logik
- R-20 Nummernkreise
**MEDIUM / V1**:
- R-12 SEPA-Modell oder raus
- R-14 Audit-Unveränderbarkeit
- R-18 Adapter-Fehlerresilienz
- R-19 API-Versionierung
- R-24 Barrierefreiheit (falls Portal in V1)
- R-25 Modul-Lifecycle
- R-26 Logging-Architektur
**MEDIUM/HIGH / V2-V3**:
- R-15 Tenant-Offboarding
- R-22 WP-Plugin-Sicherheitsmodell
- R-24 Barrierefreiheit (Portal in V2)
**LOW / NOW**:
- R-27 Spekulative Felder entfernen
---
Die Gesamtbotschaft: Die Anzahl der CRITICAL/NOW-Punkte (4) ist überschaubar und alle in 24 Wochen entscheidungsreif. Die HIGH/NOW-Punkte (10) sind ADR-Material. Wenn diese 14 Punkte vor Codebeginn entschieden sind, hat das Projekt eine sehr gute Ausgangslage. Werden sie nicht entschieden, ist V1 voraussichtlich produktiv nutzbar, aber V2/V3 wird teurer als V1 selbst.