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.
|
||||
Reference in New Issue
Block a user