docs: Abschlussbericht Phase 0+1 und vollständiger Sanierungsplan
- Kompletter Statusbericht mit allen 5 Gates - Datenbankrollen-Architektur dokumentiert - RLS-Architektur dokumentiert - Verifizierte Sicherheitsnachweise - Durchgeführte Code-Änderungen und Migrationen - Offene Risiken - Vollständiger Sanierungsplan Phase 2-10 - Gesamtschätzung: 120-210h verbleibend - Empfohlene Reihenfolge
This commit is contained in:
@@ -0,0 +1,476 @@
|
||||
# LeoCRM — Abschlussbericht Phase 0 + Phase 1 und vollständiger Sanierungsplan
|
||||
|
||||
**Datum:** 2026-08-01
|
||||
**Git-Commit:** 733fa1c (main)
|
||||
**Alembic-Head:** 0090
|
||||
**Produktion:** https://crm.media-on.de — healthy
|
||||
|
||||
---
|
||||
|
||||
## 1. Aktueller Stand
|
||||
|
||||
### 1.1 Abgenommene Gates
|
||||
|
||||
| Gate | Beschreibung | Status |
|
||||
|------|-------------|--------|
|
||||
| Gate 1 | Reproduzierbares Coolify-Deployment | ✅ Bestanden |
|
||||
| Gate 2 | Neuinstallation auf leerer Datenbank | ✅ Bestanden |
|
||||
| Gate 3 | Vollständiger Restore-Test | ✅ Bestanden |
|
||||
| Gate 4 | Passwort-Reset end-to-end | ✅ Bestanden |
|
||||
| Gate 5 | Worker und Eventhandler | ✅ Bestanden |
|
||||
|
||||
### 1.2 Produktionsstand
|
||||
|
||||
| Komponente | Wert |
|
||||
|-----------|------|
|
||||
| Git-Commit | 733fa1c |
|
||||
| Docker-Image | stvabl4vaqru7jclx4ittzr3:733fa1c |
|
||||
| API-Container | stvabl4vaqru7jclx4ittzr3-201530032526 — healthy |
|
||||
| Worker-Container | leocrm-worker — healthy |
|
||||
| Alembic-Head | 0090 |
|
||||
| Tabellen | 124 |
|
||||
| RLS-Tabellen | 108 (alle Tenant-Tabellen) |
|
||||
| RLS-Policies | 112 |
|
||||
| Legacy app.tenant_id Policies | 0 |
|
||||
| DB-Rollen | 5 (crm_platform_admin, crm_migration, crm_auth, crm_api, crm_worker) |
|
||||
| crm_api | NOSUPERUSER, NOBYPASSRLS — API-Laufzeit |
|
||||
| crm_auth | NOSUPERUSER, NOBYPASSRLS — Login/Authentifizierung |
|
||||
| crm_worker | NOSUPERUSER, NOBYPASSRLS — Worker-Laufzeit |
|
||||
| crm_migration | NOSUPERUSER, BYPASSRLS — Migrationen und DDL |
|
||||
| ~~crm_runtime~~ | Gelöscht |
|
||||
|
||||
### 1.3 Datenbankrollen-Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ PostgreSQL (crm_db) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ crm_user (POSTGRES_USER, SUPERUSER) │
|
||||
│ └── Nur für Bootstrap und DB-Initialisierung │
|
||||
│ │
|
||||
│ crm_migration (NOSUPERUSER, BYPASSRLS, Tabellenowner) │
|
||||
│ ├── Alembic-Migrationen (0001–0090) │
|
||||
│ ├── Plugin-Migrationen (DDL) │
|
||||
│ └── Datenmigrationen (tenantübergreifend) │
|
||||
│ │
|
||||
│ crm_auth (NOSUPERUSER, NOBYPASSRLS) │
|
||||
│ ├── Login/Logout │
|
||||
│ ├── Tenant-Auflösung │
|
||||
│ ├── User/Tenant-Membership │
|
||||
│ └── Password-Reset-Token │
|
||||
│ │
|
||||
│ crm_api (NOSUPERUSER, NOBYPASSRLS, kein Owner) │
|
||||
│ ├── Normale API-Abfragen (SELECT, INSERT, UPDATE, DELETE) │
|
||||
│ ├── Audit-Log (über separate Session mit Tenant-Kontext) │
|
||||
│ └── Keine DDL-Rechte │
|
||||
│ │
|
||||
│ crm_worker (NOSUPERUSER, NOBYPASSRLS, kein Owner) │
|
||||
│ ├── ARQ-Background-Jobs │
|
||||
│ ├── Outbox-Processing (per-Tenant mit RLS-Kontext) │
|
||||
│ ├── Cron-Jobs (scheduler_tick, tasks_due_reminder) │
|
||||
│ └── Event-Handler für aktive Plugins │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.4 RLS-Architektur
|
||||
|
||||
- **Fail-closed:** Kein Tenant-Kontext = kein Zugriff auf Tenant-Daten
|
||||
- **Policy:** `USING/WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::uuid)`
|
||||
- **FORCE ROW LEVEL SECURITY** auf allen 108 Tenant-Tabellen
|
||||
- **Scoped to:** `crm_api, crm_worker` (nicht PUBLIC)
|
||||
- **21 globale Tabellen** ohne RLS: users, tenants, sessions, plugins, etc.
|
||||
- **0 legacy Policies** mit `app.tenant_id` (alle durch `app.current_tenant_id` ersetzt)
|
||||
|
||||
### 1.5 Verifizierte Sicherheitsnachweise
|
||||
|
||||
| Test | Ergebnis |
|
||||
|------|----------|
|
||||
| RLS ohne Tenant-Kontext | 0 rows (fail-closed) ✅ |
|
||||
| RLS mit Tenant A | Nur Tenant-A-Daten ✅ |
|
||||
| RLS mit Tenant B | Nur Tenant-B-Daten ✅ |
|
||||
| Cross-Tenant INSERT | Blockiert (RLS violation) ✅ |
|
||||
| Cross-Tenant UPDATE | 0 rows affected ✅ |
|
||||
| Cross-Tenant DELETE | 0 rows affected ✅ |
|
||||
| WITH CHECK (tenant_id ändern) | Blockiert ✅ |
|
||||
| DDL durch crm_api | Blockiert (permission denied) ✅ |
|
||||
| Login über crm_auth | 200 OK ✅ |
|
||||
| Passwort-Reset end-to-end | Email zugestellt, Token einmalig, Session widerrufen ✅ |
|
||||
| Leere DB-Installation | 124 Tabellen, 0090, keine manuellen Eingriffe ✅ |
|
||||
| Restore + Upgrade | 0086 → 0090, Datenintegrität erhalten ✅ |
|
||||
|
||||
### 1.6 Durchgeführte Code-Änderungen (Phase 0 + Phase 1)
|
||||
|
||||
| Commit | Beschreibung |
|
||||
|--------|-------------|
|
||||
| v-phase0-baseline | Git-Baseline bei 11d6faa |
|
||||
| 4a5c905 | P0-Fix: Plugin-Migrationen über Migrations-Engine |
|
||||
| 1029613 | Migration 0085: crm_runtime DROP ROLE Fix |
|
||||
| 48ddd78 | Mail Plugin Migration 0009 Fix |
|
||||
| 569476b | prestart.sh: DB-Rollen-Passwörter setzen |
|
||||
| b5191f0 | Migration 0089: sessions.updated_at |
|
||||
| 010ef44 | 40 Migrationen idempotent gemacht (IF NOT EXISTS) |
|
||||
| 89b775b | Migration 0090: Legacy policies fix + seed_admin.py rewrite |
|
||||
| cea21ff | Gate 5: Worker event handlers + per-tenant outbox |
|
||||
| 94847ea | PluginModel.active Fix (worker crash) |
|
||||
| 733fa1c | Gate 3: Restore-Test Doku |
|
||||
|
||||
### 1.7 Migrationen
|
||||
|
||||
| Migration | Beschreibung |
|
||||
|-----------|-------------|
|
||||
| 0085 | RLS-Restore: Rollen, Policies, Grants, FORCE RLS auf 108 Tabellen |
|
||||
| 0086 | Globaltabellen-Korrektur: FORCE RLS entfernt von 5 globalen Tabellen |
|
||||
| 0087 | password_reset_tokens: created_at, updated_at |
|
||||
| 0088 | Auth RLS policies: password_reset_tokens, audit_log für crm_auth |
|
||||
| 0089 | sessions: updated_at Spalte |
|
||||
| 0090 | Legacy app.tenant_id policies auf _old Tabellen fixen |
|
||||
|
||||
### 1.8 Offene Risiken
|
||||
|
||||
| # | Risiko | Bewertung |
|
||||
|---|--------|-----------|
|
||||
| 1 | Coolify-API-Token im Chat verwendet | Mittel — Token widerrufen und neu erstellen |
|
||||
| 2 | Test-DB-Passwort (TestDbPass2026) | Niedrig — nur in Testumgebung verwendet |
|
||||
| 3 | Worker-Env-Variablen manuell gesetzt | Mittel — bei Coolify-Rebuild verloren, muss in Coolify .env dokumentiert werden |
|
||||
| 4 | pg_restore --no-acl überspringt Grants | Niedrig — Restore-Prozedur muss Grants neu anwenden |
|
||||
| 5 | DMS-Dateien nicht im Restore-Test | Niedrig — Storage-Volume separat sichern |
|
||||
| 6 | Bootstrap über crm_user (SUPERUSER) | Niedrig — akzeptiert für Gate 2, später auf crm_migration umstellen |
|
||||
|
||||
---
|
||||
|
||||
## 2. Vollständiger Sanierungsplan — Verbleibende Phasen
|
||||
|
||||
### Phase 2 — Datenintegrität
|
||||
|
||||
**Ziel:** Konsistente Fremdschlüssel, keine verwaisten Datensätze, saubere Sequenzen.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Fremdschlüssel-Constraints prüfen und fehlende ergänzen
|
||||
2. Verwaiste Datensätze identifizieren und bereinigen
|
||||
3. Sequenzen synchronisieren (sync mit MAX(id))
|
||||
4. ON DELETE CASCADE prüfen und dokumentieren
|
||||
5. Datenbank-Integritäts-Test-Suite erstellen
|
||||
6. Migration für fehlende FK-Constraints erstellen
|
||||
|
||||
**Abnahmekriterien:**
|
||||
- Alle FK-Constraints vorhanden und gültig
|
||||
- Keine verwaisten Datensätze
|
||||
- Alle Sequenzen synchron
|
||||
- Integritäts-Tests grün
|
||||
|
||||
**Aufwand:** 8–16 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 3 — Plugin-Lifecycle
|
||||
|
||||
**Ziel:** Saubere Plugin-Aktivierung, Deaktivierung und Migration ohne Race-Conditions.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Plugin-Aktivierung: Prüfen ob bereits aktiv, idempotent machen
|
||||
2. Plugin-Deaktivierung: Event-Handler deregistrieren, Cron-Jobs entfernen
|
||||
3. Plugin-Migration: Versionierung und Rollback
|
||||
4. Tenant-Plugin-Aktivierung: Per-Tenant mit Tenant-Kontext
|
||||
5. Plugin-Abhängigkeiten: Load-Order respektieren
|
||||
6. Plugin-Router: Nur in API registrieren, nicht im Worker
|
||||
7. Plugin-Event-Handler: Nur für aktive Plugins registrieren
|
||||
8. Test: Plugin aktivieren → deaktivieren → reaktivieren
|
||||
|
||||
**Abnahmekriterien:**
|
||||
- Plugin-Aktivierung ist idempotent
|
||||
- Plugin-Deaktivierung deregistriert Event-Handler
|
||||
- Plugin-Migrationen haben Versionierung
|
||||
- Tenant-Plugin-Aktivierung funktioniert mit RLS
|
||||
- Keine Race-Conditions bei paralleler Aktivierung
|
||||
|
||||
**Aufwand:** 6–10 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 4 — Sichere KI-Delegation
|
||||
|
||||
**Ziel:** KI-Agenten können sicher und kontrolliert Aufgaben ausführen.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Delegation-Contract definieren (Input, Output, Permissions)
|
||||
2. KI-Agent-Permissions: Tenant-scoped, keine Cross-Tenant
|
||||
3. KI-Agent-Session: Separate Session mit Tenant-Kontext
|
||||
4. KI-Agent-Limits: Max executions, timeout, rate-limit
|
||||
5. KI-Agent-Audit: Alle Aktionen protokollieren
|
||||
6. KI-Agent-Rollback: Fehlerhafte Aktionen zurückrollen
|
||||
7. KI-Agent-Approval: Menschliche Freigabe für kritische Aktionen
|
||||
8. Test: KI-Agent erstellt Kontakt → aktualisiert → löscht (nur im eigenen Tenant)
|
||||
|
||||
**Abnahmekriterien:**
|
||||
- KI-Agent kann nur im zugewiesenen Tenant arbeiten
|
||||
- KI-Agent-Aktionen sind auditiert
|
||||
- KI-Agent-Timeout und Rate-Limit funktionieren
|
||||
- KI-Agent kann keine Cross-Tenant-Daten lesen/schreiben
|
||||
- Kritische Aktionen erfordern Freigabe
|
||||
|
||||
**Aufwand:** 12–24 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 5 — Transactional Outbox
|
||||
|
||||
**Ziel:** Zuverlässige Event-Zustellung ohne Events zu verlieren.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Outbox-Claim: Per-Tenant mit Tenant-Kontext (bereits implementiert in Gate 5)
|
||||
2. Outbox-Event-Consumer: Erwartete Consumer pro Event registrieren
|
||||
3. Outbox-Dead-Letter: Events nach max_attempts in DLQ
|
||||
4. Outbox-Monitoring: Backlog-Metriken, Failed-Jobs-Alert
|
||||
5. Outbox-Retry: Exponentieller Backoff (bereits implementiert)
|
||||
6. Outbox-Idempotency: consumer_inbox Check (bereits implementiert)
|
||||
7. Outbox-Delivery-Guarantee: At-least-once, consumer must be idempotent
|
||||
8. Test: Event erzeugen → Worker verarbeitet → Consumer ausführen → Idempotency prüfen
|
||||
|
||||
**Abnahmekriterien:**
|
||||
- Events gehen nicht verloren (auch bei Worker-Crash)
|
||||
- Events werden mindestens einmal zugestellt
|
||||
- Consumer sind idempotent
|
||||
- Dead-Letter-Queue funktioniert
|
||||
- Backlog-Monitoring funktioniert
|
||||
|
||||
**Aufwand:** 14–24 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 6 — Workspaces
|
||||
|
||||
**Ziel:** Mehrere unabhängige Workspaces pro Benutzer, pro Browser-Tab.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Workspace-Model: UUID, Name, Owner, Tenant, Config
|
||||
2. Workspace-Widget-Config: Eigene UUID, Position, Größe, Konfiguration
|
||||
3. Workspace-Store: Zentraler React/Zustand-Store
|
||||
4. Workspace-Switcher: Sofortiger Wechsel ohne Page-Reload
|
||||
5. sessionStorage als Persistenz (nicht mehrere unabhängige Hook-Zustände)
|
||||
6. Sidebar reagiert sofort auf Workspace-Wechsel
|
||||
7. Leerer Workspace zeigt keine Module
|
||||
8. Direkte Links auf berechtigte Fachobjekte funktionieren
|
||||
9. Mehrfach-Widgets: Gleicher widget_key kann mehrfach vorkommen
|
||||
10. Workspace-Manager: Kann nur eigenen Workspace konfigurieren
|
||||
11. Cross-Tenant-Zuweisungen unmöglich
|
||||
12. Ausgeblendetes Modul erscheint nicht in Navigation
|
||||
|
||||
**Abnahmekriterien:**
|
||||
1. Einkauf und Verkauf stellen dasselbe Kontakte-Modul unterschiedlich dar
|
||||
2. Kalender unterscheiden sich pro Workspace
|
||||
3. Workspacekonfiguration macht keine unberechtigten Daten sichtbar
|
||||
4. Zwei Browser-Tabs können unterschiedliche Workspaces verwenden
|
||||
5. Derselbe Widget-Typ kann mehrfach vorkommen
|
||||
6. Workspace-Manager kann nur seinen Workspace konfigurieren
|
||||
7. Workspace-Manager kann keine Rechte ändern
|
||||
8. Cross-Tenant-Zuweisungen sind unmöglich
|
||||
9. Ein ausgeblendetes Modul erscheint nicht in der Navigation
|
||||
10. Direkte berechtigte Objektlinks bleiben erreichbar
|
||||
|
||||
**Aufwand:** 30–50 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 7 — DMS und Attachments
|
||||
|
||||
**Ziel:** Konsistenter Storage- und Berechtigungspfad für alle Dateiabläufe.
|
||||
|
||||
**Aufgaben:**
|
||||
1. Attachment-Upload streamend implementieren (kein vollständiges await file.read())
|
||||
2. Download über Storage-Streaming
|
||||
3. Alte Attachments nach files + entity_attachments migrieren
|
||||
4. Deduplikation nur tenantlokal
|
||||
5. Physische Datei nur löschen wenn keine Referenzen existieren
|
||||
6. Technische Felder (storage_path, Hashwerte) nicht an Clients ausgeben
|
||||
7. Entity-Typen konsistent registrieren
|
||||
8. Größenlimit, MIME-Prüfung und Hashing zentralisieren
|
||||
9. Lokales Storage und S3 identisch behandeln
|
||||
10. Keine Cross-Tenant-Dateireferenzen
|
||||
11. Optional: Malware-Scan
|
||||
|
||||
**Abnahmekriterien:**
|
||||
- Große Dateien verursachen keine mehrfache RAM-Belegung
|
||||
- Lokaler und S3-Storage funktionieren
|
||||
- Bestehende Attachments bleiben erhalten
|
||||
- Tenantfremde Dateien können nicht referenziert werden
|
||||
- Aktive Dateien werden nicht versehentlich physisch gelöscht
|
||||
|
||||
**Aufwand:** 12–20 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 8 — Verbleibende Sicherheits- und Betriebsfehler
|
||||
|
||||
**HTML:**
|
||||
1. Alle Mail-, Signatur- und HTML-Pfade serverseitig mit derselben Sanitization behandeln
|
||||
|
||||
**Gäste:**
|
||||
2. Tenant-Slug verpflichtend oder eindeutige Tenant-Auswahl
|
||||
3. Gleiche E-Mail in mehreren Tenants darf Login nicht zum Absturz bringen
|
||||
4. Sofortiger Session-Widerruf
|
||||
5. Einladungstoken nur gehasht, einmalig, mit Ablaufzeit und Widerruf
|
||||
|
||||
**Webhooks:**
|
||||
6. SSRF-Schutz beibehalten
|
||||
7. DNS-Ziel beim tatsächlichen Connect erneut prüfen
|
||||
8. Redirects begrenzen oder deaktivieren
|
||||
9. Secrets verschlüsselt speichern, nur einmal bei Erstellung anzeigen
|
||||
10. Interne und private Netze blockieren
|
||||
11. Retry und Fehlerstatus implementieren
|
||||
|
||||
**Healthchecks:**
|
||||
12. Trennen: /health/live, /health/ready, /metrics
|
||||
13. Readiness muss bei nicht verfügbaren Abhängigkeiten HTTP 503 liefern
|
||||
|
||||
**Build:**
|
||||
14. Entfernen: `npm ci || npm install` → Verwenden: `RUN npm ci`
|
||||
15. Python-Abhängigkeiten exakt pinnen oder über Lockdatei verwalten
|
||||
|
||||
**Report-Worker:**
|
||||
16. Keine direkten Cross-Plugin-Imports
|
||||
17. DMS nur über Contract oder Core-Service
|
||||
18. PDF-Erstellung nur im Worker
|
||||
19. Synchronen API-Reportpfad entfernen oder stark begrenzen
|
||||
20. Read-only-Dateisystem, CPU- und RAM-Limits, kein allgemeiner Netzwerkzugriff
|
||||
|
||||
**Aufwand:** 10–18 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 9 — CI und verbindliche Quality Gates
|
||||
|
||||
**Ziel:** Jeder Merge muss folgende Gates bestehen:
|
||||
|
||||
| # | Gate |
|
||||
|---|------|
|
||||
| 1 | Python Compile |
|
||||
| 2 | Ruff |
|
||||
| 3 | Python Typecheck |
|
||||
| 4 | Vollständige Testcollection |
|
||||
| 5 | Pytest |
|
||||
| 6 | Frontend Typecheck |
|
||||
| 7 | Vitest |
|
||||
| 8 | Frontend Production Build |
|
||||
| 9 | Cross-Plugin-Importprüfung |
|
||||
| 10 | SQL-Injection-Prüfung |
|
||||
| 11 | Jinja-Sandbox-Test |
|
||||
| 12 | RLS-Variablenprüfung |
|
||||
| 13 | RLS-Abdeckungsprüfung |
|
||||
| 14 | Cross-Tenant-Integrationstest |
|
||||
| 15 | Test mit echter crm_api-Rolle |
|
||||
| 16 | Login-Test mit crm_auth |
|
||||
| 17 | Alembic auf leerer Datenbank |
|
||||
| 18 | Upgrade von vorherigem Release |
|
||||
| 19 | Container Smoke Test |
|
||||
| 20 | API- und Worker-Healthcheck |
|
||||
| 21 | Dependency Scan |
|
||||
| 22 | Prüfung auf unerlaubte Bootstrap-RLS-Policies |
|
||||
| 23 | Prüfung der Tabellenowner |
|
||||
| 24 | Prüfung auf genau einen Alembic-Head |
|
||||
|
||||
Kein Gate darf über `|| true`, `allow_failure` oder `continue-on-error` ignoriert werden.
|
||||
|
||||
**Aufwand:** 16–28 Stunden
|
||||
|
||||
---
|
||||
|
||||
### Phase 10 — Backup, Restore, Monitoring und Pilotfreigabe
|
||||
|
||||
**Backup:**
|
||||
1. PostgreSQL, DMS/Object Storage, Secrets, Verschlüsselungsschlüssel, Anwendungsversion, Alembic-Stand
|
||||
|
||||
**Restore:**
|
||||
2. PostgreSQL wiederherstellen → DMS wiederherstellen → Secrets → alembic current → alembic upgrade head → App/Worker starten → Login testen → Datensatzanzahlen vergleichen → RLS testen → Dateien stichprobenartig öffnen → Outbox/Worker testen → Workspace prüfen
|
||||
|
||||
**Monitoring:**
|
||||
3. Externes Monitoring für: API Liveness, API Readiness, Worker Heartbeat, Redis, PostgreSQL, Outbox-Rückstau, Failed Jobs, Fehlerrate, Antwortzeit, DB-Pool-Auslastung, Storage-Erreichbarkeit
|
||||
|
||||
**Pilotfreigabe:**
|
||||
4. Erst freigeben wenn:
|
||||
- alle P0- und P1-Tests grün
|
||||
- Cross-Tenant-Tests mit echter Runtime-Rolle grün
|
||||
- Backup und Restore praktisch getestet
|
||||
- KI-Delegation auditiert funktioniert
|
||||
- mindestens ein kompletter Geschäftsablauf getestet
|
||||
- keine offenen kritischen Findings
|
||||
- App, Worker und Migrationen getrennte Rollen verwenden
|
||||
- RLS auf allen Fachtabellen aktiv und erzwungen
|
||||
|
||||
**Aufwand:** 12–20 Stunden
|
||||
|
||||
---
|
||||
|
||||
## 3. Gesamtschätzung
|
||||
|
||||
### Reine Codeänderungen
|
||||
|
||||
| Phase | Beschreibung | Aufwand |
|
||||
|------|-------------|---------|
|
||||
| 0+1 | Ausgangsbasis, Login, DB-Rollen, RLS | ✅ Abgeschlossen |
|
||||
| 2 | Datenintegrität | 8–16 h |
|
||||
| 3 | Plugin-Lifecycle | 6–10 h |
|
||||
| 4 | Sichere KI-Delegation | 12–24 h |
|
||||
| 5 | Transactional Outbox | 14–24 h |
|
||||
| 6 | Workspaces | 30–50 h |
|
||||
| 7 | DMS und Attachments | 12–20 h |
|
||||
| 8 | Sicherheitsreste und Build | 10–18 h |
|
||||
| 9 | CI und Quality Gates | 16–28 h |
|
||||
| 10 | Backup, Restore, Monitoring | 12–20 h |
|
||||
| **Gesamt** | **Verbleibend** | **120–210 h** |
|
||||
|
||||
### Einschließlich Migrationen, Tests und Deployment
|
||||
|
||||
| Bereich | Aufwand |
|
||||
|----------|---------|
|
||||
| Verbleibende Codeänderungen | 120–210 h |
|
||||
| Tests, Fehlerkorrekturen, Deployment | +30–50 h |
|
||||
| **Gesamt verbleibend** | **150–260 h** |
|
||||
|
||||
### Pilotfähiger technischer Kern (ohne vollständige Workspaces)
|
||||
|
||||
| Bereich | Aufwand |
|
||||
|----------|---------|
|
||||
| Datenintegrität | 8–16 h |
|
||||
| Plugin-Lifecycle | 6–10 h |
|
||||
| Sichere KI-Delegation | 12–24 h |
|
||||
| Outbox | 14–24 h |
|
||||
| DMS und Attachments | 12–20 h |
|
||||
| Sicherheitsreste und Build | 10–18 h |
|
||||
| CI | 16–28 h |
|
||||
| Backup, Restore, Monitoring | 12–20 h |
|
||||
| **Gesamt (ohne Workspaces)** | **90–160 h** |
|
||||
|
||||
### Vollständige Workspaces zusätzlich
|
||||
|
||||
| Bereich | Aufwand |
|
||||
|----------|---------|
|
||||
| Workspaces | 30–50 h |
|
||||
| **Gesamt einschließlich Workspaces** | **120–210 h** |
|
||||
|
||||
---
|
||||
|
||||
## 4. Empfohlene Reihenfolge
|
||||
|
||||
1. **Phase 2** (Datenintegrität) — Fundament für alle weiteren Phasen
|
||||
2. **Phase 3** (Plugin-Lifecycle) — Saubere Basis für Plugin-Funktionen
|
||||
3. **Phase 5** (Outbox) — Bereits teilweise implementiert, fertigstellen
|
||||
4. **Phase 4** (KI-Delegation) — Baut auf Outbox auf
|
||||
5. **Phase 7** (DMS) — Unabhängig, parallel möglich
|
||||
6. **Phase 8** (Sicherheitsreste) — Unabhängig, parallel möglich
|
||||
7. **Phase 9** (CI) — Nach allen Code-Phasen, vor Pilot
|
||||
8. **Phase 6** (Workspaces) — Größter Aufwand, nach Kern-Stabilität
|
||||
9. **Phase 10** (Backup, Monitoring, Pilot) — Als Abschluss
|
||||
|
||||
---
|
||||
|
||||
## 5. Nächste Schritte
|
||||
|
||||
1. **Freigabe Phase 2** — Nach Abnahme dieses Berichts
|
||||
2. **Coolify-API-Token widerrufen** — Token wurde im Chat verwendet
|
||||
3. **Produktions-Passwörter rotieren** — Falls noch nicht geschehen
|
||||
4. **Coolify .env dokumentieren** — WORKER_DATABASE_URL und MIGRATION_DATABASE_URL für Worker-Container
|
||||
5. **Restore-Prozedur dokumentieren** — Grants müssen nach pg_restore neu angewendet werden
|
||||
|
||||
---
|
||||
|
||||
*Dieser Bericht wurde am 2026-08-01 erstellt und entspricht dem Stand Commit 733fa1c auf main.*
|
||||
Reference in New Issue
Block a user