Ü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
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
- Keine manuellen Docker-Befehle — alles über Coolify API oder deploy.py
- Repo lesen bevor ändern — docker-compose.yml und deploy.py beachten
- Migrationen sind Forward-Only — keine alten Migrationen verändern
- RLS ist fail-closed — kein Tenant-Kontext = kein Zugriff
- crm_api hat keine DDL-Rechte — Plugin-Migrationen über get_migration_engine()
- Worker ist Coolify Service — UUID asxqaq3566to108xordck0ff
- Alle DB-Passwörter sind identisch — siehe .env.docker.example
- pgvector/pgvector:pg16 als DB-Image — nicht postgres:16-alpine
- Tests müssen mit echten unprivilegierten Rollen laufen — nicht mit Superuser
- Jede Phase: analysieren → implementieren → migrieren → testen → dokumentieren