be20a8545e
- 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
477 lines
19 KiB
Markdown
477 lines
19 KiB
Markdown
# 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.*
|