Files
leocrm/FIX-PLAN.md
T
Agent Zero 7a14973c68 chore: verify all FIX-PLAN items, remove completed, update status
- Verified all 22 FIX-PLAN items against codebase
- 20/22 items confirmed done (P0-1..P0-6, P1-1..P1-11, P2-1, P2-3, P2-4)
- Removed JWT vars from COOLIFY_SETUP.md (P1-10 final fix)
- Remaining: P0-7 (operational), P2-2 (228 cross-imports)
- Updated .a0/current_status.md and .a0/next_steps.md
2026-07-26 16:26:10 +02:00

5.2 KiB

LeoCRM — Umfassender Fix-Plan

Erstellt: 2026-07-25 Letzte Überprüfung: 2026-07-26 — Alle Items gegen Codebasis verifiziert Quellen: Externes Audit (geprüft), eigene Code-Inspektion, Coolify-Deployment-Prüfung


Erledigte Fixes (22 von 24 Items komplett)

Die folgenden Items wurden bei der Überprüfung am 2026-07-26 als erledigt bestätigt:

Item Beschreibung Verifiziert durch
P0-1 Auth-Bypass entfernt app/deps.py — keine X-Internal-Call Headers mehr
P0-2 Migrationen repariert migration_0021.sql gelöscht; Migration 0021 renamed _old Tabellen statt DROP; Migration 0027 kopiert company_id → contact_id mit Backup-Spalte
P0-3 Plugin-Upload deaktiviert app/routes/plugins.py/upload und /install-url return 403 mit upload_disabled / install_url_disabled
P0-4 RLS repariert alembic/versions/0028_rls_force.pyFORCE ROW LEVEL SECURITY + WITH CHECK auf allen Tenant-Tabellen
P0-5 Plugin-Doppelregistrierung app/main.py — Routes in create_app(), lifespan() nur aktiviert/deaktiviert, respektiert DB active Status, Migration-Fail deaktiviert Plugin
P0-6 Persistent Volume docker-compose.ymlstorage:/data/storage, pgdata, redisdata Volumes
P1-1 User/Tenant-Modell app/models/user.pyUser hat keine tenant_id/role mehr, UserTenant ist single source of truth, email global unique
P1-2 Redis zentralisiert app/core/auth.pyinit_redis()/get_redis() Singleton, init_job_pool()/close_job_pool()
P1-3 Worker ausgelagert prestart.sh — nur Alembic + Uvicorn; separater crm-worker Container in docker-compose.yml
P1-4 Transactional Outbox app/core/outbox.py, app/models/outbox.py, alembic/versions/0040_outbox.pyenqueue_outbox_event() + process_outbox_batch() mit FOR UPDATE SKIP LOCKED
P1-5 XSS-Stellen geschlossen HtmlBlock.tsx + SignatureManager.tsxDOMPurify.sanitize(); ActionCardBlock.tsx — URL-Validierung (nur http:/https:)
P1-6 DMS lastfest app/plugins/builtins/dms/routes.py — 1MB Chunked Streaming, SHA-256 Content-Hash
P1-7 Permission-System app/core/permissions.pypermission_version wird beim Cache-Lesen geprüft, redis.scan() statt redis.keys(), require_write() prüft spezifische Permissions
P1-8 Password Reset app/services/auth_service.py — ARQ Job send_password_reset_email, Token used_at Tracking
P1-9 Metrics abgesichert app/routes/metrics.pyDepends(require_admin)
P1-10 Coolify-Doku & Config COOLIFY_SETUP.md — Healthcheck /api/v1/health, JWT-Vars entfernt, CORS :443; app/config.pystorage_path=/data/storage, session_cookie_secure=True, Startup-Validierung; docker-compose.yml — Redis, Volumes, Healthcheck
P1-11 Cross-Tenant FK alembic/versions/0036_cross_tenant_fk.pyUNIQUE (tenant_id, id) + Composite FK (tenant_id, contact_id) auf contactpersons und contact_merge_history
P2-1 Contact Model normalisiert alembic/versions/0039_contact_normalize.pysurfix→suffix, Float→Numeric(5,2), JSON→JSONB, CHECK (0-100), Unique Constraints
P2-3 Commands & Statusmaschinen app/commands/ (base, contact, calendar, dms, mail) + app/core/state_machine.py
P2-4 SPA Path-Traversal app/main.pyos.path.abspath Check + ".." in full_path Blocking

Offene Items

P0-7: App von öffentlicher Domain nehmen

Status: Operational — nicht aus Code verifizierbar

Problem: Die App läuft unter https://crm.media-on.de und ist öffentlich erreichbar.

Maßnahme:

  1. Sofort: App von öffentlicher Domain nehmen oder IP-Whitelist/Basic Auth vorschalten
  2. Mindestens P0-1 (Auth-Bypass ) und P0-3 (Plugin-Upload ) sind bereits behoben
  3. Alternativ: VPN/Tunnel-Zugang statt öffentliche Domain

Aufwand: 30 Minuten


P2-2: Plugin-Cross-Imports reduzieren

Status: Offen — 228 direkte Cross-Imports zwischen Plugins

Problem: 228 direkte from app.plugins.builtins Imports zwischen Plugins. Automatisierung importiert Modelle/Services von Kommunikation, Mail, Kalender. Verteilter Monolith ohne Modulgrenzen.

Maßnahme:

  1. Öffentliche Schnittstellen (Contracts) für jedes Modul definieren
  2. Direkte Imports fremder Plugin-Modelle verbieten
  3. Kommunikation nur über Events oder öffentliche Service-API
  4. CI-Check: keine direkten Cross-Plugin-Imports

Aufwand: 1-2 Wochen


Zusammenfassung

Priorität Erledigt Offen Geschätzter Aufwand (offen)
P0 6/7 1 (operational) 30 Minuten
P1 11/11 0
P2 3/4 1 1-2 Wochen
Total 20/22 2 ~1-2 Wochen

Validierung nach jedem Fix

  • Python-Syntax-Check: python -m py_compile app/**/*.py
  • pytest: pytest tests/ -x
  • Frontend-Typecheck: cd frontend && npx tsc --noEmit
  • Frontend-Build: cd frontend && npx vite build
  • Manueller Smoke-Test: Login, Kontakt erstellen, DMS-Upload
  • Cross-Tenant-Test: Datensatz aus Mandant A kann nicht aus Mandant B gelesen werden
  • Deployment: Coolify Deploy + Healthcheck prüfen