Add AI workspace reviews
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user