Add AI workspace reviews
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Entscheidung 0001: Standalone-Core statt WordPress-Core
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Das Hosting-Backoffice wird als eigenständiges Laravel-System entwickelt.
|
||||
|
||||
WordPress wird nicht als Kernsystem verwendet, sondern später optional über ein Plugin angebunden.
|
||||
|
||||
## Begründung
|
||||
|
||||
- höhere Sicherheit
|
||||
- bessere Kontrolle über Rechte, Daten und APIs
|
||||
- weniger Abhängigkeit von Fremdplugins
|
||||
- bessere Skalierbarkeit
|
||||
- sauberere Modularchitektur
|
||||
- bessere Trennung zwischen Backoffice und Frontend
|
||||
|
||||
## Zielarchitektur
|
||||
|
||||
Standalone-Core + REST API + optionale Integrationen + optionales WordPress-Plugin.
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Entscheidung 0002: Kundenzentriertes Hosting-Backoffice
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Das System wird kundenzentriert aufgebaut.
|
||||
|
||||
Nicht Server, Domains oder Rechnungen stehen im Zentrum, sondern der Kunde mit allen zugehörigen Objekten.
|
||||
|
||||
## Zentrale Sicht
|
||||
|
||||
Kunde:
|
||||
- Verträge
|
||||
- Domains
|
||||
- Hostingpakete
|
||||
- Serverbezug
|
||||
- Rechnungen
|
||||
- Zahlungen
|
||||
- Tickets
|
||||
- Dokumente
|
||||
- Historie
|
||||
|
||||
## Begründung
|
||||
|
||||
Ein kleines Hostinggeschäft benötigt vor allem Übersicht und Beziehungskontext. Support, Abrechnung und technische Informationen müssen aus einer Kundenakte heraus verständlich sein.
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Entscheidung 0003: Kein eigenes Payment-/Banking-System
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Hosting-Backoffice wird keine eigene Zahlungs- oder Banking-Plattform.
|
||||
|
||||
Das System verwaltet Zahlungsarten, Zahlungsstatus, Hinweise, externe Referenzen und spätere Gebührenregeln. Die eigentliche Zahlungsabwicklung erfolgt über externe Anbieter oder Rechnungssysteme.
|
||||
|
||||
## Begründung
|
||||
|
||||
- weniger rechtliche Risiken
|
||||
- weniger Sicherheitsrisiken
|
||||
- weniger Compliance-Aufwand
|
||||
- keine unnötige PCI-/Banking-Komplexität
|
||||
- bessere Austauschbarkeit externer Anbieter
|
||||
|
||||
## Beispiele
|
||||
|
||||
- Lexware Office
|
||||
- Invoice Ninja CE
|
||||
- PayPal
|
||||
- Wero
|
||||
- SEPA-/Bankprozesse außerhalb des Cores
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert.
|
||||
@@ -0,0 +1,162 @@
|
||||
# ADR 0004 — Tenancy-Modell
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Tenancy bedeutet Mandantenfähigkeit.
|
||||
|
||||
Ein Mandant ist z. B. ein Anbieter, eine Agentur oder später ein Reseller, der seine eigenen Kunden, Verträge, Domains und Rechnungen verwaltet.
|
||||
|
||||
Das Tenancy-Modell legt fest, wie Daten verschiedener Mandanten technisch voneinander getrennt werden.
|
||||
|
||||
## Kontext
|
||||
Hosting-Backoffice soll zunächst einfach nutzbar sein, später aber mandantenfähig und ggf. resellerfähig erweitert werden können.
|
||||
|
||||
Die bisherige Planung enthielt die Begriffe `tenant_id` und `organisation_id`, ohne deren Verhältnis eindeutig zu definieren.
|
||||
|
||||
Das wurde im Architekturreview als kritisches Risiko bewertet, da eine nachträgliche Mandantenfähigkeit sehr teuer und fehleranfällig wäre.
|
||||
|
||||
## Entscheidung
|
||||
Hosting-Backoffice verwendet von Beginn an ein mandantenfähiges Datenmodell mit:
|
||||
|
||||
- `tenant_id` als zentrale Mandantenreferenz
|
||||
- Shared Database Modell
|
||||
- PostgreSQL als bevorzugte Datenbank
|
||||
- Tenant Scope auf Anwendungsebene
|
||||
- Row Level Security als spätere zusätzliche Sicherheitsschicht
|
||||
|
||||
`organisation_id` wird vorerst nicht als separates Standardfeld verwendet.
|
||||
|
||||
Falls später eine Organisationshierarchie benötigt wird, wird diese über das Tenant-Modell abgebildet.
|
||||
|
||||
## Gewähltes Modell
|
||||
|
||||
```text
|
||||
Platform
|
||||
└── Tenant
|
||||
└── Kunde
|
||||
└── Verträge
|
||||
└── Domains
|
||||
└── Hostingpakete
|
||||
└── Tickets
|
||||
└── Dokumente
|
||||
```
|
||||
|
||||
Später möglich:
|
||||
|
||||
```text
|
||||
Platform
|
||||
└── Tenant
|
||||
└── Reseller-Tenant
|
||||
└── Kunden
|
||||
```
|
||||
|
||||
Dafür kann später ein Feld wie `parent_tenant_id` in der Tenant-Struktur ergänzt oder vorbereitet werden.
|
||||
|
||||
## Begründung
|
||||
Ein Shared-Database-Modell mit `tenant_id` ist für den Start sinnvoll, weil:
|
||||
|
||||
- V1 klein bleiben soll
|
||||
- alle Daten zentral verwaltbar bleiben
|
||||
- Migrationen einfacher sind
|
||||
- Betrieb und Backups weniger komplex sind
|
||||
- spätere Mandantenfähigkeit vorbereitet wird
|
||||
- Resellerstrukturen später möglich bleiben
|
||||
|
||||
PostgreSQL wird bevorzugt, weil es Row Level Security unterstützt.
|
||||
|
||||
Row Level Security bedeutet:
|
||||
|
||||
```text
|
||||
Die Datenbank selbst kann verhindern,
|
||||
dass Mandant A Datensätze von Mandant B sieht.
|
||||
```
|
||||
|
||||
Das ist eine zusätzliche Sicherheitsschicht neben der Anwendung.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- Mandantenfähigkeit wird nicht später „angeklebt“
|
||||
- bessere Grundlage für spätere SaaS-/Resellerfähigkeit
|
||||
- klare Datenisolation
|
||||
- bessere Sicherheitsarchitektur
|
||||
- weniger Refactoring-Risiko
|
||||
|
||||
### Negativ
|
||||
- jede mandantenbezogene Tabelle braucht `tenant_id`
|
||||
- alle Abfragen müssen tenant-aware sein
|
||||
- Entwickler müssen von Anfang an sauber mit Tenant-Kontext arbeiten
|
||||
- Tests müssen Mandantenisolation prüfen
|
||||
|
||||
## Technische Leitlinien
|
||||
Alle mandantenbezogenen Tabellen erhalten:
|
||||
|
||||
```text
|
||||
tenant_id
|
||||
```
|
||||
|
||||
Beispiele:
|
||||
|
||||
```text
|
||||
customers.tenant_id
|
||||
contracts.tenant_id
|
||||
domains.tenant_id
|
||||
hosting_packages.tenant_id
|
||||
tickets.tenant_id
|
||||
documents.tenant_id
|
||||
```
|
||||
|
||||
Nicht mandantenbezogene Tabellen können global sein, z. B.:
|
||||
|
||||
```text
|
||||
system_settings
|
||||
module_registry
|
||||
global_permissions
|
||||
```
|
||||
|
||||
## Anwendungsebene
|
||||
Laravel soll sicherstellen, dass mandantenbezogene Daten nur im aktuellen Tenant-Kontext geladen werden.
|
||||
|
||||
Dafür vorgesehen:
|
||||
|
||||
- Tenant Context
|
||||
- Eloquent Global Scopes
|
||||
- Policies
|
||||
- Tests gegen Tenant-Leaks
|
||||
|
||||
Tenant-Leak bedeutet:
|
||||
|
||||
```text
|
||||
Ein Benutzer oder Prozess sieht versehentlich Daten eines anderen Mandanten.
|
||||
```
|
||||
|
||||
## Datenbankebene
|
||||
PostgreSQL Row Level Security soll als spätere zweite Schutzschicht vorbereitet werden.
|
||||
|
||||
V1 kann zunächst mit sauberem Tenant Scope in Laravel starten.
|
||||
|
||||
RLS sollte jedoch nicht durch Datenmodellentscheidungen blockiert werden.
|
||||
|
||||
## Offene Punkte
|
||||
Noch zu klären:
|
||||
|
||||
- genaue Tenant-Tabelle
|
||||
- ob `parent_tenant_id` sofort angelegt wird
|
||||
- ob V1 technisch bereits echtes Multi-Tenant-Login erlaubt
|
||||
- wie Plattform-Admins mandantenübergreifend arbeiten dürfen
|
||||
- wie Tenant-Offboarding später funktioniert
|
||||
|
||||
## Nicht entschieden
|
||||
Diese ADR entscheidet noch nicht:
|
||||
|
||||
- ob Hosting-Backoffice später SaaS oder nur self-hosted wird
|
||||
- ob einzelne Mandanten später eigene Datenbanken erhalten können
|
||||
- ob Resellerstrukturen bereits in V1 aktiv sichtbar sind
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0005 — Datenbankwahl
|
||||
- ADR 0006 — Auth-Strategie
|
||||
- ADR 0009 — Core-Grenzen
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
@@ -0,0 +1,80 @@
|
||||
# ADR 0005 — Datenbankwahl
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Die Datenbank ist der zentrale Speicher für Kunden, Verträge, Domains, Tickets, Dokumente und technische Referenzen.
|
||||
|
||||
Die Wahl der Datenbank beeinflusst später besonders:
|
||||
|
||||
- Mandantenfähigkeit
|
||||
- Sicherheit
|
||||
- Performance
|
||||
- Auditierbarkeit
|
||||
- Skalierbarkeit
|
||||
- Entwicklungsaufwand
|
||||
|
||||
## Kontext
|
||||
In der ersten Planung waren MariaDB und PostgreSQL offen.
|
||||
|
||||
Das Architekturreview hat kritisiert, dass eine offene Datenbankwahl bei Multi-Tenancy und API-first zu einem kleinsten gemeinsamen Nenner führen würde.
|
||||
|
||||
## Entscheidung
|
||||
Hosting-Backoffice verwendet PostgreSQL als primäre Datenbank.
|
||||
|
||||
## Begründung
|
||||
PostgreSQL bietet wichtige Funktionen für das Zielbild:
|
||||
|
||||
- Row Level Security
|
||||
- starke Datenintegrität
|
||||
- JSONB-Unterstützung
|
||||
- gute Indexierungsoptionen
|
||||
- transaktionale Migrationen
|
||||
- gute Grundlage für Mandantenfähigkeit
|
||||
- gute Grundlage für spätere SaaS-/Reseller-Strukturen
|
||||
|
||||
## Row Level Security
|
||||
Row Level Security bedeutet:
|
||||
|
||||
```text
|
||||
Die Datenbank kann Regeln erzwingen,
|
||||
welche Datensätze ein Benutzer oder Prozess sehen darf.
|
||||
```
|
||||
|
||||
Das ist besonders relevant, wenn mehrere Mandanten in einer gemeinsamen Datenbank verwaltet werden.
|
||||
|
||||
## Nicht gewählt
|
||||
|
||||
### MariaDB / MySQL
|
||||
Vorteile:
|
||||
|
||||
- sehr weit verbreitet
|
||||
- vielen Hostern bekannt
|
||||
- einfacher Einstieg
|
||||
|
||||
Nachteile:
|
||||
|
||||
- schwächer für Row-Level-Isolation
|
||||
- schwächer als Sicherheitsbasis für Mandantenfähigkeit
|
||||
- langfristig weniger geeignet für das geplante SaaS-/Reseller-Modell
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- bessere Sicherheitsarchitektur
|
||||
- bessere Grundlage für Multi-Tenancy
|
||||
- bessere technische Zukunftsfähigkeit
|
||||
|
||||
### Negativ
|
||||
- etwas höhere Einstiegshürde
|
||||
- nicht jeder kleine Shared-Hosting-Anbieter bietet PostgreSQL gleichwertig an
|
||||
- Self-hosted-Installationen benötigen klare Systemvoraussetzungen
|
||||
|
||||
## Leitlinie
|
||||
Hosting-Backoffice wird nicht primär für beliebiges Billig-Shared-Hosting optimiert, sondern für eine seriöse, betreibbare Hosting-/Backoffice-Umgebung.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0004 — Tenancy-Modell
|
||||
- ADR 0010 — Secrets-Management
|
||||
- ADR 0014 — Audit-Log-Strategie
|
||||
@@ -0,0 +1,96 @@
|
||||
# ADR 0006 — Auth-Strategie
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Auth bedeutet Authentifizierung und Autorisierung.
|
||||
|
||||
Authentifizierung beantwortet:
|
||||
|
||||
```text
|
||||
Wer bist du?
|
||||
```
|
||||
|
||||
Autorisierung beantwortet:
|
||||
|
||||
```text
|
||||
Was darfst du?
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das System benötigt mehrere Zugriffstypen:
|
||||
|
||||
- Admin-Login
|
||||
- Mitarbeiter-Login
|
||||
- Kundenlogin später
|
||||
- API-Zugriffe
|
||||
- Integrationen
|
||||
- später WordPress-Plugin
|
||||
|
||||
Das Architekturreview hat kritisiert, dass „Tokenbasiert, später OAuth/Sanctum“ zu unscharf ist.
|
||||
|
||||
## Entscheidung
|
||||
V1 verwendet Laravel Sanctum als Auth-Basis.
|
||||
|
||||
Sanctum wird genutzt für:
|
||||
|
||||
- Admin-/Backoffice-Login
|
||||
- interne API
|
||||
- Personal Access Tokens für technische Clients
|
||||
- spätere einfache API-Zugriffe
|
||||
|
||||
OAuth2/Passport wird nicht in V1 eingeführt.
|
||||
|
||||
## Warum Sanctum?
|
||||
Sanctum ist für V1 passend, weil:
|
||||
|
||||
- es Laravel-nah ist
|
||||
- wenig Overhead erzeugt
|
||||
- API-Tokens unterstützt
|
||||
- SPA-/Frontend-Sessions unterstützt
|
||||
- für ein kleines V1-Team einfacher beherrschbar ist
|
||||
|
||||
## OAuth2 später
|
||||
OAuth2 kann später relevant werden für:
|
||||
|
||||
- Drittanbieter-Apps
|
||||
- öffentliches Plugin-Ökosystem
|
||||
- externe Entwickler
|
||||
- komplexere WordPress-Plugin-Szenarien
|
||||
|
||||
## Rechteprüfung
|
||||
Auth allein reicht nicht.
|
||||
|
||||
Jeder Zugriff benötigt zusätzlich:
|
||||
|
||||
- Tenant-Kontext
|
||||
- Rollenprüfung
|
||||
- Policy-Prüfung
|
||||
- Auditierbarkeit bei kritischen Aktionen
|
||||
|
||||
## MFA
|
||||
MFA bedeutet Multi-Faktor-Authentifizierung.
|
||||
|
||||
Für V1 gilt:
|
||||
|
||||
- MFA für Superadmins empfohlen
|
||||
- MFA für normale Kunden optional später
|
||||
- WebAuthn kann später geprüft werden
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- einfacher Einstieg
|
||||
- Laravel-nah
|
||||
- gut für V1
|
||||
- weniger Komplexität
|
||||
|
||||
### Negativ
|
||||
- für öffentliche Drittanbieter-Ökosysteme später eventuell nicht ausreichend
|
||||
- OAuth2 muss ggf. später zusätzlich eingeführt werden
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0004 — Tenancy-Modell
|
||||
- ADR 0012 — Frontend-Strategie
|
||||
- ADR 0018 — WordPress-Plugin-Security
|
||||
@@ -0,0 +1,102 @@
|
||||
# ADR 0007 — Modul-System
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Das Modul-System legt fest, wie Funktionen voneinander getrennt werden.
|
||||
|
||||
Ziel ist:
|
||||
|
||||
```text
|
||||
modular denken,
|
||||
aber V1 nicht technisch überkomplizieren.
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das Projekt soll kein klassischer Monolith werden.
|
||||
|
||||
Gleichzeitig wäre ein echtes Microservice-System für V1 zu komplex.
|
||||
|
||||
## Entscheidung
|
||||
V1 verwendet ein modulares In-App-Modell innerhalb einer Laravel-Anwendung.
|
||||
|
||||
Module sind logisch getrennt, laufen aber im selben Deployment.
|
||||
|
||||
## Warum kein Microservice-System?
|
||||
Microservices bedeuten:
|
||||
|
||||
- mehrere Deployments
|
||||
- mehrere Services
|
||||
- Service-Kommunikation
|
||||
- verteiltes Logging
|
||||
- verteilte Fehlerbilder
|
||||
- mehr DevOps-Aufwand
|
||||
|
||||
Für V1 wäre das zu schwer.
|
||||
|
||||
## Modularten
|
||||
|
||||
### Core
|
||||
Minimaler Plattformkern.
|
||||
|
||||
### Service-Module
|
||||
Fachliche Module wie:
|
||||
|
||||
- Kunden
|
||||
- Verträge
|
||||
- Domains
|
||||
- Hosting
|
||||
- Tickets
|
||||
- Dokumente
|
||||
- Billing
|
||||
|
||||
### Integrationsmodule
|
||||
Adapter zu externen Systemen wie:
|
||||
|
||||
- KeyHelp
|
||||
- 1blu
|
||||
- Lexware
|
||||
- Invoice Ninja
|
||||
|
||||
## Technische Leitlinien
|
||||
Module kommunizieren über:
|
||||
|
||||
- Service-Contracts
|
||||
- Events
|
||||
- definierte Interfaces
|
||||
|
||||
Nicht erlaubt:
|
||||
|
||||
```text
|
||||
Modul A verändert ungeprüft interne Tabellen von Modul B.
|
||||
```
|
||||
|
||||
## Modul-Lifecycle
|
||||
Module sollen später Zustände haben:
|
||||
|
||||
- installiert
|
||||
- aktiviert
|
||||
- deaktiviert
|
||||
- aktualisiert
|
||||
- archiviert
|
||||
|
||||
Deinstallation mit Datenlöschung ist nicht Standard.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- V1 bleibt betreibbar
|
||||
- Architektur bleibt modular
|
||||
- keine Microservice-Komplexität
|
||||
- spätere Auslagerung einzelner Module bleibt möglich
|
||||
|
||||
### Negativ
|
||||
- strikte Disziplin nötig
|
||||
- Modulgrenzen müssen geprüft werden
|
||||
- ohne klare Contracts droht trotzdem ein Monolith
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0009 — Core-Grenzen
|
||||
- ADR 0008 — External-Reference-Pattern
|
||||
- ADR 0016 — Modul-Lifecycle
|
||||
@@ -0,0 +1,97 @@
|
||||
# ADR 0008 — External-Reference-Pattern
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
External Reference bedeutet:
|
||||
|
||||
```text
|
||||
Ein internes Objekt merkt sich,
|
||||
wie es in einem externen System heißt.
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
- Kunde im Backoffice
|
||||
- derselbe Kunde in Lexware
|
||||
- dieselbe Domain bei 1blu
|
||||
- derselbe Hostingaccount in KeyHelp
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass konkrete Anbieterfelder wie `keyhelp_id` oder `lexware_id` im Core das Adapter-Pattern zerstören würden.
|
||||
|
||||
## Entscheidung
|
||||
Hosting-Backoffice verwendet ein generisches External-Reference-Pattern.
|
||||
|
||||
Der Core erhält keine Anbieterfelder wie:
|
||||
|
||||
```text
|
||||
keyhelp_id
|
||||
lexware_id
|
||||
oneblu_id
|
||||
```
|
||||
|
||||
Stattdessen gibt es eine generische Referenzstruktur.
|
||||
|
||||
## Beispielstruktur
|
||||
|
||||
```text
|
||||
external_references
|
||||
- id
|
||||
- tenant_id
|
||||
- owner_type
|
||||
- owner_id
|
||||
- provider
|
||||
- provider_account_id
|
||||
- external_id
|
||||
- external_type
|
||||
- metadata
|
||||
- last_synced_at
|
||||
- created_at
|
||||
- updated_at
|
||||
```
|
||||
|
||||
## Beispiel
|
||||
|
||||
```text
|
||||
owner_type: Domain
|
||||
owner_id: 123
|
||||
provider: 1blu
|
||||
external_id: ABC-987
|
||||
```
|
||||
|
||||
Oder:
|
||||
|
||||
```text
|
||||
owner_type: Server
|
||||
owner_id: 55
|
||||
provider: KeyHelp
|
||||
external_id: server-user-4711
|
||||
```
|
||||
|
||||
## Begründung
|
||||
Dieses Pattern sorgt für:
|
||||
|
||||
- Providerneutralität
|
||||
- weniger Core-Abhängigkeiten
|
||||
- einfachere neue Integrationen
|
||||
- saubere Migrationen
|
||||
- bessere Austauschbarkeit von Modulen
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- keine harte Anbieterlogik im Core
|
||||
- bessere Erweiterbarkeit
|
||||
- sauberer Wechsel von Anbietern möglich
|
||||
|
||||
### Negativ
|
||||
- etwas komplexeres Datenmodell
|
||||
- Entwickler müssen über Adapter denken
|
||||
- direkte Fremdschlüssel zu externen Systemen sind nicht erlaubt
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0007 — Modul-System
|
||||
- ADR 0009 — Core-Grenzen
|
||||
- ADR 0017 — Adapter-Fehlerresilienz
|
||||
@@ -0,0 +1,106 @@
|
||||
# ADR 0009 — Core-Grenzen
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Core-Grenzen legen fest, was wirklich in den Plattformkern gehört.
|
||||
|
||||
Je größer der Core wird, desto höher ist das Risiko, dass das System trotz Modulidee zu einem Monolithen wird.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass der bisherige Core zu groß definiert war.
|
||||
|
||||
Bisher waren u. a. Kunden, Domains, Server, Produkte, Dokumente und Benachrichtigungen im Core vorgesehen.
|
||||
|
||||
Das widerspricht dem Ziel eines modularen Systems.
|
||||
|
||||
## Entscheidung
|
||||
Der Core wird bewusst klein gehalten.
|
||||
|
||||
Der Core enthält nur technische und organisatorische Plattformfunktionen, die alle Module benötigen.
|
||||
|
||||
## Core enthält
|
||||
|
||||
- Identity
|
||||
- Authentication
|
||||
- Tenant Context
|
||||
- RBAC / Policies
|
||||
- Audit-Grundstruktur
|
||||
- Module Registry
|
||||
- Settings-Grundstruktur
|
||||
- Event Routing
|
||||
- API-Basis
|
||||
- System Health
|
||||
|
||||
## Core enthält NICHT
|
||||
|
||||
- Kundenfachlogik
|
||||
- Domainfachlogik
|
||||
- Billingfachlogik
|
||||
- Hostingfachlogik
|
||||
- Ticketsystemfachlogik
|
||||
- Dokumentenarchivfachlogik
|
||||
- Anbieterlogik
|
||||
|
||||
Diese Bereiche werden als Service-Module oder Integrationsmodule behandelt.
|
||||
|
||||
## Neue Struktur
|
||||
|
||||
```text
|
||||
Core
|
||||
├── Identity
|
||||
├── Tenancy
|
||||
├── RBAC
|
||||
├── Audit Base
|
||||
├── Module Registry
|
||||
├── Settings Base
|
||||
├── Event Routing
|
||||
└── API Base
|
||||
|
||||
Service Modules
|
||||
├── Customers
|
||||
├── Contracts
|
||||
├── Products
|
||||
├── Domains
|
||||
├── Hosting
|
||||
├── Billing
|
||||
├── Tickets
|
||||
├── Documents
|
||||
└── Notifications
|
||||
|
||||
Integration Modules
|
||||
├── KeyHelp
|
||||
├── 1blu
|
||||
├── Lexware
|
||||
└── Invoice Ninja
|
||||
```
|
||||
|
||||
## Begründung
|
||||
Ein kleiner Core reduziert:
|
||||
|
||||
- Kopplung
|
||||
- Refactoring-Risiken
|
||||
- Monolith-Gefahr
|
||||
- Abhängigkeiten zwischen Fachbereichen
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- sauberere Modulgrenzen
|
||||
- leichter testbar
|
||||
- langfristig besser erweiterbar
|
||||
- neue Integrationen einfacher möglich
|
||||
|
||||
### Negativ
|
||||
- mehr Architekturdisziplin nötig
|
||||
- Module brauchen definierte Contracts
|
||||
- anfänglich mehr Planungsaufwand
|
||||
|
||||
## Regel
|
||||
Wenn ein Bereich fachliche Geschäftslogik enthält, gehört er nicht in den Core.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0007 — Modul-System
|
||||
- ADR 0008 — External-Reference-Pattern
|
||||
- ADR 0016 — Modul-Lifecycle
|
||||
@@ -0,0 +1,99 @@
|
||||
# ADR 0010 — Secrets-Management
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Secrets sind geheime technische Zugangsdaten, z. B.:
|
||||
|
||||
- API-Keys
|
||||
- Registrar-Zugänge
|
||||
- Tokens
|
||||
- Passwörter
|
||||
- Webhook-Secrets
|
||||
|
||||
Secrets dürfen nicht wie normale Stammdaten gespeichert werden.
|
||||
|
||||
## Kontext
|
||||
Hosting-Backoffice wird später Zugangsdaten zu externen Systemen verwalten:
|
||||
|
||||
- KeyHelp
|
||||
- 1blu
|
||||
- Lexware
|
||||
- Invoice Ninja
|
||||
- SMTP
|
||||
- Zahlungsanbieter
|
||||
|
||||
Das Architekturreview hat fehlendes Secrets-Management als kritisches Risiko bewertet.
|
||||
|
||||
## Entscheidung
|
||||
Das Datenmodell speichert keine Secrets direkt in fachlichen Tabellen.
|
||||
|
||||
Fachliche Tabellen speichern nur Referenzen auf Secrets.
|
||||
|
||||
## V1-Strategie
|
||||
Für V1 wird mindestens verwendet:
|
||||
|
||||
- verschlüsselte Speicherung mit Laravel Encryption
|
||||
- getrennte Secret-Tabelle
|
||||
- Zugriff nur über Secret-Service
|
||||
- keine Ausgabe von Secrets im UI
|
||||
- Audit-Log bei Secret-Erstellung/Änderung
|
||||
- Rotation vorbereiten
|
||||
|
||||
## Spätere Strategie
|
||||
Für SaaS- oder größere Multi-Tenant-Nutzung wird ein externer Vault vorbereitet, z. B.:
|
||||
|
||||
- HashiCorp Vault
|
||||
- Bitwarden Secrets Manager
|
||||
- Cloud KMS / Secrets Manager
|
||||
|
||||
## Beispiel
|
||||
|
||||
Nicht erlaubt:
|
||||
|
||||
```text
|
||||
registrar_accounts.api_password
|
||||
```
|
||||
|
||||
Erlaubt:
|
||||
|
||||
```text
|
||||
registrar_accounts.secret_reference_id
|
||||
```
|
||||
|
||||
## Begründung
|
||||
Bei einem Einbruch darf nicht sofort der direkte Zugriff auf alle externen Systeme möglich sein.
|
||||
|
||||
Secrets brauchen:
|
||||
|
||||
- Verschlüsselung
|
||||
- Zugriffskontrolle
|
||||
- Rotation
|
||||
- Auditierung
|
||||
- Mandantenisolation
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- höheres Sicherheitsniveau
|
||||
- bessere Mandantenisolation
|
||||
- spätere Vault-Anbindung möglich
|
||||
|
||||
### Negativ
|
||||
- mehr technische Komplexität
|
||||
- Secret-Service muss früh gebaut werden
|
||||
- Backups müssen besonders betrachtet werden
|
||||
|
||||
## Mindestregeln
|
||||
|
||||
- Secrets nie im Klartext loggen
|
||||
- Secrets nie im UI vollständig anzeigen
|
||||
- Secrets nie in normalen Exporten ausgeben
|
||||
- Secret-Zugriff auditieren
|
||||
- API-Keys rotierbar halten
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0004 — Tenancy-Modell
|
||||
- ADR 0006 — Auth-Strategie
|
||||
- ADR 0017 — Adapter-Fehlerresilienz
|
||||
@@ -0,0 +1,76 @@
|
||||
# ADR 0011 — GoBD-Verantwortlichkeit
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
GoBD beschreibt Anforderungen an ordnungsgemäße Buchführung und Aufbewahrung steuerlich relevanter Daten in Deutschland.
|
||||
|
||||
Wichtige Frage:
|
||||
|
||||
```text
|
||||
Ist Hosting-Backoffice das führende Rechnungssystem
|
||||
oder nur ein Verwaltungs-/Spiegelsystem?
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das System soll Rechnungen anzeigen, archivieren und mit Kunden/Verträgen verknüpfen.
|
||||
|
||||
Gleichzeitig soll die eigentliche Rechnungsstellung über externe Systeme wie Lexware oder Invoice Ninja erfolgen.
|
||||
|
||||
Das Architekturreview hat zurecht bemängelt, dass die GoBD-Rolle nicht eindeutig war.
|
||||
|
||||
## Entscheidung
|
||||
Hosting-Backoffice ist in V1 nicht das führende GoBD-Rechnungssystem.
|
||||
|
||||
Das führende Rechnungssystem ist:
|
||||
|
||||
- Lexware Office
|
||||
- oder Invoice Ninja CE, sofern der Betreiber dies bewusst so nutzt
|
||||
|
||||
Hosting-Backoffice ist in V1:
|
||||
|
||||
- Referenzsystem
|
||||
- Spiegel
|
||||
- Dokumentenablage
|
||||
- Prozess- und Audit-System
|
||||
|
||||
## Konsequenz
|
||||
Hosting-Backoffice erzeugt in V1 keine steuerlich führenden Originalrechnungen.
|
||||
|
||||
Es speichert:
|
||||
|
||||
- Rechnungsreferenzen
|
||||
- PDF-Kopien
|
||||
- Hashes
|
||||
- Zahlungsstatus-Referenzen
|
||||
- Audit-Ereignisse
|
||||
|
||||
## Begründung
|
||||
Damit werden reduziert:
|
||||
|
||||
- Buchhaltungsrisiken
|
||||
- GoBD-Komplexität
|
||||
- Haftungsfragen
|
||||
- technische Anforderungen an unveränderbare Originalbelege
|
||||
|
||||
## Archivierung
|
||||
PDF-Kopien können gespeichert werden, aber die Originalverantwortung liegt beim externen Billing-System.
|
||||
|
||||
## Später möglich
|
||||
Ein späteres eigenes GoBD-fähiges Billing-Modul wäre möglich, aber nicht Teil von V1.
|
||||
|
||||
Dafür wären nötig:
|
||||
|
||||
- lückenlose Nummernkreise
|
||||
- Beleg-Festschreibung
|
||||
- unveränderbare Speicherung
|
||||
- Exportfunktionen
|
||||
- Verfahrensdokumentation
|
||||
- Steuerlogik
|
||||
- Retention-Strategie
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0014 — Audit-Log-Strategie
|
||||
- ADR 0015 — Tax- und VAT-Strategie
|
||||
- ADR 0021 — DSGVO-Löschung und Retention
|
||||
@@ -0,0 +1,69 @@
|
||||
# ADR 0012 — Frontend-Strategie
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Die Frontend-Strategie legt fest, wie Benutzer die Anwendung bedienen.
|
||||
|
||||
Wichtig ist die Frage:
|
||||
|
||||
```text
|
||||
Klassische Laravel-Seiten
|
||||
oder modernes API-basiertes Frontend?
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass „Blade oder später Vue/Nuxt“ eine offene Grundsatzentscheidung ist.
|
||||
|
||||
Für API-first darf das Frontend nicht direkt an Datenbanklogik hängen.
|
||||
|
||||
## Entscheidung
|
||||
V1 verwendet ein Laravel-basiertes Admin-Frontend, aber strikt über interne Service-/API-Schichten.
|
||||
|
||||
Es wird kein vollständig getrenntes Nuxt/Vue-SPA in V1 gebaut.
|
||||
|
||||
Das Frontend darf nicht direkt fachliche Datenbanklogik umgehen.
|
||||
|
||||
## Warum?
|
||||
Ein vollständiges SPA erhöht V1-Komplexität:
|
||||
|
||||
- separater Build-Prozess
|
||||
- separate Auth-Flows
|
||||
- mehr Frontend-Architektur
|
||||
- mehr Testing-Aufwand
|
||||
|
||||
Für V1 ist ein Laravel-nahes Frontend effizienter.
|
||||
|
||||
## API-first bleibt bestehen
|
||||
API-first bedeutet hier:
|
||||
|
||||
- Geschäftslogik liegt in Services/Contracts
|
||||
- REST API wird parallel sauber definiert
|
||||
- spätere externe Clients bleiben möglich
|
||||
- WordPress-Plugin nutzt später ausschließlich API
|
||||
|
||||
## Später möglich
|
||||
In V2/V3 kann ein SPA-Frontend entstehen, wenn:
|
||||
|
||||
- API stabil ist
|
||||
- Auth-Scopes klar sind
|
||||
- Kundenportal ausgebaut wird
|
||||
- Plugin-/App-Ökosystem entsteht
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- schnellerer V1-Start
|
||||
- weniger Komplexität
|
||||
- gute Laravel-Integration
|
||||
|
||||
### Negativ
|
||||
- API-first muss diszipliniert umgesetzt werden
|
||||
- Gefahr eines klassischen Laravel-Monolithen bleibt
|
||||
- klare Architekturregeln nötig
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0006 — Auth-Strategie
|
||||
- ADR 0018 — WordPress-Plugin-Security
|
||||
- ADR 0020 — Customer-Portal-Scope
|
||||
@@ -0,0 +1,108 @@
|
||||
# ADR 0013 — Kunden-/Adress-/Kontaktmodell
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Ein Kunde ist nicht einfach nur ein Datensatz mit Name, Adresse und E-Mail.
|
||||
|
||||
Es gibt:
|
||||
|
||||
- Privatpersonen
|
||||
- Firmen
|
||||
- Ansprechpartner
|
||||
- Rechnungsadressen
|
||||
- technische Kontakte
|
||||
- abweichende Postadressen
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass das Objekt „Kunde“ zu monolithisch gedacht war.
|
||||
|
||||
Ein zu einfaches Kundenmodell erschwert später:
|
||||
|
||||
- DSGVO-Auskunft
|
||||
- DSGVO-Löschung
|
||||
- B2B/B2C-Unterscheidung
|
||||
- mehrere Ansprechpartner
|
||||
- getrennte Rechnungsadressen
|
||||
- spätere Mandantenfähigkeit
|
||||
|
||||
## Entscheidung
|
||||
Das fachliche Kundenmodell wird aufgeteilt in:
|
||||
|
||||
- Customer
|
||||
- Party
|
||||
- Address
|
||||
- ContactPoint
|
||||
- CustomerContact
|
||||
|
||||
## Begriffe
|
||||
|
||||
### Customer
|
||||
Die Kundenbeziehung im System.
|
||||
|
||||
### Party
|
||||
Eine Person oder Organisation.
|
||||
|
||||
### Address
|
||||
Eine Adresse mit Verwendungszweck, z. B.:
|
||||
|
||||
- Rechnungsadresse
|
||||
- Postadresse
|
||||
- Firmensitz
|
||||
|
||||
### ContactPoint
|
||||
Kontaktmöglichkeit, z. B.:
|
||||
|
||||
- E-Mail
|
||||
- Telefon
|
||||
- Mobil
|
||||
- Website
|
||||
|
||||
### CustomerContact
|
||||
Verknüpfung zwischen Kunde und Ansprechpartner.
|
||||
|
||||
## Beispiel
|
||||
|
||||
```text
|
||||
Customer: Müller Webservice
|
||||
Party: Müller Webservice GmbH
|
||||
Address: Rechnungsadresse
|
||||
ContactPoint: buchhaltung@...
|
||||
ContactPoint: technik@...
|
||||
CustomerContact: Max Müller als technischer Ansprechpartner
|
||||
```
|
||||
|
||||
## B2B/B2C
|
||||
Das Modell muss unterscheiden können:
|
||||
|
||||
- B2B
|
||||
- B2C
|
||||
- öffentliche Einrichtung
|
||||
- Verein/Organisation
|
||||
|
||||
## Begründung
|
||||
Das ist notwendig für:
|
||||
|
||||
- korrekte Rechnungsdaten
|
||||
- DSGVO
|
||||
- Supportprozesse
|
||||
- Vertragsverwaltung
|
||||
- spätere Erweiterbarkeit
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- saubereres Datenmodell
|
||||
- bessere DSGVO-Fähigkeit
|
||||
- bessere B2B/B2C-Unterstützung
|
||||
- bessere Kundenrealität
|
||||
|
||||
### Negativ
|
||||
- mehr Tabellen
|
||||
- mehr UI-Komplexität
|
||||
- Importlogik muss sauber mappen
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0021 — DSGVO-Löschung und Retention
|
||||
- ADR 0015 — Tax- und VAT-Strategie
|
||||
@@ -0,0 +1,92 @@
|
||||
# ADR 0014 — Audit-Log-Strategie
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Audit-Logs dokumentieren wichtige Änderungen und Aktionen.
|
||||
|
||||
Sie beantworten:
|
||||
|
||||
```text
|
||||
Wer hat wann was geändert?
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat bemängelt, dass „nicht manipulierbare Logs“ gefordert wurden, aber kein Mechanismus definiert war.
|
||||
|
||||
## Entscheidung
|
||||
V1 verwendet ein append-only Audit-Log.
|
||||
|
||||
Append-only bedeutet:
|
||||
|
||||
```text
|
||||
Einträge werden nur hinzugefügt,
|
||||
aber nicht geändert oder gelöscht.
|
||||
```
|
||||
|
||||
## V1-Mindestmechanismus
|
||||
Audit-Logs werden gespeichert mit:
|
||||
|
||||
- tenant_id
|
||||
- actor_id
|
||||
- actor_type
|
||||
- action
|
||||
- object_type
|
||||
- object_id
|
||||
- old_values
|
||||
- new_values
|
||||
- created_at
|
||||
- request_id
|
||||
- ip_address
|
||||
- user_agent
|
||||
|
||||
## Integrität
|
||||
V1 bereitet eine Hash-Chain vor.
|
||||
|
||||
Hash-Chain bedeutet:
|
||||
|
||||
```text
|
||||
Jeder Logeintrag enthält einen Prüfwert
|
||||
und verweist rechnerisch auf den vorherigen Eintrag.
|
||||
```
|
||||
|
||||
Dadurch werden nachträgliche Manipulationen besser erkennbar.
|
||||
|
||||
## Trennung
|
||||
Es gibt unterschiedliche Logarten:
|
||||
|
||||
- App-Logs
|
||||
- Security-Logs
|
||||
- Audit-Logs
|
||||
|
||||
Audit-Logs sind keine normalen Debug-Logs.
|
||||
|
||||
## Kritische Aktionen
|
||||
Immer auditieren:
|
||||
|
||||
- Login/Logout
|
||||
- fehlgeschlagene Logins
|
||||
- Rechteänderungen
|
||||
- Kundendatenänderungen
|
||||
- Vertragsänderungen
|
||||
- Zahlungsstatusänderungen
|
||||
- Importvorgänge
|
||||
- Secret-Änderungen
|
||||
- Modulaktivierungen
|
||||
- API-Token-Erstellung
|
||||
|
||||
## Nicht-Ziel
|
||||
V1 garantiert noch keine vollständige externe WORM-Archivierung.
|
||||
|
||||
## Später möglich
|
||||
- Export in externes Audit-Sink
|
||||
- WORM-Speicher
|
||||
- signierte Logs
|
||||
- tägliche Hash-Summen
|
||||
- revisionssichere Langzeitablage
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
- ADR 0010 — Secrets-Management
|
||||
- ADR 0021 — DSGVO-Löschung und Retention
|
||||
@@ -0,0 +1,60 @@
|
||||
# ADR 0015 — Tax- und VAT-Strategie
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Tax/VAT bedeutet Steuer- und Mehrwertsteuerlogik.
|
||||
|
||||
Auch wenn Hosting-Backoffice V1 keine eigene Buchhaltung sein soll, muss das System steuerlich relevante Informationen verstehen und sauber an externe Rechnungssysteme übergeben oder anzeigen können.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat bemängelt, dass MwSt, B2B/B2C, OSS und Reverse Charge nicht erwähnt wurden.
|
||||
|
||||
Für V1 muss mindestens der deutsche Standardfall sauber abgebildet werden.
|
||||
|
||||
## Entscheidung
|
||||
V1 enthält ein minimales Steuer-Metadatenmodell, erzeugt aber keine führenden Steuerbelege.
|
||||
|
||||
Führende Steuerberechnung bleibt in:
|
||||
|
||||
- Lexware
|
||||
- Invoice Ninja
|
||||
- späterem externen Billing-System
|
||||
|
||||
## V1-Mindestumfang
|
||||
|
||||
- Kundentyp: B2B / B2C
|
||||
- Land des Kunden
|
||||
- USt-IdNr. optional
|
||||
- Standard-Steuersatz je Produktreferenz
|
||||
- Steuerhinweis je Vertrag/Rechnungsreferenz
|
||||
- Brutto-/Netto-Anzeige nur als Referenz aus Billing-System
|
||||
|
||||
## Nicht Teil von V1
|
||||
|
||||
- vollständige OSS-Automatisierung
|
||||
- vollständige Reverse-Charge-Prüfung
|
||||
- eigene Steuerberechnung als führendes System
|
||||
- komplexe internationale Steuerlogik
|
||||
|
||||
## Warum trotzdem Tax-Metadaten?
|
||||
Weil das System sonst nicht zuverlässig erkennen kann:
|
||||
|
||||
- welche Kunden B2B/B2C sind
|
||||
- welche Rechnungslogik extern nötig ist
|
||||
- welche Daten für Lexware/Invoice Ninja relevant sind
|
||||
- welche Kunden steuerlich anders behandelt werden müssen
|
||||
|
||||
## Später möglich
|
||||
|
||||
- OSS-Unterstützung
|
||||
- EU-B2B Reverse Charge
|
||||
- Steuerprofile pro Mandant
|
||||
- Steuerregeln pro Produkt
|
||||
- Prüfung von USt-IdNr.
|
||||
- tiefe Billing-Synchronisation
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
- ADR 0013 — Kunden-/Adress-/Kontaktmodell
|
||||
@@ -0,0 +1,66 @@
|
||||
# ADR 0016 — Modul-Lifecycle
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Der Modul-Lifecycle beschreibt, was mit einem Modul passiert, wenn es installiert, aktiviert, deaktiviert oder entfernt wird.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass Module zwar aktivierbar/deaktivierbar sein sollen, aber nicht definiert war, was mit bestehenden Daten passiert.
|
||||
|
||||
## Entscheidung
|
||||
Module haben definierte Zustände:
|
||||
|
||||
- available
|
||||
- installed
|
||||
- enabled
|
||||
- disabled
|
||||
- archived
|
||||
|
||||
Deinstallation mit Datenlöschung ist kein Standardfall.
|
||||
|
||||
## Zustände
|
||||
|
||||
### available
|
||||
Modul ist im System vorhanden, aber nicht installiert.
|
||||
|
||||
### installed
|
||||
Modul ist installiert, aber nicht aktiv.
|
||||
|
||||
### enabled
|
||||
Modul ist aktiv.
|
||||
|
||||
### disabled
|
||||
Modul ist deaktiviert, Daten bleiben erhalten.
|
||||
|
||||
### archived
|
||||
Modul wird nicht mehr genutzt, Daten bleiben aus Nachvollziehbarkeitsgründen erhalten.
|
||||
|
||||
## Datenregel
|
||||
Daten werden beim Deaktivieren nicht gelöscht.
|
||||
|
||||
Grund:
|
||||
|
||||
- Audit
|
||||
- GoBD
|
||||
- Nachvollziehbarkeit
|
||||
- Referenzintegrität
|
||||
|
||||
## Modul-Abhängigkeiten
|
||||
Module müssen Abhängigkeiten deklarieren.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```text
|
||||
Invoice Ninja Adapter benötigt Billing-Modul.
|
||||
```
|
||||
|
||||
## Migrationen
|
||||
Jedes Modul verwaltet eigene Migrationen.
|
||||
|
||||
Core-Migrationen dürfen keine Anbieterlogik enthalten.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0007 — Modul-System
|
||||
- ADR 0009 — Core-Grenzen
|
||||
@@ -0,0 +1,69 @@
|
||||
# ADR 0017 — Adapter-Fehlerresilienz
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Adapter verbinden Hosting-Backoffice mit externen Systemen.
|
||||
|
||||
Fehlerresilienz bedeutet:
|
||||
|
||||
```text
|
||||
Das System darf nicht kaputt gehen,
|
||||
nur weil ein externer Anbieter gerade nicht erreichbar ist.
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Integrationen zu KeyHelp, 1blu, Lexware und Invoice Ninja sind geschäftskritisch.
|
||||
|
||||
Das Architekturreview hat fehlende Retry-, Backoff- und Reconciliation-Strategien bemängelt.
|
||||
|
||||
## Entscheidung
|
||||
Alle Integrationsmodule müssen ein gemeinsames Fehlerverhalten unterstützen.
|
||||
|
||||
## Pflichtmechanismen
|
||||
|
||||
- Retry
|
||||
- Backoff
|
||||
- Dead Letter Queue
|
||||
- Reconciliation
|
||||
- sichtbarer Job-Status
|
||||
- Audit-Log bei kritischen Fehlern
|
||||
|
||||
## Begriffe
|
||||
|
||||
### Retry
|
||||
Ein fehlgeschlagener Vorgang wird erneut versucht.
|
||||
|
||||
### Backoff
|
||||
Wiederholungen erfolgen mit zunehmender Wartezeit.
|
||||
|
||||
### Dead Letter Queue
|
||||
Fehlgeschlagene Jobs werden gesammelt, damit ein Admin sie prüfen kann.
|
||||
|
||||
### Reconciliation
|
||||
Abgleich zwischen internem System und externem Anbieter, um Abweichungen zu erkennen.
|
||||
|
||||
## Beispiel
|
||||
Wenn Lexware nicht erreichbar ist:
|
||||
|
||||
- Job schlägt nicht still fehl
|
||||
- System versucht später erneut
|
||||
- Admin sieht den Fehler
|
||||
- Daten bleiben nachvollziehbar
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positiv
|
||||
- stabilere Integrationen
|
||||
- weniger stille Fehler
|
||||
- bessere Admin-Kontrolle
|
||||
|
||||
### Negativ
|
||||
- mehr Implementierungsaufwand
|
||||
- Job-System erforderlich
|
||||
- Monitoring wird wichtiger
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0008 — External-Reference-Pattern
|
||||
- ADR 0010 — Secrets-Management
|
||||
@@ -0,0 +1,61 @@
|
||||
# ADR 0018 — WordPress-Plugin-Sicherheit
|
||||
|
||||
## Status
|
||||
Proposed
|
||||
|
||||
## Kurz erklärt
|
||||
Das WordPress-Plugin ist später ein API-Client.
|
||||
|
||||
Es läuft in einer WordPress-Umgebung, die möglicherweise durch andere Plugins, Themes oder schlechte Wartung gefährdet ist.
|
||||
|
||||
## Kontext
|
||||
WordPress soll nicht Core sein, aber später als Frontend-/Widget-Schicht dienen.
|
||||
|
||||
Das Architekturreview hat gewarnt, dass das Plugin eine zweite Sicherheitsdomäne erzeugt.
|
||||
|
||||
## Entscheidung
|
||||
Das WordPress-Plugin wird nicht Teil von V1.
|
||||
|
||||
Für spätere Versionen gilt:
|
||||
|
||||
- Plugin nutzt ausschließlich REST API
|
||||
- Plugin bekommt minimale API-Scopes
|
||||
- keine direkten Datenbankzugriffe
|
||||
- keine lokalen Kopien sensibler Daten, außer technisch zwingend nötig
|
||||
- Token-Rotation muss möglich sein
|
||||
- Plugin-Zugriffe werden auditierbar
|
||||
|
||||
## API-Scopes
|
||||
Das Plugin darf nur das, was für seine Widgets nötig ist.
|
||||
|
||||
Beispiele:
|
||||
|
||||
- Kundenbereich anzeigen
|
||||
- Ticket erstellen
|
||||
- Rechnungsreferenzen anzeigen
|
||||
- Vertragsdaten lesen
|
||||
|
||||
Nicht erlaubt:
|
||||
|
||||
- globale Adminfunktionen
|
||||
- Anbieter-Credentials lesen
|
||||
- fremde Mandantendaten lesen
|
||||
|
||||
## Bei kompromittierter WordPress-Seite
|
||||
Ein kompromittiertes Plugin-Token darf nicht das gesamte Backoffice gefährden.
|
||||
|
||||
Deshalb:
|
||||
|
||||
- Token widerrufbar
|
||||
- Scope begrenzt
|
||||
- Mandant begrenzt
|
||||
- Audit-Logs
|
||||
- Rate-Limits
|
||||
|
||||
## Status
|
||||
Diese ADR bleibt zunächst Proposed, weil das WordPress-Plugin erst nach V1 konkret geplant wird.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0006 — Auth-Strategie
|
||||
- ADR 0012 — Frontend-Strategie
|
||||
- ADR 0020 — Customer-Portal-Scope
|
||||
@@ -0,0 +1,77 @@
|
||||
# ADR 0019 — V1-Scope-Finalisierung
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Der V1-Scope legt fest, was in die erste produktiv nutzbare Version gehört und was bewusst nicht.
|
||||
|
||||
Das verhindert Feature-Explosion.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat Widersprüche festgestellt:
|
||||
|
||||
- 1–500 Kunden vs. 1–50 Kunden
|
||||
- KI in V1 vs. V2
|
||||
- Customer Portal in V1 vs. unklar
|
||||
- SEPA als Zahlungsart ohne Modell
|
||||
|
||||
## Entscheidung
|
||||
V1 wird auf eine interne produktive Grundversion für kleine Anbieter mit 1–50 Kunden begrenzt.
|
||||
|
||||
## V1 enthält
|
||||
|
||||
- Admin-/Backoffice-Oberfläche
|
||||
- Kundenverwaltung
|
||||
- Kontakt-/Adressmodell
|
||||
- Verträge
|
||||
- Produkte/Leistungen
|
||||
- Domains
|
||||
- Registrar-Import 1blu
|
||||
- Server-/Hosting-Zuordnung
|
||||
- Rechnungsreferenzen
|
||||
- Billing-Referenzen zu Lexware/Invoice Ninja
|
||||
- Tickets light intern
|
||||
- Dokumentenablage
|
||||
- Audit-Logs
|
||||
- Tax-/VAT-Metadaten minimal
|
||||
- Nummernkreise
|
||||
- einfache Statuslogik
|
||||
|
||||
## V1 enthält NICHT
|
||||
|
||||
- KI-Assistent
|
||||
- öffentliches WordPress-Plugin
|
||||
- vollständiges Customer Portal
|
||||
- SEPA-Lastschrift mit Mandatsverwaltung
|
||||
- eigenes Payment-System
|
||||
- eigene Rechnungsstellung als führendes System
|
||||
- automatische Servermigration
|
||||
- automatische VM-/Cloud-Provisionierung
|
||||
- Plesk/cPanel
|
||||
- Marketplace
|
||||
|
||||
## Customer Portal
|
||||
Ein vollständiges Kundenportal wird auf V2 verschoben.
|
||||
|
||||
In V1 kann optional eine interne Kundenansicht vorbereitet werden, aber kein öffentlicher Self-Service.
|
||||
|
||||
## KI
|
||||
KI wird auf V2 verschoben.
|
||||
|
||||
Grund:
|
||||
|
||||
- Datenschutz
|
||||
- Subprozessoren
|
||||
- Drittlandtransfer
|
||||
- unnötige V1-Komplexität
|
||||
|
||||
## Zahlungsarten
|
||||
In V1 werden Zahlungsarten nur als Referenz/Status geführt.
|
||||
|
||||
Keine echte Zahlungsabwicklung im Backoffice.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
- ADR 0015 — Tax- und VAT-Strategie
|
||||
- ADR 0020 — Customer-Portal-Scope
|
||||
@@ -0,0 +1,58 @@
|
||||
# ADR 0020 — Customer-Portal-Scope
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Das Kundenportal ist der Bereich, in dem Endkunden später selbst Daten, Rechnungen, Verträge und Tickets sehen können.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass das Customer Portal gleichzeitig als V1-Modul genannt, aber nicht konsistent im MVP enthalten war.
|
||||
|
||||
## Entscheidung
|
||||
Ein vollständiges Customer Portal ist nicht Teil von V1.
|
||||
|
||||
## V1
|
||||
V1 enthält nur eine interne Kundenansicht für Admins/Mitarbeiter.
|
||||
|
||||
Diese zeigt:
|
||||
|
||||
- Kundendaten
|
||||
- Verträge
|
||||
- Domains
|
||||
- Hostingpakete
|
||||
- Rechnungsreferenzen
|
||||
- Tickets
|
||||
- Dokumente
|
||||
|
||||
## V2
|
||||
Das öffentliche Customer Portal wird in V2 geplant.
|
||||
|
||||
Dann müssen zusätzlich geklärt werden:
|
||||
|
||||
- Kundenlogin
|
||||
- Self-Service
|
||||
- Barrierefreiheit
|
||||
- AGB-/Datenschutz-Hinweise
|
||||
- Session-Sicherheit
|
||||
- Passwort-Reset
|
||||
- MFA optional
|
||||
- WordPress-Integration
|
||||
|
||||
## Warum nicht V1?
|
||||
Ein öffentliches Portal erhöht V1-Komplexität stark:
|
||||
|
||||
- Sicherheitsrisiko
|
||||
- Supportaufwand
|
||||
- rechtliche Anforderungen
|
||||
- UI-/UX-Aufwand
|
||||
- Barrierefreiheit
|
||||
- Auth-Komplexität
|
||||
|
||||
## Konsequenz
|
||||
V1 wird stabiler und schneller erreichbar.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0012 — Frontend-Strategie
|
||||
- ADR 0018 — WordPress-Plugin-Sicherheit
|
||||
- ADR 0019 — V1-Scope-Finalisierung
|
||||
@@ -0,0 +1,53 @@
|
||||
# ADR 0021 — DSGVO-Löschung und Retention
|
||||
|
||||
## Status
|
||||
Proposed
|
||||
|
||||
## Kurz erklärt
|
||||
DSGVO-Löschung bedeutet, dass personenbezogene Daten unter bestimmten Voraussetzungen gelöscht werden müssen.
|
||||
|
||||
Retention bedeutet Aufbewahrungspflicht, z. B. für Rechnungsunterlagen.
|
||||
|
||||
Diese Anforderungen können kollidieren.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat bemängelt, dass DSGVO-Löschung und GoBD-Aufbewahrung nicht modelliert wurden.
|
||||
|
||||
## Entscheidung
|
||||
V1 muss ein Lösch-/Pseudonymisierungskonzept vorbereiten.
|
||||
|
||||
## Grundprinzip
|
||||
Personenbezogene Stammdaten sollen von retentionspflichtigen Belegdaten getrennt werden.
|
||||
|
||||
## Modell
|
||||
Bei Löschanforderung:
|
||||
|
||||
- nicht aufbewahrungspflichtige Daten werden gelöscht
|
||||
- aufbewahrungspflichtige Daten bleiben erhalten
|
||||
- personenbezogene Daten werden soweit möglich pseudonymisiert
|
||||
- Audit-Log dokumentiert den Vorgang
|
||||
|
||||
## Beispiel
|
||||
Statt Kundenname:
|
||||
|
||||
```text
|
||||
Gelöschter Kunde 8f3a...
|
||||
```
|
||||
|
||||
## Nicht einfach löschen
|
||||
Rechnungsrelevante Daten dürfen ggf. nicht vollständig gelöscht werden, wenn gesetzliche Aufbewahrungspflichten bestehen.
|
||||
|
||||
## V1-Mindestanforderung
|
||||
|
||||
- Kennzeichnung gelöschter/pseudonymisierter Kunden
|
||||
- Export der Kundendaten vorbereiten
|
||||
- Trennung von Stammdaten und Belegdaten
|
||||
- Audit-Log für Löschung/Pseudonymisierung
|
||||
|
||||
## Offener Punkt
|
||||
Rechtliche Prüfung erforderlich.
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
- ADR 0013 — Kunden-/Adress-/Kontaktmodell
|
||||
- ADR 0014 — Audit-Log-Strategie
|
||||
@@ -0,0 +1,55 @@
|
||||
# ADR 0022 — Dokumentenhierarchie und Single Source of Truth
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Single Source of Truth bedeutet:
|
||||
|
||||
```text
|
||||
Es gibt eine verbindliche Quelle,
|
||||
wenn sich Dokumente widersprechen.
|
||||
```
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat kritisiert, dass mehrere Dokumente unterschiedliche Aussagen enthalten.
|
||||
|
||||
Beispiele:
|
||||
|
||||
- V1-Kundenzahl
|
||||
- KI in V1 oder V2
|
||||
- Customer Portal in V1 oder V2
|
||||
- Module im Core oder Service-Modul
|
||||
|
||||
## Entscheidung
|
||||
Es gilt folgende Dokumentenhierarchie:
|
||||
|
||||
1. ADRs
|
||||
2. Architektur-Dokumente
|
||||
3. Modulstruktur
|
||||
4. Roadmap
|
||||
5. Modul-Detaildokumente
|
||||
6. Brainstorming-/Ideendokumente
|
||||
|
||||
## Konsequenz
|
||||
Wenn sich Dokumente widersprechen, gilt die höhere Ebene.
|
||||
|
||||
Beispiel:
|
||||
|
||||
Wenn ADR 0019 sagt „KI ist V2“, aber ein altes Modul-Dokument KI als V1 beschreibt, gilt ADR 0019.
|
||||
|
||||
## Pflege-Regel
|
||||
Nach jeder größeren ADR-Serie müssen betroffene Dokumente aktualisiert werden.
|
||||
|
||||
## Ziel
|
||||
Architekturdrift verhindern.
|
||||
|
||||
Architekturdrift bedeutet:
|
||||
|
||||
```text
|
||||
Planung und tatsächliche Umsetzung entfernen sich schleichend voneinander.
|
||||
```
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0019 — V1-Scope-Finalisierung
|
||||
- ADR 0009 — Core-Grenzen
|
||||
@@ -0,0 +1,62 @@
|
||||
# ADR 0023 — Nummernkreise
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Kurz erklärt
|
||||
Nummernkreise erzeugen eindeutige Nummern für:
|
||||
|
||||
- Kunden
|
||||
- Verträge
|
||||
- Rechnungsreferenzen
|
||||
- Tickets
|
||||
|
||||
Bei Rechnungen sind Nummern besonders sensibel, weil sie steuerlich relevant sein können.
|
||||
|
||||
## Kontext
|
||||
Das Architekturreview hat fehlende Nummernkreislogik als V1-Risiko bewertet.
|
||||
|
||||
## Entscheidung
|
||||
V1 erhält eine zentrale Nummernkreisverwaltung pro Tenant.
|
||||
|
||||
## Beispielstruktur
|
||||
|
||||
```text
|
||||
number_sequences
|
||||
- tenant_id
|
||||
- sequence_key
|
||||
- prefix
|
||||
- current_number
|
||||
- padding
|
||||
- reset_strategy
|
||||
- locked_at
|
||||
```
|
||||
|
||||
## Beispiele
|
||||
|
||||
```text
|
||||
K-00001
|
||||
V-00001
|
||||
T-2026-00001
|
||||
```
|
||||
|
||||
## Rechnungen
|
||||
Da Hosting-Backoffice V1 nicht führendes Rechnungssystem ist, erzeugt es keine verbindlichen Rechnungsnummern.
|
||||
|
||||
Es speichert externe Rechnungsnummern aus Lexware/Invoice Ninja.
|
||||
|
||||
## Interne Referenzen
|
||||
Für interne Vorgänge dürfen eigene Referenzen erzeugt werden.
|
||||
|
||||
## Technische Regel
|
||||
Nummernvergabe muss atomar erfolgen.
|
||||
|
||||
Atomar bedeutet:
|
||||
|
||||
```text
|
||||
Zwei gleichzeitige Vorgänge dürfen nicht dieselbe Nummer erhalten.
|
||||
```
|
||||
|
||||
## Verwandte ADRs
|
||||
- ADR 0011 — GoBD-Verantwortlichkeit
|
||||
- ADR 0019 — V1-Scope-Finalisierung
|
||||
Reference in New Issue
Block a user