ÜBERHOLT – NICHT ALS UMSETZUNGSANWEISUNG VERWENDEN # LeoCRM Sanierungsfortschritt **Letztes Update:** 2026-08-03 **Git-Commit:** 310a9f0 (main) **Alembic-Head:** 0092 **Produktion:** https://crm.media-on.de — healthy > Diese Datei ist der kompakte Fortschritts-Tracker für den Sanierungsplan. > Der vollständige Sanierungsplan steht in `docs/ABSCHLUSSBERICHT_PHASE0_PHASE1.md`. > Die Installationsanleitung steht in `docs/INSTALL.md`. --- ## Phasen-Status | Phase | Status | Commit | Tests | Migration | |-------|--------|--------|-------|----------| | 0 — Ausgangsbasis | ✅ Abgeschlossen | v-phase0-baseline | — | — | | 1 — Login, DB-Rollen, RLS | ✅ Abgeschlossen | 733fa1c | 35 Backend + 14 Plugin | 0085–0090 | | 2 — Datenintegrität | ✅ Abgeschlossen | 745bc4f | FK-Tests auf Produktion | 0091 | | 3 — Plugin-Lifecycle | ✅ Abgeschlossen | dfd9e77 | 14/14 pytest | — | | 4 — KI-Delegation | ⏳ Nicht begonnen | — | — | — | | 5 — Outbox | ✅ Abgeschlossen | 07a9997 | 18/18 pytest + Prod-Smoke | 0092 | | 6 — Workspaces | ✅ Abgeschlossen | 310a9f0 | 25 Backend + 12 Frontend | 0072–0074 | | 7 — DMS/Attachments | ⏳ Nicht begonnen | — | — | — | | 8 — Sicherheitsreste | ⏳ Nicht begonnen | — | — | — | | 9 — CI/Quality Gates | ⏳ Nicht begonnen | — | — | — | | 10 — Backup/Monitoring/Pilot | ⏳ Nicht begonnen | — | — | — | --- ## Abgenommene Gates (Phase 0+1) | Gate | Beschreibung | Status | |------|-------------|--------| | Gate 1 | Reproduzierbares Coolify-Deployment | ✅ | | Gate 2 | Neuinstallation auf leerer Datenbank | ✅ | | Gate 3 | Vollständiger Restore-Test | ✅ | | Gate 4 | Passwort-Reset end-to-end | ✅ | | Gate 5 | Worker und Eventhandler | ✅ | --- ## Produktions-Setup ### Coolify-Ressourcen | Ressource | UUID | Typ | |-----------|------|------| | API (crm.media-on.de) | stvabl4vaqru7jclx4ittzr3 | Application | | Worker | asxqaq3566to108xordck0ff | Service | | PostgreSQL | (Coolify Service) | Service | | Redis | (Coolify Service) | Service | ### Datenbankrollen | Rolle | Superuser | BYPASSRLS | Verwendung | |-------|----------|-----------|------------| | crm_user | Ja | Ja | Bootstrap (POSTGRES_USER) | | crm_migration | Nein | Ja | Alembic + Plugin-Migrationen (DDL) | | crm_auth | Nein | Nein | Login, Authentifizierung | | crm_api | Nein | Nein | API-Abfragen | | crm_worker | Nein | Nein | ARQ-Worker, Outbox | ### Volumes | Volume | Verwendung | |--------|------------| | crm-postgres-data | PostgreSQL-Daten | | crm-redis-data | Redis-Daten | | stvabl4vaqru7jclx4ittzr3_storage | API + Worker Storage (geteilt) | ### Deployment ```bash # Full deploy (API + Worker) über Coolify API COOLIFY_API_TOKEN= python scripts/deploy.py # Nur Verifikation COOLIFY_API_TOKEN= python scripts/deploy.py --verify-only # Nur Worker COOLIFY_API_TOKEN= python scripts/deploy.py --worker-only ``` --- ## Was erledigt ist ### Phase 0+1 (Security & RLS) - 5 DB-Rollen mit separaten Verbindungen - RLS fail-closed auf 108 Tenant-Tabellen - FORCE ROW LEVEL SECURITY aktiviert - 0 legacy app.tenant_id Policies - Plugin-Migrationen über crm_migration (DDL) - Worker per-Tenant Outbox-Processing mit RLS-Kontext - Event-Handler nur für aktive Plugins - Passwort-Reset end-to-end mit SMTP getestet - Leere DB-Installation ohne manuelle Eingriffe - Restore + Upgrade verifiziert - Coolify Redeploy/Stop/Start funktioniert ohne manuelles Eingreifen ### Phase 2 (Datenintegrität) - 74 FK-Constraints (tenant_id → tenants.id ON DELETE CASCADE) hinzugefügt - 10 globale Tabellen ausgeschlossen - Orphan-Cleanup durchgeführt - FK-Tests auf Produktion: INSERT mit ungültiger tenant_id blockiert ✅ ### Phase 3 (Plugin-Lifecycle) - 14 Tests: Registry, Lifecycle, Idempotency, Dependencies, Core-Schutz - Plugin-Lifecycle war bereits korrekt implementiert - Tests bestätigen: activate → deactivate → reactivate funktioniert --- ## Was als nächstes zu tun ist ### Phase 5 (Outbox) — abgeschlossen (produktionsverifiziert) - Per-Tenant Outbox-Processing (Gate 5) - Dead-Letter-Queue: error_message + failed_at Spalten, Replay-Funktionen - Monitoring: /api/v1/outbox/stats, /failed, /consumer-registry Endpoints - Consumer-Registry: outbox_deliveries pro Consumer-Handler geschrieben - Processing-Recovery: recover_stuck_events (stuck processing -> pending) - Retention-Cleanup: cleanup_published_events (hourly cron job, 30 days) - Replay setzt outbox_deliveries zurueck (clean retry) - 23/23 Unit-Tests + Produktions-Verifikation: - outbox_deliveries: 4 Eintraege mit status=delivered - recover-stuck: 200, 0 stuck events - cleanup-published: 200, 22 alte Events geloescht - consumer-registry: 200, alle Handler gelistet - failed: 200, 0 failed events - stats: 200, korrekte counts - deploy.py repariert: Worker-Deploy funktioniert jetzt korrekt ### Phase 7 (DMS/Attachments) — nicht begonnen - Streaming Upload/Download - Deduplikation tenantlokal - Keine Cross-Tenant-Dateireferenzen - Aufwand: 10–16h ### Phase 4 (KI-Delegation) — nicht begonnen - Delegation-Contract, Tenant-scoped Permissions - Audit, Rollback, Approval - Aufwand: 10–16h ### Phase 6 (Workspaces) — abgeschlossen (produktionsverifiziert) - Backend: Widget CRUD (create, list, update, delete), Manager-Role-Check, Cross-Tenant-Validierung - Default-Workspace Seeding (12 Standard-Module), Set-User-Default-Workspace - Fix: create_workspace Default-Uniqueness (unset others before insert) - Frontend: workspaceStore (Zustand) mit sessionStorage Persistenz - API-Client Interceptor: X-Workspace-ID Header auf allen Requests - useWorkspace hook auf workspaceStore umgestellt - Widget API hooks: useWorkspaceWidgets, useCreateWorkspaceWidget, etc. - Settings-Route: /settings/workspaces mit WorkspaceManagerPage - 25 Backend-Tests + 12 Frontend-Tests (alle bestanden) - Produktions-Verifikation: - 2 Workspaces (Verkauf/Einkauf) mit unterschiedlichen Modulen ✅ - Hidden module (calendar in Einkauf) nicht in Context ✅ - Multiple widgets mit gleichem key (2x recent_contacts) ✅ - Widget CRUD: create, update, delete ✅ - Set-default: Workspace-Wechsel funktioniert ✅ - Manager-Role: Creator ist Manager ✅ - Cross-Tenant: RLS isoliert Workspaces pro Tenant ✅ ### Phase 8–10 — nicht begonnen - Sicherheitsreste, CI, Backup/Monitoring - Aufwand: 38–66h --- ## Wichtige Dateien | Datei | Inhalt | |-------|--------| | `docs/ABSCHLUSSBERICHT_PHASE0_PHASE1.md` | Vollständiger Abschlussbericht + Sanierungsplan | | `docs/INSTALL.md` | Vollständige Installationsanleitung | | `docs/phase0_phase1_acceptance_report.md` | Abnahmeprotokoll Phase 0+1 | | `scripts/deploy.py` | Coolify API Deployment-Skript | | `scripts/seed_admin.py` | Admin-User erstellen | | `docker-compose.yml` | Referenz-Compose (API + Worker + DB + Redis) | | `.env.docker.example` | ENV-Template | | `prestart.sh` | Container-Entrypoint (Migrationen + Rollen) | | `worker.sh` | Worker-Entrypoint | --- ## Wichtige Regeln für den nächsten Agenten 1. **Keine manuellen Docker-Befehle** — alles über Coolify API oder deploy.py 2. **Repo lesen bevor ändern** — docker-compose.yml und deploy.py beachten 3. **Migrationen sind Forward-Only** — keine alten Migrationen verändern 4. **RLS ist fail-closed** — kein Tenant-Kontext = kein Zugriff 5. **crm_api hat keine DDL-Rechte** — Plugin-Migrationen über get_migration_engine() 6. **Worker ist Coolify Service** — UUID asxqaq3566to108xordck0ff 7. **Alle DB-Passwörter sind identisch** — siehe .env.docker.example 8. **pgvector/pgvector:pg16** als DB-Image — nicht postgres:16-alpine 9. **Tests müssen mit echten unprivilegierten Rollen laufen** — nicht mit Superuser 10. **Jede Phase: analysieren → implementieren → migrieren → testen → dokumentieren**