Add AI workspace reviews

This commit is contained in:
2026-05-18 04:37:23 +00:00
commit 7ac1371aff
106 changed files with 5378 additions and 0 deletions
+312
View File
@@ -0,0 +1,312 @@
# 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.