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
@@ -0,0 +1,472 @@
## 1. Zusammenfassung
Claude benennt valide Architektur-Risiken. Für das Projekt werden daraus keine neuen Produktziele abgeleitet, sondern konkrete Korrekturen an Datenmodell, Security-Dokumentation, ADRs und Betriebsregeln.
Kernentscheidungen:
- `tenant_id` wird der einzige technische Mandanten-Isolationsschlüssel.
- `organisation_id` wird nicht mehr für Tenant-Isolation verwendet.
- Multi-Tenancy wird nicht „halb vorbereitet“, sondern technisch sauber in V1 angelegt.
- Secrets werden nicht im Domainmodell gespeichert, sondern nur referenziert.
- Audit-Hash-Chain wird nicht als manipulationssichere Security-Maßnahme verkauft.
- DLQ, Dokumente, Rollen und Reconciliation erhalten konkrete Regeln.
- Bounded Contexts werden als Modul-/Schema-Grenzen dokumentiert, keine Microservice-Aufspaltung.
---
## 2. Übernommene Punkte
### Tenant-Isolation
Übernehmen.
Änderung:
- `tenant_id` ist Pflichtfeld auf allen mandantenbezogenen Tabellen.
- `organisation_id` wird aus der technischen Isolation entfernt.
- Falls Organisation benötigt wird, dann nur fachlich, z. B. als `customer_organisation_id`.
- PostgreSQL Row-Level-Security wird vorgesehen.
- Tenant-Kontext wird pro Request/Job explizit gesetzt.
- Queries ohne Tenant-Kontext müssen fehlschlagen.
Konkrete Modellregel:
```text
tenant_id UUID NOT NULL REFERENCES tenants(id)
```
Für mandantenbezogene Relationen:
```text
FOREIGN KEY (tenant_id, customer_id)
REFERENCES customers(tenant_id, id)
```
---
### Secrets-Management
Übernehmen.
Änderung:
- Keine API-Keys, Passwörter oder Tokens in Fachentitäten.
- Domainmodelle speichern nur `secret_ref`.
- Secret-Service wird als technischer Baustein dokumentiert.
- Encryption-at-rest wird verpflichtend für Secret-Storage.
- Zugriff auf Secrets nur über Service-Layer, nicht über direkte DB-Reads.
Beispiel:
```text
registrar_accounts.secret_ref
```
statt:
```text
registrar_accounts.api_key
registrar_accounts.password
```
---
### Audit-Log
Teilweise übernehmen.
Änderung:
- Hash-Chain wird nicht als Schutz gegen DB-Admin-Manipulation beschrieben.
- Audit-Log bleibt append-only auf Anwendungsebene.
- Integritätsprüfung wird klar abgegrenzt.
- Optional: periodischer Export/Checkpoint in externes System.
ADR 0014 muss entsprechend korrigiert werden.
---
### Dead Letter Queue
Übernehmen.
Änderung:
- DLQ erhält Retention-Regeln.
- PII in Fehlerpayloads wird vermieden oder redaktiert.
- Maximale Aufbewahrung wird festgelegt.
- Reprocessing und Löschung werden beschrieben.
Vorschlag:
```text
DLQ default retention: 30 Tage
DLQ max retention: 90 Tage
PII payloads: nicht speichern oder redaktieren
```
---
### Bounded Contexts
Übernehmen, aber pragmatisch.
Änderung:
- Keine sofortige Service-Aufteilung.
- Einführung klarer Modulgrenzen im Monolithen.
- Datenmodell wird nach fachlichen Bereichen gegliedert.
Kontexte:
- Identity & Access
- CRM
- Billing
- Provisioning
- Registry
- Support
- Documents
- Audit
---
### Reconciliation
Teilweise übernehmen.
Änderung:
- Kein vollständiges Event-Sourcing für V1.
- Stattdessen Operation-/Job-Historie und Status-Snapshots.
- Reconciliation basiert auf:
- gewünschtem Zustand
- aktuellem externem Zustand
- letzter Operation
- Fehlerhistorie
Benötigte Tabellen/Modelle:
```text
provisioning_operations
external_resource_snapshots
job_runs
job_attempts
```
---
### Rollen und Scopes
Übernehmen.
Änderung:
- Rollen werden nicht nur benannt, sondern mit konkreten Berechtigungen dokumentiert.
- Zugriff auf Secrets, Rechnungen, Serverdaten und Kundendaten wird explizit geregelt.
Beispielrollen:
- Owner
- Admin
- Billing
- Support
- Provisioning Operator
- Read-only Auditor
---
### Dokument-Storage
Übernehmen.
Änderung:
- Dokumente speichern keine Datei direkt im Datenmodell.
- Dokumente referenzieren Object Storage.
- Tenant-Isolation über Bucket/Prefix plus DB-Zugriffskontrolle.
- Löschung, Archivierung und Legal Hold werden dokumentiert.
Beispiel:
```text
documents.object_key
documents.storage_provider
documents.checksum_sha256
documents.retention_until
documents.legal_hold
documents.deleted_at
```
---
## 3. Abgelehnte oder verschobene Punkte
### Vollständiges Event-Sourcing
Verschoben.
Begründung:
- Für V1 nicht erforderlich.
- Reconciliation kann über Operation-Historie, Job-Historie und Snapshots umgesetzt werden.
---
### Microservice-Aufteilung nach Bounded Contexts
Abgelehnt für V1.
Begründung:
- Zu hoher Betriebs- und Integrationsaufwand.
- Modulgrenzen im Monolithen reichen aktuell aus.
---
### Audit-Hash-Chain als Manipulationsschutz
Abgelehnt.
Änderung:
- Hash-Chain darf maximal als Integritätsindikator beschrieben werden.
- Kein Sicherheitsversprechen gegen privilegierte DB-Manipulation.
---
### Parallele Nutzung von `organisation_id` und `tenant_id`
Abgelehnt.
Änderung:
- Nur `tenant_id` ist technischer Scope.
- Organisation ist, falls benötigt, ein CRM-/Kundenkonzept.
---
### Single-Tenant V1 ohne Tenant-Schutz
Abgelehnt.
Änderung:
- V1 darf fachlich nur einen aktiven Tenant haben.
- Technisch wird Tenant-Isolation trotzdem sauber eingebaut.
---
## 4. Neue/geänderte Dateien
### Geändert
#### `docs/data-model-v0.2.md`
Änderungen:
- `organisation_id` aus technischer Mandanten-Isolation entfernen.
- `tenant_id` als verbindlichen Scope definieren.
- Tenant-FK-Regeln ergänzen.
- Tabellen nach Bounded Contexts gruppieren.
- Secret-Felder durch `secret_ref` ersetzen.
- Dokumentmodell um Storage-Metadaten erweitern.
- Operation-/Job-Historie ergänzen.
---
#### `docs/security.md`
Änderungen:
- Tenant-Isolation konkretisieren.
- Secrets-Management konkretisieren.
- RBAC/Scopes verlinken.
- RLS und Tenant-Kontext als Pflichtmechanismus aufnehmen.
---
#### `docs/adr/0014-audit-log.md`
Änderungen:
- Hash-Chain nicht mehr als manipulationssicher beschreiben.
- Algorithmus konkretisieren, falls beibehalten.
- Optionalen externen Checkpoint/Export dokumentieren.
- Grenzen des Mechanismus explizit nennen.
---
#### `docs/adr/0017-jobs-reconciliation-dlq.md`
Änderungen:
- DLQ-Retention ergänzen.
- PII-Regeln ergänzen.
- Reprocessing-Regeln ergänzen.
- Reconciliation-Datenbasis ergänzen.
---
### Neu
#### `docs/architecture/tenant-isolation.md`
Inhalt:
- `tenant_id` als einziger technischer Mandantenschlüssel
- Request-/Job-Tenant-Kontext
- Fail-closed-Verhalten
- RLS-Grundregeln
- Cross-Tenant-Zugriffe verboten
- Composite FK-Regeln
---
#### `docs/architecture/bounded-contexts.md`
Inhalt:
- Modulgrenzen
- erlaubte Abhängigkeiten
- Besitz von Tabellen/Entitäten
- keine direkten Fremdzugriffe zwischen Kontexten ohne definierte Schnittstelle
---
#### `docs/security/secrets-management.md`
Inhalt:
- Secret-Service-Konzept
- `secret_ref`
- keine Klartext-Secrets in DB
- Rotation
- Zugriffskontrolle
- Auditierung von Secret-Zugriffen
---
#### `docs/security/rbac-matrix.md`
Inhalt:
| Bereich | Owner | Admin | Billing | Support | Provisioning | Auditor |
|---|---:|---:|---:|---:|---:|---:|
| Kunden lesen | ja | ja | ja | ja | ja | ja |
| Kunden ändern | ja | ja | nein | eingeschränkt | nein | nein |
| Rechnungen lesen | ja | ja | ja | nein | nein | ja |
| Rechnungen ändern | ja | ja | ja | nein | nein | nein |
| Serverdaten lesen | ja | ja | nein | eingeschränkt | ja | ja |
| Server ändern | ja | ja | nein | nein | ja | nein |
| Secrets lesen | nein | nein | nein | nein | nein | nein |
| Secret nutzen | ja | ja | nein | nein | system | nein |
---
#### `docs/storage/document-storage.md`
Inhalt:
- Object-Storage-Strategie
- Tenant-Isolation per Prefix/Bucket
- Checksums
- Archivierung
- Löschanfragen
- Legal Hold
- Zugriffskontrolle
---
#### `docs/operations/dlq-retention.md`
Inhalt:
- DLQ-Retention
- PII-Regeln
- Reprocessing
- manuelle Freigabe
- endgültige Löschung
- Monitoring
---
#### `docs/operations/reconciliation.md`
Inhalt:
- gewünschter Zustand
- externer Ist-Zustand
- Operation-Historie
- Snapshot-Modell
- Konfliktbehandlung
- Retry-Strategie
---
#### `db/policies/tenant_rls.sql`
Inhalt:
- PostgreSQL RLS-Grundstruktur
- Policy pro mandantenbezogener Tabelle
- Nutzung von `current_setting('app.tenant_id')`
- Fail-closed bei fehlendem Tenant-Kontext
Beispiel:
```sql
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_customers
ON customers
USING (
tenant_id = current_setting('app.tenant_id')::uuid
);
```
---
#### `db/migrations/xxxx_add_tenant_scope.sql`
Inhalt:
- `tenants`-Tabelle
- `tenant_id` auf mandantenbezogenen Tabellen
- NOT NULL Constraints
- Composite Foreign Keys
- Indizes auf `(tenant_id, id)`
---
## 5. Konkrete nächste Schritte
1. `docs/data-model-v0.2.md` anpassen:
- `tenant_id` festlegen
- `organisation_id` aus Isolation entfernen
- Secret-Felder durch `secret_ref` ersetzen
2. `docs/architecture/tenant-isolation.md` neu erstellen.
3. `db/migrations/xxxx_add_tenant_scope.sql` vorbereiten:
- `tenants`
- `tenant_id`
- Constraints
- Indizes
4. `db/policies/tenant_rls.sql` erstellen.
5. `docs/security/secrets-management.md` erstellen.
6. `docs/security/rbac-matrix.md` erstellen.
7. ADR 0014 überarbeiten:
- keine falsche Sicherheitsbehauptung zur Hash-Chain
8. ADR 0017 überarbeiten:
- DLQ-Retention
- PII-Regeln
- Reconciliation-Datenbasis
9. `docs/storage/document-storage.md` erstellen.
10. `docs/architecture/bounded-contexts.md` erstellen und Datenmodell danach gruppieren.
+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.
+168
View File
@@ -0,0 +1,168 @@
# Offene Fragen vor Entwicklungsbeginn
**Stand:** 15. Mai 2026
**Reviewer:** Claude
**Bezug:** Hosting-Backoffice v0.1 (vollständiger Basisbestand)
Diese Fragen müssen vor Beginn der V1-Implementierung beantwortet sein. Sie sind nach Themenbereich gruppiert. Innerhalb jedes Bereichs sind sie nach Dringlichkeit geordnet.
---
## 1. Mandantenfähigkeit
1. Welches Tenancy-Modell gilt für V1: Shared Database mit `tenant_id`-Scope, Schema-pro-Tenant, oder Database-pro-Tenant?
2. Was bedeutet `organisation_id` zusätzlich zu `tenant_id`? Sind beide Synonyme (eines streichen) oder Hierarchieebenen (dann mit ER-Modell zeigen)?
3. Wie wird Tenant-Isolation technisch erzwungen? Eloquent Global Scope, Policy-Layer, Row-Level Security in Postgres, Connection-Switching, oder Kombination?
4. Wie viele Subjektebenen hat das Berechtigungsmodell? Plattformbetreiber → Mandant → Endkunde, oder mit Reseller-Zwischenebene?
5. Wie sieht der Tenant-Lifecycle aus: Provisioning, Suspend, Termination, Datenexport, Offboarding?
6. Wie wird Cross-Tenant-Datenzugriff für Plattform-Admins technisch geregelt (Impersonation, Read-only-Bypass, Audit-Pflicht)?
7. Wie wird beim Wechsel von V1 (Single-Tenant) zu V2/V3 (Multi-Tenant) der erste Mandant migriert?
8. Gibt es Cross-Tenant-Ressourcen (gemeinsame Templates, Knowledge Base, Module Registry), und wie sind sie modelliert?
---
## 2. Datenmodell
1. Wie sieht das vollständige ER-Modell mit Beziehungen und Kardinalitäten aus?
2. Welche Statusmaschinen existieren für Vertrag, Domain, Hostingpaket, Ticket, Rechnung, und welche Übergänge sind erlaubt?
3. Wie werden Nummernkreise pro Mandant verwaltet (lückenlos, GoBD-konform, separat für Kunde/Vertrag/Rechnung)?
4. Wird `Kunde` in Party/Address/ContactPoint aufgespalten, oder als monolithisches Objekt gehalten?
5. Wie wird B2B vs. B2C unterschieden im Datenmodell?
6. Wie wird das Spannungsfeld Soft-Delete / GoBD-Retention / DSGVO-Löschung technisch aufgelöst? Tombstone-Modell mit Pseudonymisierung?
7. Wie werden externe Referenzen modelliert (generisches Pattern statt anbieter-spezifischer Felder im Core)?
8. Wie ist das Audit-Log-Schema, und wie wird Unveränderbarkeit garantiert (Hash-Chain, Append-only-DB, externes Sink)?
9. Werden Verträge versioniert (Vertragsversion, Änderungshistorie)?
10. Wie werden Subscriptions/Laufzeiten modelliert (Vertrag.Laufzeit reicht nicht für Up-/Downgrade und Pro-rata)?
11. Wie wird die Many-to-many-Beziehung Vertrag↔Produkt, Vertrag↔Domain, Vertrag↔Hostingpaket modelliert?
12. Wie ist das Asset-/Dokument-Modell (Hashes, Content-Addressing, Versionen, Storage-Backend-Abstraktion)?
---
## 3. API
1. Welcher Auth-Stack: Sanctum Personal Access Tokens, Sanctum SPA-Mode, Passport/OAuth2, oder Kombination je Client-Typ?
2. Gibt es OpenAPI 3.x als verbindliche Spec, und ist die Implementierung spec-first?
3. Welches Error-Modell wird verwendet (Problem Details RFC 7807 empfohlen)?
4. Welche Pagination-Strategie: Offset, Cursor, Page?
5. Welche Idempotenz-Strategie für nicht-idempotente Operationen (Domain-Registrierung, Rechnungsanlage)?
6. Wie sieht das Filtering-/Sorting-Schema aus?
7. Wie wird API-Versionierung über `/api/v1/` hinaus gehandhabt (Deprecation, Sunset, Compatibility)?
8. Gibt es Webhooks/Outbound Events? Welches Format, welche Signaturen, welche Delivery-Garantien?
9. Wie werden Rate-Limits pro Mandant skaliert (nicht nur pro IP/Token)?
10. Welche Endpoints sind read-only, welche schreibend, und wie ist das in der Auth-Scope-Logik abgebildet?
11. Wie werden Long-Running-Operations modelliert (Domain-Imports, große Synchronisationen) synchron, asynchron mit Job-Status-Endpoint, oder via Webhook-Callback?
---
## 4. Core- und Modulgrenzen
1. Was gehört verbindlich in den Core, was in Service-Module, was in Integrationsmodule? (Aktuelle Liste in `module-structure-v0.1.md` ist unvollständig.)
2. Wo lebt Billing architektonisch? Im Core (Daten heute dort), als Service-Modul, als Adapter-Verbund?
3. Wo lebt das Customer Portal? Service-Modul oder eigenes UI-Modul?
4. Wie ist ein Modul technisch verpackt Composer-Package, in-app Namespace, Nwidart-Modul, anderes?
5. Wie kommunizieren Module untereinander: Events, Service-Contracts, beides?
6. Wie wird die Modul↔Core-API versioniert? Wie deklariert ein Modul seine Core-API-Mindestversion?
7. Was passiert bei Modul-Deinstallation mit existierenden Datenreferenzen?
8. Wie sind Modul-Migrationen mit Core-Migrationen verzahnt?
9. Wer ist „Owner" jeder Entität (Aggregate Root)? Insbesondere: Wer besitzt `Rechnung` Billing-Modul oder Core?
10. Wie wird ein generisches External-Reference-Pattern eingeführt, ohne die heutigen anbieter-spezifischen Felder zu zementieren?
---
## 5. Sicherheit und Compliance
1. Wie werden Registrar-/Provider-API-Credentials gespeichert? Externer Vault, eigenes Verschlüsselungsschema, KMS, HSM?
2. Wer ist GoBD-Verantwortlicher für Rechnungen Hosting-Backoffice oder das externe Billing-System (Lexware/Invoice Ninja)?
3. Falls Hosting-Backoffice GoBD-Verantwortlicher ist: Welcher Mechanismus garantiert Unveränderbarkeit nach Festschreibung?
4. Wie wird DSGVO-Auskunft pro Endkunde umgesetzt (vollständiger Datenexport in maschinenlesbarer Form)?
5. Wie wird DSGVO-Löschung pro Endkunde umgesetzt, ohne GoBD-Retention zu verletzen (Pseudonymisierung)?
6. Wer ist Auftragsverarbeiter zwischen Plattformbetreiber und Mandant (DPA)? Wie ist die Beziehung Mandant↔Endkunde geregelt?
7. Welche Subprozessoren werden eingesetzt (insbesondere KI-Provider, Mail-Versand, Hosting-Region, Backup-Region)?
8. Wo werden Audit-Logs gespeichert, und wie wird ihre Integrität garantiert?
9. Welche Authentication-Faktoren werden unterstützt (Password, 2FA, WebAuthn)? Pflicht für Admins?
10. Welche Session-Strategie (Lifetime, Idle-Timeout, Refresh, Revocation)?
11. Wie wird Datenresidenz garantiert („europäisch" auf welcher Ebene: Hosting, DB, Backup, Subprozessoren)?
12. Wer haftet bei kompromittierten Registrar-Credentials? Welche technischen Maßnahmen reduzieren das Risiko?
13. Welche AGB-/Widerrufs-Mechanismen werden bei Customer Portal benötigt?
14. Ist BFSG/Barrierefreiheit für das Customer Portal relevant (EU-Verordnung seit 28.06.2025)?
---
## 6. Integrationen
1. Wie ist der formale Adapter-Contract definiert (Interface-Methoden, Fehler-Schema, Auth, Idempotenz)?
2. Wie werden Adapter-Fehler behandelt (Retry, Backoff, Circuit Breaker, Dead Letter)?
3. Wie wird inkonsistenter Zustand zwischen Core und externem System aufgelöst (Reconciliation, manueller Eingriff)?
4. Wie werden Adapter-Konfigurationen pro Mandant verwaltet (Mandant A nutzt Lexware, Mandant B Invoice Ninja)?
5. Was ist die Bedeutung von „Zahlungsart PayPal/Wero": reine Statusanzeige oder echte Integration?
6. Wie wird SEPA-Lastschrift modelliert (Mandate, UMR, Pre-Notification, IBAN-Verschlüsselung)?
7. Welche Steuer-/MwSt-Logik liegt im System, welche im Billing-Adapter?
8. Was passiert bei Modul-Updates eines Adapters mit nicht-rückwärtskompatiblen Änderungen?
9. Wie wird Mail-Versand (SMTP/Transactional) als eigene Integration gehandhabt? Welcher Anbieter? SPF/DKIM/DMARC-Strategie?
---
## 7. WordPress-Plugin
1. Welche Auth-Brücke zwischen WordPress und Hosting-Backoffice? OAuth2 Client Credentials? App-Token pro Mandant? Endkunden-Delegation?
2. Speichert das Plugin Daten lokal in WordPress (Sync-Risiko) oder ist es reiner API-Konsument?
3. Wie wird WP-User-Identität auf Backoffice-User-Identität gemappt?
4. Wie ist das Plugin-Update-Lifecycle (eigener Auto-Updater, WordPress.org-Repository, privates Repo)?
5. Welche API-Scopes erhält das Plugin? Was passiert bei kompromittierter WP-Site?
6. Wer ist Mandant aus Sicht der API, wenn ein WP-User klickt der WP-Site-Betreiber oder der endgültige Endkunde?
7. Welche Caching-/Stale-Data-Strategie hat das Plugin gegenüber der API?
---
## 8. KI-Assistent
1. Bleibt KI in V1 oder rückt es in V2 (Empfehlung: V2)?
2. Welcher KI-Provider? OpenAI, Anthropic, Mistral, lokal?
3. Wenn US-basierter Provider: DPA, SCC, Drittlandtransfer-Risikobewertung?
4. Welche Daten gehen an die KI Inhalte oder nur Metadaten? Auf welcher Datenklassifikation basiert das?
5. Wie wird Endkunden-Zustimmung eingeholt, falls Support-Tickets KI-verarbeitet werden?
6. Wie werden Halluzinationen kontrolliert (Mensch-im-Loop, Confidence-Schwellen, Quellen-Citation)?
7. Wer haftet bei falschen KI-Vorschlägen (insbesondere bei Rechnungs-/Vertragsdaten)?
8. Wie wird KI-Output protokolliert und auditiert?
---
## 9. V1-Scope
1. Endgültige V1-Kundenzahl: 150 oder 1500? (Empfehlung: 150, Roadmap-Wert)
2. Kundenportal in V1 oder V2? (Empfehlung: V2)
3. KI-Assistent in V1 oder V2? (Empfehlung: V2)
4. SEPA-Lastschrift in V1 oder V2? (Empfehlung: V2 oder vollständiges Modell jetzt)
5. PayPal/Wero in V1: reine Anzeige oder Integration?
6. Welche Mahnwesen-Funktionalität ist V1-Minimum (Status „überfällig" + manuelle Mail)?
7. Welche Tax-/MwSt-Funktionalität ist V1-Minimum?
8. Welche DSGVO-Funktionen sind V1-Pflicht (Auskunft, Löschung, Datenportabilität)?
9. Welche Backup-/Restore-Funktion ist V1-Pflicht?
---
## 10. Deployment und Operations
1. Self-hosted-only oder SaaS-Variante geplant? Welcher Mix?
2. Welche PHP-Version? Welche Laravel-Version?
3. Welcher Queue-Driver in V1 (Database, Redis)?
4. Welche Backup-Strategie pro Mandant?
5. Welche Disaster-Recovery-Strategie?
6. Welche Logging-/Monitoring-Tools (Sentry, Loki, Grafana, Telemetry-Provider)?
7. Welcher CI/CD-Stack?
8. Welche Update-/Migration-Strategie auf Kundensystemen (bei Self-hosted)?
9. Welche Update-Strategie für Module unabhängig vom Core?
---
## 11. Lizenz und Geschäftsmodell
1. Welche Open-Source-Lizenz, oder Closed-Source?
2. Welche kommerzielle Lizenz für Mandanten?
3. Werden Module einzeln verkauft, oder als Bundle?
4. Wer darf Module von Drittanbietern entwickeln und verteilen?
5. Wie wird das Versprechen „europäisch" geschäftlich umgesetzt (Hosting-Region, Subprozessoren, Vertragsrecht)?
---
Diese Liste ist nicht vollständig, aber priorisiert. Die Punkte unter 1, 2, 4 und 5 sind harte Blocker für Codebeginn. Die übrigen können in v0.2 oder begleitend zur ersten Implementierungsphase entschieden werden.
+94
View File
@@ -0,0 +1,94 @@
## Kritische Architekturprobleme
### 1. Fataler Tenant-Isolation-Fehler
Das Datenmodell nennt sowohl `organisation_id` als auch `tenant_id`, aber ohne klare Abgrenzung. Dies ist ein **kritischer Designfehler**:
```
# Problem in data-model-v0.1.md:
"Von Anfang an vorbereiten:
- organisation_id
- tenant_id"
```
**Warum kritisch:**
- Unklare Hierarchie zwischen Organisation und Tenant
- Potenzielle Tenant-Leaks durch falsche Filterung
- Kein explizites Constraint-Modell definiert
**Lösung erforderlich:** Eine klare Entscheidung - entweder Organisation ODER Tenant, nicht beides halbherzig.
### 2. Secrets-Management ohne Implementierung
Das Security-Dokument behauptet:
```
"Secrets werden nur über einen Secret-Service gelesen/geschrieben"
```
Aber:
- Kein Secret-Service definiert
- Registrar-Account hat "Zugangsdaten/API-Referenzen" direkt im Modell
- Keine Encryption-at-Rest-Strategie
**Risiko:** Passwörter landen im Klartext in der Datenbank.
### 3. Audit-Log Hash-Chain ist Pseudo-Security
ADR 0014 schlägt eine Hash-Chain vor, aber:
- Kein Schutz gegen DB-Admin-Manipulation
- Hash-Algorithm nicht spezifiziert
- "V1 bereitet vor" = wird nicht implementiert
**Problem:** Security-Theater ohne echten Schutz. Ein DB-Admin kann die gesamte Chain neu berechnen.
### 4. Dead Letter Queue ohne Retention-Strategie
ADR 0017 fordert Dead Letter Queues, aber:
- Keine maximale Retention definiert
- Potenzielle Speicher-Explosion
- DSGVO-Konflikt bei personenbezogenen Daten in fehlgeschlagenen Jobs
### 5. Fehlende Core-Domain-Boundaries
Das Datenmodell mischt alles:
- Billing (Rechnung, Zahlung)
- Provisioning (Server, Hostingpaket)
- CRM (Kunde, Ticket)
- Registry (Domain, Registrar)
**Problem:** Keine Bounded Contexts = massive Kopplung, unmöglich zu skalieren.
### 6. Reconciliation ohne Event-Sourcing
ADR 0017 fordert Reconciliation, aber das Datenmodell hat keine Event-Historie. Wie soll man reconcilen ohne zu wissen, was passiert ist?
### 7. Security-Rollen ohne Scope-Definition
"Staff/Support" hat Zugriff auf "operative Daten" - was heißt das konkret?
- Kann Support Passwörter sehen?
- Kann Support Rechnungen ändern?
- Kann Support Server-Zugänge einsehen?
### 8. Single Point of Failure: tenant_id
Alles hängt an einem einzigen Feld. Ein fehlerhafter Query-Scope = Datenleck über alle Mandanten.
**Fehlende Sicherheitsschicht:**
- Kein Row-Level-Security auf DB-Ebene
- Keine Tenant-Context-Validierung
- Kein Fail-Safe-Mechanismus
### 9. Dokument-Objekt ohne Storage-Strategy
"Dokument" hat "Hashes" und "Archivinformationen", aber:
- Wo werden Dateien gespeichert?
- Wie wird Tenant-Isolation im Filesystem sichergestellt?
- Was passiert bei Löschanfragen?
### 10. Keine Migrationsstrategie für Multi-Tenancy
"V1 arbeitet als Single-Tenant" aber "Struktur vorbereitet" - das ist ein Widerspruch. Entweder man designed multi-tenant von Anfang an oder man plant eine Migration. Beides fehlt.
## Fazit
Die Architektur versucht, zu viele Probleme gleichzeitig zu lösen, ohne eines davon richtig zu durchdenken. Kritischster Punkt: Die Tenant-Isolation ist nur oberflächlich geplant und wird mit hoher Wahrscheinlichkeit zu Datenleaks führen.
+9
View File
@@ -0,0 +1,9 @@
# Claude Review Placeholder
Hier können spätere Claude-Reviews abgelegt werden.
Empfohlene Nutzung:
- Architektur kritisch prüfen lassen
- Sicherheitsrisiken identifizieren
- V1-Scope hinterfragen
- Datenmodell kommentieren lassen
+123
View File
@@ -0,0 +1,123 @@
# Claude Review Response Map v0.3
## Zweck
Dieses Dokument zeigt, welche Claude-Risiken durch dieses Update adressiert wurden.
## Bereits adressiert
### R-01 Mandantenfähigkeit
Adressiert durch:
- ADR 0004 Tenancy-Modell
- ADR 0005 Datenbankwahl
- security-and-rights-v0.2.md
### R-02 Anbieterlogik im Core
Adressiert durch:
- ADR 0008 External-Reference-Pattern
- data-model-v0.2-direction.md
### R-03 Billing im Core
Adressiert durch:
- ADR 0009 Core-Grenzen
- module-structure-v0.2.md
- data-model-v0.2-direction.md
### R-04 Modulstruktur widersprüchlich
Adressiert durch:
- ADR 0022 Dokumentenhierarchie
- module-structure-v0.2.md
### R-05 Secrets-Management
Adressiert durch:
- ADR 0010 Secrets-Management
### R-06 Core zu groß
Adressiert durch:
- ADR 0009 Core-Grenzen
- core-architecture-v0.2.md
### R-07 GoBD-Verantwortlichkeit
Adressiert durch:
- ADR 0011 GoBD-Verantwortlichkeit
### R-08 DSGVO-Löschung vs. Retention
Adressiert durch:
- ADR 0021 DSGVO-Löschung und Retention
### R-09 API-Auth
Adressiert durch:
- ADR 0006 Auth-Strategie
### R-10 Datenbankwahl
Adressiert durch:
- ADR 0005 Datenbankwahl
### R-11 KI in V1
Adressiert durch:
- ADR 0019 V1-Scope-Finalisierung
### R-12 SEPA ohne Modell
Adressiert durch:
- ADR 0019 V1-Scope-Finalisierung
### R-13 V1-Scope widersprüchlich
Adressiert durch:
- ADR 0019 V1-Scope-Finalisierung
- roadmap/v1-scope-v0.2.md
### R-14 Audit-Unveränderbarkeit
Adressiert durch:
- ADR 0014 Audit-Log-Strategie
### R-16 Steuer-/MwSt-Logik
Adressiert durch:
- ADR 0015 Tax- und VAT-Strategie
### R-18 Adapter-Fehlerresilienz
Adressiert durch:
- ADR 0017 Adapter-Fehlerresilienz
### R-20 Nummernkreise
Adressiert durch:
- ADR 0023 Nummernkreise
### R-21 Personen-/Adressmodell
Adressiert durch:
- ADR 0013 Kunden-/Adress-/Kontaktmodell
### R-23 Frontend-Strategie
Adressiert durch:
- ADR 0012 Frontend-Strategie
### R-25 Modul-Lifecycle
Adressiert durch:
- ADR 0016 Modul-Lifecycle
### R-28 Dokumentenhierarchie
Adressiert durch:
- ADR 0022 Dokumentenhierarchie
## Noch nicht vollständig adressiert
### R-15 Tenant-Offboarding
Teilweise durch ADR 0021 vorbereitet.
Braucht später eigenes Dokument.
### R-19 API-Versionierungsstrategie
Teilweise durch api-strategy-v0.2 adressiert.
Braucht später API-Conventions-Datei.
### R-22 WordPress-Plugin-Sicherheitsmodell
Teilweise durch ADR 0018 adressiert.
Später konkreter.
### R-24 Barrierefreiheit
Noch offen.
Relevant für Customer Portal V2.
### R-26 Logging-/Audit-Sink-Architektur
Teilweise durch ADR 0014 adressiert.
Braucht später Logging-Strategy v0.2.
### R-27 Spekulative Felder
Wird durch data-model-v0.2-Überarbeitung behandelt.
+289
View File
@@ -0,0 +1,289 @@
# Architecture Review Runde 1
**Reviewer:** Claude (kritischer Senior Architect / Platform Engineer)
**Reviewed:** Hosting-Backoffice v0.1 vollständiger Basisbestand (49 Dateien)
**Datum:** 15. Mai 2026
**Stand:** v0.1 Konzeptphase, vor Entwicklungsbeginn
---
## Gesamtanalyse
Hosting-Backoffice befindet sich in einer ungewöhnlich gut dokumentierten v0.1-Konzeptphase. ADR-Kultur, explizite Non-Goals, ein erkanntes Adapter-Pattern und eine konsistente Vision sind mehr Strukturhygiene, als die meisten Projekte in dieser Phase vorweisen.
Genau diese Stärken erschweren aber die ehrliche Bewertung. Die Dokumentenmenge täuscht über das tatsächliche Spezifikationsniveau hinweg. Mehrere zentrale Architekturentscheidungen sind nicht entschieden, sondern als „vorbereiten" umschrieben Mandantenfähigkeit, Datenbankwahl, API-Authentifizierung, Modul-Contract, Secrets-Management, Audit-Unveränderbarkeit, Frontend-Strategie. „Vorbereiten" ist in Softwarearchitektur fast immer das Synonym für „später unter Schmerzen nachrüsten".
Das zweite Grundmuster ist innere Widersprüchlichkeit. Strategie-Dokumente, Modulbeschreibungen, Roadmap und MVP-Liste erzählen an mehreren Stellen unterschiedliche Geschichten:
- V1-Zielgröße: 1500 Kunden (Vision) vs. 150 Kunden (Roadmap/MVP)
- KI-Assistent: V1-Modul vs. V2-Roadmap-Eintrag
- Kundenportal: eigenes V1-Modul vs. fehlt in MVP-Muss-Funktionen
- Billing/Customer-Portal: existieren als Modul-Dokument, aber tauchen in `module-structure-v0.1.md` weder unter Service- noch unter Integrationsmodulen auf
- Adapter-Pattern („Core kennt keine Anbieterlogik") vs. Datenmodell (`Server.KeyHelp-Referenz`)
- Mandantenfähigkeit: zwei IDs (`organisation_id` + `tenant_id`) ohne erklärte Beziehung
Diese Inkonsistenzen sind keine Schönheitsfehler. Sie zeigen, dass Strategie- und Modul-Dokumente unabhängig voneinander gewachsen sind, ohne dass eine Quelle die andere kontrolliert. Bevor Code geschrieben wird, muss die Modul-Struktur zur einzigen verbindlichen Wahrheit erhoben werden sonst entstehen drei verschiedene Implementierungen aus drei verschiedenen Dokumenten.
Die zentrale Empfehlung dieses Reviews ist nicht „Stoppt das Projekt" und auch nicht „Macht weiter wie geplant". Sie lautet: **Entscheidet jetzt eine begrenzte Anzahl harter Architekturfragen, reduziert V1 weiter, und stellt sicher, dass die Adapter-/Modul-Architektur nicht durch das Datenmodell sabotiert wird.** Alles andere lässt sich später korrigieren. Diese drei Punkte nicht.
Das Projekt ist gut positioniert, schlank zu bleiben. Es ist gleichzeitig schlecht positioniert, modular zu bleiben. Beide Eigenschaften kollidieren in der aktuellen Core-Größe.
---
## Architekturkritik
**Der Core ist faktisch die ganze Anwendung.**
Die Aussage „Core enthält ausschließlich zentrale Plattformlogik" wird durch die Core-Liste sofort widerlegt: Kunden, Verträge, Produkte, Domains, Hostingpakete, Server, Dokumente, Benachrichtigungen, plus Identity/RBAC/Audit/API/Settings. Das sind 13 Bereiche, davon mindestens 6 (Domains, Hostingpakete, Server, Dokumente, Notifications, Produkte) klare Service-Domänen mit eigener Geschäftslogik. Wenn diese sechs Bereiche im Core leben, gibt es genau einen Bounded Context, und das System ist per Definition ein Monolith mit angeflanschten Integrationen exakt das, was in der Vision vermieden werden soll. Modularität entsteht nicht durch Modul-Verzeichnisse, sondern durch klare Bounded Contexts mit eigenen Datenmodellen und definierten Kontrakten.
**„API-first" wird nicht konsequent durchgehalten.**
„API-first" ist in den Strategiepapieren proklamiert, aber:
- Frontend-Strategie ist offen („Blade oder später Vue/Nuxt") das ist mit echtem API-first nicht vereinbar
- Es existiert kein API-Vertrag (kein OpenAPI/Stoplight/etc.), keine spec-first-Disziplin
- Auth-Strategie ist nicht entschieden („Tokenbasiert, später OAuth/Sanctum möglich")
- Idempotenz, Pagination, Filterung, Error-Modell sind nicht beschrieben
- Versionierung beschränkt sich auf URL-Path (`/api/v1/`), ohne Deprecation/Sunset-Strategie
Solange die API kein Vertrag vor dem ersten Endpoint ist, ist „API-first" Marketing, nicht Architektur.
**Adapter-Pattern und Datenmodell widersprechen sich direkt.**
Das Adapter-Pattern wird als zentrales Architekturprinzip beschrieben („Core kennt keine direkte Anbieterlogik"). Im Datenmodell stehen aber `Server.KeyHelp-Referenz` und `Rechnung.externes System` als Core-Felder. Das ist nicht ein bisschen unsauber das ist genau der Verstoß gegen das eigene Pattern. Sobald V1 mit dieser Schema-Form deployt wird, ist das Adapter-Pattern auf Konzept-Ebene tot.
**Mandantenfähigkeit ist eine Absichtserklärung, kein Design.**
Das Multi-Tenancy-Dokument beschreibt nur Ziele, nicht den Mechanismus. Zwei ID-Spalten auf jeder Tabelle (`tenant_id` und `organisation_id`, ohne dass deren Verhältnis erklärt ist) sind keine Multi-Tenancy. Ohne entschiedenes Isolationsmodell (Scope-basiert, Schema-basiert, DB-basiert) und ohne enforcement-Mechanismus (Global Scope, Row-Level Security, Connection-Switching) ist V1 ein Single-Tenant-System, das *behauptet*, vorbereitet zu sein. Diese Behauptung trägt nicht in V3, wenn Reseller-Strukturen kommen sollen.
**Daten im Core, Logik in Modulen das klassische Anti-Pattern.**
`Rechnung` und `Zahlung` stehen im Core-Datenmodell. Billing-Logik ist als Modul gedacht und über externe Integrationen (Lexware, Invoice Ninja) angebunden. Das ergibt: Module schreiben in Core-Tabellen, kennen also das Core-Schema, und jede Schema-Änderung im Core bricht Module. Saubere Variante: Billing ist eine eigene Bounded-Context-Domäne mit eigenem Datenmodell, der Core kennt höchstens eine `InvoiceReference`-Tabelle ohne semantische Tiefe.
**WordPress-Plugin ist eine zweite Datensphäre ohne Sicherheitsmodell.**
Die Entscheidung gegen WordPress als Core ist richtig und gut begründet (ADR 0001). Die Folgekosten sind aber unterschätzt: Das Plugin ist ein vollständiger API-Client mit eigener Session-Domäne, eigenem Update-Zyklus, eigener Plugin-Ökosystem-Risikofläche und eigener Auth-Brücke zu Hosting-Backoffice. Was passiert, wenn die WP-Site kompromittiert ist welche API-Rechte hatte das Plugin? Gibt es Scope-begrenzte Tokens? Wer ist Mandant aus Sicht der API, wenn ein WP-User auf das Plugin klickt? Diese Fragen sind nicht beantwortet, und Plugin-Entwicklung kann nicht beginnen, bevor sie es sind.
---
## Core- und Modulbewertung
Die Modulstruktur in `module-structure-v0.1.md` ist nicht die einzige Quelle der Wahrheit. Sie listet weniger Module, als das Repository tatsächlich definiert. Vor allem fehlen **Billing** und **Customer Portal** in der Struktur, obwohl sie eigene Modul-Dokumente haben. Vor dem Codebeginn muss diese Liste verbindlich und vollständig sein.
**Was sinnvoll im Core gehört (kleinster nötiger Core):**
- Identity / Authentication (User, Tenant)
- RBAC / Policy
- Audit Trail (append-only)
- Settings / Configuration
- Module Registry & Lifecycle
- Event Bus / Notification Routing (Routing, nicht Channels)
- Tenant Scope Enforcement
**Was aktuell im Core ist und herausgeschoben werden sollte:**
- Domains → eigene Domäne (Service-Modul)
- Hostingpakete → eigene Domäne (Service-Modul)
- Server → eigene Domäne (Service-Modul)
- Dokumente / Content → Document-Archive-Modul (existiert bereits separat warum dann auch im Core?)
- Notifications (Channels, nicht Routing) → eigenes Modul oder Adapter
- Produkte → entweder zu Billing-Domäne oder eigene kleine Domäne
**Module, die fehlen oder unscharf sind:**
- **Billing/Invoicing-Domäne** als eigenständige Service-Domäne (heute im Core-Datenmodell, in Modul-Beschreibung unspezifisch)
- **Mahnwesen / Offene Posten** „kein Payment-System" heißt nicht „kein Forderungsmanagement"
- **DNS-Management** gehört nicht in Domain-Verwaltung
- **Provisioning** Hostingpaket-Lifecycle ist eigene Domäne
- **Tenant-Lifecycle** (Onboarding, Suspend, Offboarding, Export)
- **Secrets-Vault** für Registrar-/Provider-Credentials
- **Reporting/Export** (GoBD-Z3-Export, DSGVO-Auskunft)
- **Webhooks / Outbound-Events** für API-first praktisch zwingend
- **Tax/VAT-Logik** (kein Wort zu MwSt, OSS, Reverse Charge B2B EU)
**Modul-Contract muss formalisiert werden.**
„Definierte Interfaces" reicht nicht. Konkret zu spezifizieren:
- Wie ist ein Modul aufgebaut (Composer-Package, in-app Namespace, Nwidart-Module)
- Wie deklariert ein Modul Abhängigkeiten zur Core-API-Version
- Wie kommunizieren Module untereinander (Events? Service-Contracts? Beides?)
- Was passiert bei Deinstallation eines Moduls mit existierenden Daten und Referenzen
- Wie sind Migrationen pro Modul versioniert und mit Core-Migrationen verzahnt
---
## Datenmodellbewertung
Das Dokument `data-model-v0.1.md` ist kein Datenmodell. Es ist eine Objektliste mit Feldnamen. Die schwierigen Teile fehlen vollständig: Beziehungen, Kardinalitäten, Lebenszyklen, Statusmaschinen, Nummernkreise, Aggregat-Grenzen.
**Konkrete Probleme im aktuellen Stand:**
- `Server.KeyHelp-Referenz` und `Rechnung.externes System` verdrahten konkrete Anbieter im Core und brechen das Adapter-Pattern. Saubere Form: generische `external_references`-Tabelle mit `owner_type`, `owner_id`, `adapter_id`, `external_id`, `metadata`.
- `Registrar-Account.Zugangsdaten/API-Referenzen` impliziert Credentials im Core-Datenmodell. Es darf keine Credential-Spalten in DB-Tabellen geben nur Referenzen in einen Vault.
- `Kunde` enthält „Stammdaten + Ansprechpartner + Kontaktdaten" als undifferenziertes Bündel. Klassisches Anti-Pattern. Üblich: `Party` (Person/Organisation) + `Address` (mit Verwendungszweck) + `ContactPoint`. DSGVO-Auskunft und -Löschung werden sonst sehr teuer.
- `organisation_id` + `tenant_id` parallel ohne erklärte Semantik entweder Duplikat (eines streichen) oder Hierarchie (dann benennen und Modell zeigen).
- B2B/B2C-Unterscheidung fehlt komplett beeinflusst Steuer, AGB, Widerrufsrecht, Rechnungsfelder.
- Nummernkreise (Kundennummer, Vertragsnummer, Rechnungsnummer) pro Mandant lückenlos, GoBD-konform nirgends modelliert.
**Was im Datenmodell fehlt:**
- Statusmaschinen für Vertrag, Domain, Hostingpaket, Ticket, Rechnung mit erlaubten Übergängen
- Beziehungstabellen explizit (Many-to-many: VertragProdukt? DomainVertrag? HostingpaketVertrag?)
- Subscription-/Recurring-Logik (Laufzeit, Up-/Downgrade, Pro-rata)
- Soft-Delete vs. Archivierung vs. DSGVO-Löschung diese drei Anforderungen konkurrieren und müssen entschieden werden
- Audit-Log-Schema (was wird wie granular geloggt, append-only-Mechanismus)
- Versionierung von Belegen (für GoBD: unveränderbar nach Festschreibung)
- Datei-/Asset-Modell mit Hashes, Content-Addressing, Versionen
**Empfehlung:**
Vor dem Codebeginn sollte ein vollständiges ER-Modell (z.B. dbdiagram.io oder vergleichbar) entstehen, das Beziehungen, Kardinalitäten und mindestens die wichtigsten Statusmaschinen zeigt. Aus dem aktuellen Objektliste-Format lassen sich keine sauberen Migrationen ableiten.
---
## API-Bewertung
Die API-Strategie und API-Conventions sind die schwächsten Dokumente im Bestand, gemessen daran, dass „API-first" das zentrale Architekturversprechen ist.
**Was vorhanden ist:**
- URL-Path-Versionierung (`/api/v1/`)
- Ressourcen-Endpoints sinnvoll benannt
- Konsistentes Antwortformat (`data`, `meta`, `errors`)
- Bewusstsein für Auth, Rechteprüfung, Rate-Limiting, Logging
**Was fehlt:**
- **Spec-first**: Kein OpenAPI/AsyncAPI-Dokument. Ohne maschinenlesbare API-Spec gibt es keinen Vertrag, kein Contract-Testing, keinen Client-Generator, kein verbindliches Schema. Für API-first ist OpenAPI 3.x die Mindestanforderung.
- **Auth-Strategie konkret**: „Tokenbasiert, später OAuth/Sanctum" mischt Konzeptebenen. Konkret zu entscheiden: Sanctum Personal Access Tokens (gut für M2M und einfache Clients), Sanctum SPA-Mode (für eigenes Frontend), oder Passport/OAuth2 (für Drittanbieter-Apps). Antwort: vermutlich Sanctum für V1 (alles), Passport in V2/V3 wenn das WP-Plugin von Mandant zu Mandant deployed wird.
- **Idempotenz**: Bei `POST` auf Domain-Registrierung, Vertragsanlage, Rechnungserstellung essentiell. Idempotency-Key-Header sollte Standard sein.
- **Pagination-Strategie**: Offset/Limit, Cursor, Page? Cursor ist für skalierende APIs robuster.
- **Filtering & Sorting**: einheitliches Schema (z.B. `filter[status]=open`, `sort=-created_at`).
- **Error-Modell**: Problem Details (RFC 7807) ist Standard kein einzelnes Wort dazu.
- **Deprecation/Sunset**: `/api/v2/` ohne Strategie, wie alte Versionen abgekündigt werden.
- **Webhooks**: Out-of-band Notifications nach außen (an WordPress-Plugin, an Integratoren) sind in den V1-Plänen unsichtbar.
- **Rate-Limit pro Mandant**: nicht nur pro IP/Token, sondern pro Tenant-Budget.
**Empfehlung:**
Bevor der erste Endpoint implementiert wird, sollte ein OpenAPI-Stub mit den ~20 wichtigsten Ressourcen und Auth-Flows entstehen. Daraus folgen Controller-Skelette, Resource-Klassen und Validation Rules praktisch automatisch.
---
## Mandantenfähigkeitsbewertung
Dies ist der größte einzelne Risikobereich des Projekts.
**Aktueller Stand:**
- Multi-Tenancy-Strategie listet Ziele, keinen Mechanismus
- V1 ist explizit Single-Tenant
- `tenant_id` und `organisation_id` werden auf alle Tabellen gehängt
- Sicherheitsprinzip lautet: „Mandanten dürfen niemals auf fremde Daten zugreifen"
**Was problematisch ist:**
1. **„Vorbereiten" ohne Mechanismus** ist keine Vorbereitung. Wenn V1 ohne Tenant-Scope-Enforcement implementiert wird (Global Scopes, Policy-Checks, RLS, Connection-Switching), wird jede Query, jede Policy, jeder Job, jeder Cache-Key, jeder Webhook und jede Integration beim Multi-Tenant-Schritt aufgegriffen werden müssen.
2. **Zwei IDs ohne erklärtes Modell.** Falls die Doppelung eine Hierarchie meint (z.B. Plattformbetreiber → Reseller-Organisation → Mandant), muss das ER-Modell die Hierarchie zeigen. Falls beides Synonym ist, muss eines weg.
3. **Tenant-Lifecycle nirgends modelliert.** Provisioning, Suspend, Termination, Datenexport, Datenmigration, Offboarding keine dieser Operationen ist beschrieben. Bei DSGVO-Beendigung muss ein Mandant seine Daten innerhalb angemessener Frist erhalten und der Plattformbetreiber sie löschen können (mit GoBD-Vorbehalt).
4. **Cross-Tenant-Datenflüsse** (z.B. shared Templates, shared Knowledge Base, shared Module Registry) architektonisch nicht vorgesehen, aber realistisch.
**Empfehlung:**
- Tenancy-Modell *jetzt* entscheiden mein Vorschlag: Shared Database, Tenant-ID-Scope, Row-Level Security on Postgres als zweite Verteidigungsschicht. Begründung: gut testbar, ein Schema, gute Migration-Hygiene, RLS als Defense-in-Depth, später ohne Datenstruktur-Bruch auf DB-per-Tenant für Premium-Mandanten erweiterbar.
- Tenant-Scope von Tag 1 als Global Scope auf allen mandantenscoped Eloquent-Modellen.
- Verpflichtende Tenant-ID-Spalte auf allen mandantenrelevanten Tabellen mit FK, NOT NULL, indexed.
- Audit-Test in CI: keine Query ohne Tenant-Scope (statische Analyse oder Runtime-Assertion).
- Klarstellung `organisation_id` vs. `tenant_id` mit ER-Modell.
---
## V1-Scope-Bewertung
V1 hat ein klares Erfolgsversprechen („Ordnung schaffen für kleine Anbieter mit 150 Kunden"), das durch die V1-Non-Goals-Disziplin unterstützt wird. Allerdings ist V1 intern nicht konsistent und an mehreren Stellen ambitionierter, als das Erfolgsversprechen rechtfertigt.
**Was widersprüchlich oder zu groß ist:**
- **KI-Assistent** ist v0.1-Modul, aber Roadmap listet KI in V2. KI bringt DSGVO-Subprozessor-Komplexität (Auftragsverarbeitung, Drittlandtransfer), die V1 nicht braucht. Empfehlung: aus V1 raus, in V2 zusammen mit WordPress-Plugin.
- **Customer Portal** ist v0.1-Modul, fehlt aber in den MVP-Muss-Funktionen. Empfehlung: explizit entscheiden. Wenn V1 kein Kundenportal hat, sind viele Folgekosten weg (Self-Service-Auth, BFSG, AGB-Annahme). Wenn ja, dann mit reduziertem Funktionsumfang.
- **SEPA-Lastschrift** als V1-Zahlungsart ohne SEPA-Modell (Mandate, UMR, Pre-Notification, IBAN-Speicherung). Empfehlung: Lastschrift aus V1 raus oder Modell ergänzen.
- **1blu Business** + **KeyHelp** als V1-Integrationen mit Import-Funktion realistisch für 35 Pilotkunden, aber **API-Sync** sollte explizit V2 bleiben (steht so in der Roadmap, sollte aber auch im V1-Modul-Dokument klargestellt sein).
- **PayPal, Wero** als V1-Zahlungsarten sind Zahlungsarten reine Anzeige/Status (dann OK) oder Integrationen (dann viel mehr Aufwand)? Aktuell mehrdeutig.
**Was in V1 fehlt und gebraucht wird:**
- **Steuer-/MwSt-Logik** mindestens minimal (deutscher Standardfall, mit Erweiterbarkeit für EU-OSS)
- **Mahnwesen** mindestens als Status („überfällig" + manuelle Erinnerung) steht in V1-Non-Goals als „eigenes Mahnwesen in voller Tiefe", aber ohne *jegliches* Mahnwesen ist Hosting-Betrieb nicht durchführbar
- **DSGVO-Auskunft** als Funktion (Datenexport pro Endkunde) wenn V1 wirklich produktiv genutzt wird, ist das Pflicht
- **Nummernkreis-Verwaltung** (mindestens Rechnungs- und Kundennummer pro Mandant)
- **E-Mail-Versand-Infrastruktur** (SMTP/Transactional Mail, SPF/DKIM/DMARC-Hinweise)
**Empfehlung:**
- V1-Kundenzahl auf 150 vereinheitlichen (Roadmap-Wert).
- KI raus aus V1.
- Customer Portal entweder explizit IN oder OUT, mit allen Folgekosten.
- SEPA aus V1 raus oder vollständig modellieren.
- Tax und Nummernkreise als V1-Pflicht ergänzen.
---
## Roadmap-Bewertung
Die V1→V2→V3-Progression ist als Konzept stimmig. V1 schafft Ordnung, V2 automatisiert, V3 öffnet Plattform-Funktionen. Das Problem liegt in den V1-Vorarbeiten für V2/V3.
**Was V2/V3 voraussetzt und V1 nicht liefert:**
- V3-Reseller / tiefere Mandantenfähigkeit: setzt voraus, dass V1 strikten Tenant-Scope von Tag 1 hat. V1 hat das aktuell nicht.
- V3-Servermigration: setzt voraus, dass Hostingpaket-Server-Zuordnung versioniert und auditierbar ist. V1 hat heute nur eine direkte Zuordnung ohne History.
- V2-API-Synchronisation: setzt voraus, dass externe Referenzen als generisches Pattern existieren. V1 hat hartkodierte Anbieter-Referenzen.
- V2-WordPress-Plugin: setzt voraus, dass die API ein vollständiger, versionierter, mit Auth-Scopes versehener Vertrag ist. V1 hat „/api/v1/" ohne Vertrag.
- V2-KI-Funktionen: setzt DSGVO-Auftragsverarbeitungsmodell und Subprozessor-Transparenz voraus. Beides fehlt.
**Empfehlung:**
Die Roadmap sollte um eine Spalte ergänzt werden: *„V1-Voraussetzungen für dieses V2/V3-Feature"*. Jedes V2/V3-Feature, dessen V1-Voraussetzungen heute fehlen, ist entweder ein verstecktes V1-Item oder ein gefährlicher Selbstbetrug.
---
## Empfehlungen für die nächste Arbeitsphase
Diese Empfehlungen sind die Konsequenz der bisherigen Bewertung. Sie sind in absteigender Priorität sortiert.
### 1. NOW-Entscheidungen vor Codebeginn
Zehn Entscheidungen, die *jetzt* fallen müssen:
1. **Tenancy-Modell konkret entscheiden** (Vorschlag: Shared DB + Tenant-Scope + Postgres RLS)
2. **Datenbank-Engine entscheiden** (Postgres empfohlen, weil RLS, JSONB, transaktionales DDL)
3. **`organisation_id` vs. `tenant_id` klären** und einen davon streichen, oder Hierarchie als ER-Modell
4. **Auth-Stack festlegen** (Vorschlag: Sanctum für V1, Passport für V2 WP-Plugin)
5. **Modul-Container festlegen** (Composer-Packages, Nwidart-Module, oder eigenes Modul-System)
6. **Secrets-Strategie** (Laravel Encryption nicht ausreichend für Mandanten-Credentials; eigener Vault-Service oder externer Secret-Manager)
7. **Frontend-Modell** (Blade-Renderer als API-Konsument *oder* echtes SPA nicht „später entscheiden")
8. **GoBD-Eigner** (ist Hosting-Backoffice der Beleg-Originalspeicher oder nur Spiegel? Empfehlung: Spiegel)
9. **KI-Assistent V1 oder V2** (Empfehlung: V2)
10. **Customer Portal V1 oder V2** (Empfehlung: V2, falls möglich)
### 2. Strukturhygiene vor Codebeginn
- Modulstruktur in `module-structure-v0.1.md` als einzige Wahrheit etablieren. Alle Modul-Dokumente müssen darin gelistet sein.
- Roadmap und MVP-Liste auf gleichen Kundenzahl-Bereich (150) bringen.
- Adapter-Pattern-Konformität im Datenmodell herstellen: keine anbieter-spezifischen Felder im Core, generische `external_references`.
- ADRs ergänzen: ADR 0004 (Tenancy-Modell), ADR 0005 (Datenbankwahl), ADR 0006 (Auth-Strategie), ADR 0007 (Modul-Container), ADR 0008 (GoBD-Verantwortlichkeit).
### 3. Datenmodell auf v0.2 bringen
- ER-Diagramm mit Beziehungen und Kardinalitäten
- Statusmaschinen für Vertrag, Domain, Hostingpaket, Ticket, Rechnung
- Party/Address/ContactPoint-Trennung statt monolithischem `Kunde`-Objekt
- Nummernkreis-Mechanismus
- Generisches External-Reference-Pattern
- Audit-Log-Schema mit Unveränderbarkeitsmechanismus
### 4. API-Vertrag vor Endpoint-Implementierung
- OpenAPI 3.x als verbindliche API-Spezifikation
- Auth-Flows dokumentiert
- Idempotency-, Pagination-, Filtering-, Error-Modell festgelegt
- Webhook-Strategie als eigenes Dokument
### 5. V1 weiter verschlanken
- KI raus
- Customer Portal entscheiden (idealerweise raus)
- SEPA raus oder vollständig modellieren
- Aber: Tax, Nummernkreise, einfaches Mahnwesen, DSGVO-Auskunft hinzunehmen
### 6. Was bewusst nicht jetzt entschieden werden muss
- SaaS-vs-Self-hosted-Mix
- Konkrete Cloud-Strategie
- Marketplace-/Reseller-Detail
- Mehrsprachigkeit (außer dass UI-Layer das nicht blockiert)
- Mobile App
Diese Bereiche dürfen in v0.x bleiben sie sind unkritisch für die Architekturqualität.
---
## Schlussbemerkung
Hosting-Backoffice ist nicht in der Gefahr, ein schlechtes Produkt zu werden. Vision, Positionierung und Disziplin sind über dem Branchendurchschnitt. Es ist aber in der Gefahr, **als modulares Produkt geplant und als verstecker Monolith gebaut zu werden**, wenn die hier beschriebenen NOW-Entscheidungen nicht vor dem ersten Endpoint fallen. Die einzelnen Probleme sind alle lösbar aber in Summe und ungelöst sind sie das Material, aus dem teure Refactorings gemacht sind.
Die nächste Arbeitsphase sollte nicht „mit V1-Implementierung beginnen" heißen, sondern „v0.2 mit den entschiedenen NOW-Punkten herausgeben". Erst dann lohnt sich Code.
+62
View File
@@ -0,0 +1,62 @@
# Offene Entscheidungen für Olaf
## Zweck
Diese Datei sammelt Punkte, bei denen später eine geschäftliche oder strategische Entscheidung nötig ist.
Technische Architekturentscheidungen wurden soweit sinnvoll vorbereitet.
## 1. SaaS oder Self-hosted?
### Kurz erklärt
SaaS bedeutet:
Du betreibst die Software zentral für Kunden.
Self-hosted bedeutet:
Kunden installieren/betreiben die Software selbst.
### Empfehlung aktuell
Noch nicht final entscheiden.
V1 als eigene interne produktive Instanz planen.
Später SaaS-/Self-hosted-Strategie bewerten.
## 2. Customer Portal in V2 wirklich öffentlich?
### Kurz erklärt
Ein öffentliches Kundenportal bedeutet, dass Endkunden sich selbst einloggen können.
### Empfehlung aktuell
V1 ohne öffentliches Portal.
V2 bewusst entscheiden.
## 3. WordPress-Plugin früh oder später?
### Empfehlung aktuell
Architektur vorbereiten, aber nicht in V1 bauen.
## 4. KI-Assistent
### Empfehlung aktuell
Nicht V1.
In V2 neu bewerten, wenn Datenschutz- und Anbieterfrage klar ist.
## 5. Zahlungsarten mit Gebühren
### Kurz erklärt
Ein Zahlungsaufschlag für bestimmte Zahlungsarten kann rechtlich heikel sein.
### Empfehlung aktuell
Architektur erlaubt Gebührenregeln.
Aktivierung erst nach rechtlicher Prüfung.
## 6. Invoice Ninja als echte Alternative zu Lexware?
### Empfehlung aktuell
Als Referenz-/Integrationsziel ja.
Aber GoBD-Rolle sauber prüfen, wenn produktiv für echte Rechnungen genutzt.
## 7. Marke / Produktname
### Empfehlung aktuell
Später separat behandeln.
Nicht vor Architektur v0.2 abschließend entscheiden.
@@ -0,0 +1,12 @@
# Perplexity Research Placeholder
Hier können spätere Rechercheergebnisse abgelegt werden.
Themen:
- WHMCS-Alternativen
- KeyHelp API
- Lexware API
- Invoice Ninja CE
- 1blu Export/API
- GoBD-Archivierung
- Wero/Payment-Integration
+32
View File
@@ -0,0 +1,32 @@
# Review Notes Template
## Quelle / Modell
## Datum
## Thema
## Wichtigste Erkenntnisse
-
## Risiken
-
## Vorschläge
-
## Entscheidung erforderlich?
Ja / Nein
## Übernahme ins Projekt
- übernehmen
- später prüfen
- verwerfen