Add AI workspace reviews
This commit is contained in:
@@ -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.
|
||||
@@ -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 (3–5 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 1–500 vs. 1–50. 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 1–50 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 2–4 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.
|
||||
@@ -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: 1–50 oder 1–500? (Empfehlung: 1–50, 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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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: 1–500 Kunden (Vision) vs. 1–50 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: Vertrag–Produkt? Domain–Vertrag? Hostingpaket–Vertrag?)
|
||||
- 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 1–50 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 3–5 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 1–50 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 (1–50) 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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user