- Old code archived on archive/legacy-v0 and feat/T1-auth - Main contains only requirements and analysis docs - UI Prototype: https://webspace.media-on.de/leocrm-prototype-x7k2p9/ - Ready for Phase 2: Architecture design
26 KiB
LeoCRM — Codebase vs Requirements Analysis
Datum: 2026-06-28
Prüfer: Codebase Explorer (Agent Zero)
Methode: Read-only-Inspektion der bestehenden Codebase gegen bereinigte requirements.md
1. Bestehende Architektur-Übersicht
Stack
| Komponente | Code-Realität | Requirements | Status |
|---|---|---|---|
| Backend | FastAPI 0.115.6 | FastAPI | ✅ kompatibel |
| Python | 3.11+ (pyproject.toml) | 3.12 (Annahme 10) | ⚠️ Minor-Abweichung |
| Datenbank | SQLite (WAL mode) | PostgreSQL 16 | ❌ KONFLIKT |
| ORM | SQLAlchemy 2.0.36 | (offen — architecture.md) | ✅ kompatibel |
| Frontend | Jinja2 Templates (server-side) | React SPA (client-side) | ❌ KONFLIKT |
| Auth | Starlette SessionMiddleware (Cookie) | Session-basiert (Cookie) | ✅ kompatibel |
| Deployment | Docker (single container) | Coolify (Docker) | ⚠️ Single-Container vs Multi-Container |
| Testing | pytest (backend only) | pytest + Vitest + Playwright | ⚠️ Backend-only |
Projekt-Struktur
app/
├── main.py — FastAPI app, lifespan, middleware, router wiring
├── config.py — Pydantic Settings (env: LEOCRM_*)
├── deps.py — Auth dependencies (get_current_user, require_admin)
├── db/
│ ├── models.py — 862 Zeilen, 15 SQLAlchemy-Modelle (alle Core, keine Plugins)
│ ├── session.py — SQLite-Engine, SessionLocal, get_db dependency
│ └── init_db.py — Table creation + demo seed (admin/admin)
├── routes/
│ ├── api_routes.py — JSON auth endpoints (/api/auth/login, /api/auth/logout)
│ ├── html_routes.py — HTML auth endpoints (/login, /logout — Jinja2)
│ ├── company_routes.py— JSON API /api/companies (CRUD, search, export)
│ ├── contact_routes.py— JSON API /api/contacts (CRUD, search)
│ ├── dms_routes.py — JSON API /api/dms/* (folders, files, search, links, bulk)
│ ├── tag_routes.py — JSON API /api/tags (CRUD, assign, bulk-assign)
│ ├── calendar_routes.py— JSON API /api/calendars, /api/entries (CRUD, shares, subtasks, attendees, links)
│ ├── notification_routes.py — JSON API /api/notifications
│ ├── import_routes.py — JSON API /api/companies/import, /api/contacts/import (CSV)
│ ├── public_routes.py — Public share links /api/public/share/{token}
│ └── health_routes.py — /api/health
├── services/
│ ├── auth_service.py — bcrypt password hashing, authenticate_user
│ ├── company_service.py — Company CRUD logic
│ ├── contact_service.py — Contact CRUD logic
│ ├── dms_service.py — DMS file/folder operations (26KB, größte Service-Datei)
│ ├── tag_service.py — Tag CRUD + assignment
│ ├── calendar_service.py — Calendar/entry/subtask/attendee/notification logic (21KB)
│ ├── permission_service.py— DMS permissions + share links
│ ├── import_service.py — CSV import for companies/contacts
│ └── export_service.py — CSV/XLSX export for companies
├── schemas/ — Pydantic schemas (auth, company, contact, dms, tag, calendar, common)
└── templates/ — Jinja2 HTML templates (login, register, dashboard, company_form, contact_form, contact_list, base)
Patterns
- Monolith: Single FastAPI app, alle Module fest eingebaut
- Dual-Interface: HTML routes (Jinja2) + JSON API routes parallel
- Service-Layer: Business-Logik in
services/, Routes sind dünn - SQLAlchemy 2.0: DeclarativeBase, Mapped types, mapped_column
- Soft-Delete:
deleted_atauf Company, Contact, Folder, File - N:M Junctions: CompanyContact, TagAssignment, FileEntityLink, EntryLink, CalendarShare
- RBAC: 3 Rollen (admin, editor, viewer) — hardcoded in
require_admindependency - Demo-Seed: init_db() erstellt admin/admin + 2 Firmen + 3 Kontakte
2. Konflikte: Requirements vs Code-Realität
K1: Multi-Tenant (F-AUTH-07, F-CORE-02) — KRITISCH
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| tenant_id | Auf allen Core-Tabellen | Nirgendwo vorhanden |
| Tenant-Isolation | ORM filtert automatisch | Keine Filterung |
| User-Tenant-Zuordnung | User kann zu mehreren Tenants gehören | Nicht implementiert |
| Tenant-Switch UI | Wechsel aktiver Tenant | Nicht vorhanden |
| Plugin-Tabellen | Müssen tenant_id haben | N/A (keine Plugins) |
Evidence:
models.pyZeile 42:class User(Base):docstring sagt explizit"Login account for LeoCRM (single-tenant)."- Keine
tenant_id-Spalte auf Company, Contact, Folder, File, Tag, Calendar, CalendarEntry, Notification, Permission, ShareLink deps.py: Session speichert nuruser_id, keintenant_id-Kontext- Keine Tenant-Modell-Klasse existiert
Impact: Fundamentale Architektur-Veränderung erforderlich. Jede Tabelle braucht tenant_id, ORM-Queries müssen tenant-gefiltert sein, User-Tenant-Mapping-Tabelle nötig.
K2: Plugin-System (F-PLUGIN-01, F-PLUGIN-02) — KRITISCH
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Plugin-Architektur | Core-Feature v1 | Nicht existent |
| DMS/Kalender/Tags/Mail | Als Plugins implementiert | Fest im Core eingebaut |
| Plugin-Manifest | Definiertes Format | Nicht vorhanden |
| Lifecycle-Hooks | install/activate/deactivate/uninstall | Nicht vorhanden |
| Plugin-API-Endpunkte | Plugins registrieren eigene Routes | Nicht vorhanden |
| Plugin-DB-Migration | Eigene Migrationen | Nicht vorhanden |
| Plugin-Abhängigkeiten | Deklarierbar | Nicht vorhanden |
Evidence:
grep -rn 'plugin\|Plugin\|manifest\|lifecycle\|activate\|deactivate' app/→ 0 Treffer- DMS:
models.pyFolder/File/FileEntityLink +dms_service.py(26KB) +dms_routes.py— alles fest im Core - Kalender:
models.pyCalendar/CalendarShare/CalendarEntry/Attendee/EntryLink/SubTask +calendar_service.py(21KB) +calendar_routes.py— fest im Core - Tags:
models.pyTag/TagAssignment +tag_service.py+tag_routes.py— fest im Core - Keine Plugin-Registry, kein Plugin-Loader, kein Manifest-Format
Impact: Komplette Plugin-Architektur muss neu gebaut werden. Bestehende DMS/Kalender/Tag-Module müssen in Plugins umgewandelt werden.
K3: Datenbank — SQLite vs PostgreSQL — KRITISCH
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| DB-Engine | PostgreSQL 16 | SQLite |
| Connection-Pooling | PostgreSQL MVCC | SQLite WAL, check_same_thread=False |
| Concurrent Writes | Multi-User fähig | SQLite limitiert |
Evidence:
config.py:db_path: str = Field(default=str(Path("/data/leocrm.db")))→ SQLite-Dateiconfig.py:database_urlproperty →f"sqlite:///{self.db_path}"session.py: SQLite-spezifische PRAGMAs (PRAGMA foreign_keys = ON,PRAGMA journal_mode = WAL)session.py:connect_args={"check_same_thread": False}— SQLite-onlypyproject.toml: Keinepsycopg2/asyncpg/psycopg-Dependency
Impact: DB-Layer muss auf PostgreSQL umgestellt werden. Session-Engine, PRAGMAs, connect_args müssen angepasst werden.
K4: Frontend — Jinja2 vs React SPA — KRITISCH
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Frontend | React SPA (client-side) | Jinja2 Templates (server-side) |
| i18n | DE + EN, Sprachwahl persistiert | Nicht implementiert |
| UI-Plugin-Framework | Plugins registrieren UI-Komponenten | Nicht vorhanden |
Evidence:
app/templates/: 7 Jinja2-HTML-Templates (login, register, dashboard, company_form, contact_form, contact_list, base)html_routes.py: Jinja2Templates, TemplateResponse- Keine
package.json, keine.tsx/.jsx-Dateien, kein React/Vite-Setup pyproject.toml:jinja2==3.1.5als Dependency- Requirements Annahme 3: "SPA-Frontend: Client-side rendering mit React SPA (bestätigt durch genehmigten Prototyp leocrm-prototype-x7k2p9)"
Impact: Komplettes Frontend muss als React SPA neu gebaut werden. Jinja2-Templates und HTML-Routes werden obsolet. UI-Plugin-Framework (F-CORE-04) muss in React integriert werden.
K5: F-CORE-01 — Event Bus — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Event Bus | Core-Feature v1 | Nicht implementiert |
| Events emit/subscribe | Typisiert, Payload, asynchron | Nicht vorhanden |
| Plugin-Listener | Registrieren beim Aktivieren | N/A |
Evidence: grep -rn 'event.bus\|EventBus\|event_bus\|emit\|subscribe\|listener' app/ → 0 Treffer
K6: F-CORE-05 — Service Container / DI — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Service Container | Core-Services über Container | Nicht implementiert |
| DI für Plugins | Services injiziert | N/A |
| Mocking für Tests | Mock-Services injizierbar | Nur DB-Session override |
Evidence: Services werden direkt importiert (from app.services import company_service), nicht über Container. FastAPI Depends() ist das einzige DI-Muster, aber nur für Request-Scoped dependencies (DB-Session, Current-User).
K7: F-CORE-06 — API-First Architecture — TEILWEISE
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Alle Features über API | API-First | Teilweise — API routes existieren für alle Module |
| UI ist API-Client | UI nutzt API | ❌ Jinja2 rendert server-side |
| API versioniert | z.B. /api/v1/ | ❌ Keine Versionierung |
| OpenAPI/Swagger | Auto-gen, dokumentiert | ⚠️ FastAPI auto-gen existiert, aber nicht explizit konfiguriert |
| Plugin-API-Endpunkte | Registrierbar | N/A |
| KI-Copilot nutzt API | Gleiche Endpunkte | Nicht implementiert |
Evidence:
- API routes:
/api/companies,/api/contacts,/api/dms/*,/api/tags/*,/api/calendars,/api/entries,/api/notifications,/api/auth/* - Kein
/api/v1/Prefix — alle routes sind unversioniert - FastAPI generiert automatisch OpenAPI unter
/openapi.json, aber nicht explizit konfiguriert oder dokumentiert - HTML routes existieren parallel (
/login,/dashboard) — UI ist NICHT API-Client
K8: F-CORE-07 — Async Job Queue — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Queue-System | Background-Jobs asynchron | Nicht implementiert |
| Retry-Logic | Automatische Retries | Nicht vorhanden |
| Dead-Letter-Queue | Bei wiederholtem Fehlschlag | Nicht vorhanden |
| Job-Status UI | Sichtbar im UI | Nicht vorhanden |
Evidence: grep -rn 'celery\|Celery\|queue\|Queue\|async_job\|background_job\|job_queue' app/ → 0 Treffer
K9: F-CORE-08 — Caching-Strategie — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Cache-Backend | Sessions, Query-Cache, Plugin-Data | Nicht implementiert |
| Cache-Invalidierung | Event-basiert | N/A |
| TTL-Caching | Fallback | Nur @lru_cache für Settings |
Evidence: grep -rn 'cache\|Cache\|redis\|Redis' app/ → nur functools.lru_cache in config.py für Settings-Caching. Kein Redis, kein Query-Cache.
K10: F-CORE-09 — User-Profile und Preferences — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| User-Profile | Profil mit Preferences | Nicht implementiert |
| Sprache/Zeitzone/Theme | Umschaltbar | Nicht vorhanden |
| Dashboard-Konfiguration | Konfigurierbar | Nicht vorhanden |
| Plugin-Preferences | Eigene Felder registrierbar | N/A |
Evidence: User-Modell hat nur: id, username, password_hash, role, personal_folder_id, default_calendar_id, created_at. Keine Preferences, keine Sprache, keine Zeitzone.
K11: F-CORE-10 — Storage-Backend — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| S3-kompatibel | Konfigurierbar | Nicht implementiert |
| Lokales Volume | Alternative | Lokales Dateisystem |
| Presigned-URLs | Download ohne Plugin-Code | Nicht vorhanden |
| Storage-Service | Core-Service für Plugins | Direkter Dateizugriff |
Evidence:
config.py:dms_storage_path: str = Field(default="/data/dms")— lokales Verzeichnisdms_service.py: Direkter Dateizugriff viaopen(),Path-Operationen- Keine S3/MinIO/boto3-Integration
grep -rn 's3\|S3\|boto3\|storage_backend\|presigned' app/→ 0 Treffer
K12: F-CORE-11 — Generic Import/Export Service — TEILWEISE
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| CSV-Import | Mit Preview, Dry-Run, Fehler-Reporting | ⚠️ Nur direkter Import ohne Preview/Dry-Run |
| Excel-Export | Feld-Auswahl, Filterung | ⚠️ CSV + XLSX Export, aber begrenzte Feld-Auswahl |
| Plugin-Definitionen | Registrierbar | N/A |
Evidence:
import_service.py:import_companies_csv(),import_contacts_csv()— direkter Import, kein Preview, kein Dry-Runexport_service.py:export_companies_csv(),export_companies_xlsx()— Export funktioniert, aber nicht generisch/plugin-fähig- Import/Export ist hardcoded für Companies/Contacts, nicht generisch
K13: F-CORE-12 — PDF/Document Generation Service — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| PDF-Generierung | Aus Templates | Nicht implementiert |
| Template-Engine | Variablen, Conditionals, Tabellen | Nicht vorhanden |
| Storage-Integration | PDFs im Storage gespeichert | N/A |
Evidence: grep -rn 'pdf\|PDF\|weasyprint\|reportlab\|pdfkit' app/ → nur DMS-Preview (stream existing PDFs), keine Generierung
K14: F-CORE-13 — Notification Service — TEILWEISE
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| In-App-Notifications | Bell-Icon, Badge-Zähler | ⚠️ DB-Modell existiert, keine UI |
| E-Mail-Channel | Notifications per Mail | Nicht implementiert |
| Preferences | Pro User konfigurierbar | Nicht vorhanden |
| Tenant-Isolation | Pro Tenant isoliert | N/A (single-tenant) |
| Plugin-Notification-Typen | Registrierbar | N/A |
Evidence:
models.py:Notification-Modell existiert (id, user_id, type, title, body, related_entry_id, is_read, created_at)notification_routes.py: API für List/Mark-Read existiert- Keine E-Mail-Integration, keine Preferences, kein Badge-Zähler in UI (Jinja2-Templates haben kein Notification-UI)
K15: F-AUTH-01 — Login mit E-Mail — KONFLIKT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Login-Feld | E-Mail + Passwort | Username + Passwort |
| Session-Cookie | HttpOnly, Secure, SameSite=Strict | SameSite=lax, https_only conditional |
Evidence:
auth_service.py:authenticate_user(db, username, password)— verwendetusername, nichtemailmodels.py:User.username: Mapped[str]— keinemail-Feld auf Userdeps.py: Session speichertuser_id, kein Tenant-Kontextmain.py:same_site="lax"(requirements sagen Strict),https_only=settings.is_production(requirements sagen Secure)
K16: F-AUTH-03 — User-Verwaltung durch Admin — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Admin legt User an | E-Mail, Name, Rolle, Passwort | Nicht implementiert |
| User-Tenant-Zuordnung | User wird Tenant zugeordnet | N/A |
| Keine Self-Registration | Admin-only | ⚠️ Register-Template existiert |
Evidence:
- Keine User-Management-Routes (kein
/api/users, kein Admin-User-CRUD) app/templates/register.htmlexistiert — Self-Registration-Template (widerspricht Non-Goal #1)init_db.py: Demo-Seed erstellt nur admin/admin
K17: F-AUTH-05 — Passwort-Reset — FEHLT
| Aspekt | Requirements | Code-Realität |
|---|---|---|
| Reset-Flow | E-Mail mit Reset-Link | Nicht implementiert |
| Reset-Link | Gültig 24h | Nicht vorhanden |
Evidence: Keine Reset-Routes, keine Reset-Templates, keine Token-Generierung.
K18: F-AUTH-07 — Multi-Tenant — FEHLT (siehe K1)
Bereits in K1 abgedeckt. Keine Tenant-Modelle, keine User-Tenant-Mapping-Tabelle.
K19: DMS/Calendar/Tags als Core vs Plugin — ARCHITEKTUR-KONFLIKT
| Modul | Requirements | Code-Realität |
|---|---|---|
| DMS | v2-Plugin (F-FILE/F-DMS/F-LINK/F-PERM) | Core: 3 Modelle + 26KB Service + eigene Routes |
| Kalender | v2-Plugin (F-CAL-01..18) | Core: 6 Modelle + 21KB Service + eigene Routes |
| Tags | v2-Plugin (F-TAG-01..04) | Core: 2 Modelle + 8KB Service + eigene Routes |
| v2-Plugin (F-MAIL-01..19) | Nicht implementiert |
Evidence: Alle Module sind direkt in models.py, services/, routes/ integriert. Keine Plugin-Grenzen, keine Plugin-Schnittstellen.
Hinweis: Requirements sagen Plugin-System ist v1-Core-Feature, aber die Module selbst sind v2-Plugins. Das bedeutet: In v1 muss das Plugin-System gebaut werden, aber DMS/Kalender/Tags können als v2-Plugins nachgezogen werden. Die bestehenden Implementierungen können als Referenz dienen, müssen aber auf Plugin-Architektur umgebaut werden.
3. Kompatibel — Was bereits passt
✅ Session-basierte Auth (F-AUTH-01/02, Annahme 12)
- Starlette
SessionMiddlewaremit signed Cookie session_cookie="leocrm_session",max_agekonfigurierbar- Login setzt
request.session[SESSION_USER_ID_KEY] = user.id - Logout cleared session
- Kompatibel mit Requirements (Session-basiert, Cookie-basiert)
✅ RBAC Grundgerüst (F-AUTH-04/06)
- 3 Rollen: admin, editor, viewer
require_admindependency prüftuser.role == "admin"get_current_userdependency für auth-geschützte Routes- Kompatibel mit Requirements (3 Rollen v1)
✅ Company/Contact CRUD (F-COMP-01..06, F-CONT-01..07)
- Company: 27 Felder (Name, Adresse, Industrie, Revenue, etc.)
- Contact: 29 Felder (Name, Email, Phone, Title, etc.)
- N:M Junction:
CompanyContact - Soft-Delete:
deleted_atauf beiden - Pagination, Search, Filter, Sort in Routes
- Kompatibel mit Requirements
✅ Data-Features (F-DATA-01..04)
- Pagination:
PageResponseschema - Search: Query-Parameter in company/contact routes
- Sort: Sortier-Parameter
- Soft-Delete:
deleted_at+ restore functionality - Kompatibel mit Requirements
✅ Health-Check (F-INFRA-01)
/api/healthendpoint, prüft DB, gibt Status + Version- Nicht auth-geschützt (für Coolify/LB)
- Kompatibel mit Requirements
✅ Import/Export Grundgerüst (F-MIG-01, F-DATA-01/02)
- CSV-Import für Companies/Contacts
- CSV + XLSX Export für Companies
- Teilweise kompatibel — fehlt Preview, Dry-Run, generische Service-Architektur
✅ DMS-Features (als Referenz für späteres Plugin)
- Folder-Tree mit materialized path
- File-Upload, Preview (PDF), Soft-Delete, Restore
- Entity-Links (N:M zu Companies/Contacts)
- Permissions (Individual/Group/Default)
- Share-Links mit Password + Expiry
- OnlyOffice-Edit-Session
- Vollständig implementiert — kann als Plugin-Referenz dienen
✅ Calendar-Features (als Referenz für späteres Plugin)
- Calendar CRUD, Sharing, Visibility-Toggle
- Entries: Events/Tasks/Reminders, Kanban-Status
- Subtasks, Attendees, Entry-Links
- Notifications für Reminders/Invites/Shares
- Vollständig implementiert — kann als Plugin-Referenz dienen
✅ Tag-System (als Referenz für späteres Plugin)
- Tag CRUD (admin-only), Color, Assignment
- Bulk-Assign, Entity-Type polymorphic
- Vollständig implementiert — kann als Plugin-Referenz dienen
✅ Testing-Setup (F-TEST-01)
- pytest mit 20+ Test-Dateien
- conftest.py mit Fixtures
- Coverage-Messung konfiguriert
- Teilweise kompatibel — fehlt Vitest (Frontend) und Playwright (E2E)
4. F-CORE-Feature-Matrix
| F-CORE-ID | Feature | Status im Code | Anmerkung |
|---|---|---|---|
| F-CORE-01 | Event Bus | ❌ Nicht implementiert | Keine Event-Infrastruktur |
| F-CORE-02 | Tenant-Isolation | ❌ Nicht implementiert | Kein tenant_id, single-tenant |
| F-CORE-03 | Plugin-DB-Migration | ❌ Nicht implementiert | Kein Plugin-System |
| F-CORE-04 | UI-Plugin-Framework | ❌ Nicht implementiert | Jinja2, keine Plugin-UI |
| F-CORE-05 | Service Container / DI | ❌ Nicht implementiert | Direkte Imports, nur FastAPI Depends |
| F-CORE-06 | API-First Architecture | ⚠️ Teilweise | API routes existieren, aber HTML parallel, keine Versionierung |
| F-CORE-07 | Async Job Queue | ❌ Nicht implementiert | Keine Queue-Infrastruktur |
| F-CORE-08 | Caching-Strategie | ❌ Nicht implementiert | Nur lru_cache für Settings |
| F-CORE-09 | User-Profile/Preferences | ❌ Nicht implementiert | User hat nur username/role |
| F-CORE-10 | Storage-Backend | ❌ Nicht implementiert | Lokales Dateisystem, kein S3 |
| F-CORE-11 | Generic Import/Export | ⚠️ Teilweise | CSV/XLSX funktioniert, nicht generisch, kein Preview/Dry-Run |
| F-CORE-12 | PDF Generation | ❌ Nicht implementiert | Keine PDF-Generierung |
| F-CORE-13 | Notification Service | ⚠️ Teilweise | DB-Modell + API existiert, keine UI, kein E-Mail-Channel |
Bilanz: 0/13 vollständig implementiert, 3/13 teilweise, 10/13 fehlen komplett.
5. Empfehlung: Was vor Phase 2 angepasst werden muss
Priorität 1 — Fundamentale Architektur (vor allem anderen)
-
Datenbank-Migration: SQLite → PostgreSQL
config.py:database_urlauf PostgreSQL umstellensession.py: SQLite-PRAGMAs entfernen, PostgreSQL-Engine konfigurierenpyproject.toml:psycopg[binary]oderasyncpghinzufügendocker-compose.yml: PostgreSQL-Service hinzufügen
-
Multi-Tenant-Architektur
- Neues
Tenant-Modell +UserTenant-Mapping-Tabelle tenant_id-Spalte auf ALLE Core-Tabellen (Company, Contact, Folder, File, Tag, Calendar, etc.)- ORM-Query-Filter: automatische tenant_id-Filterung (SQLAlchemy Event oder Query-Wrapper)
- Session-Kontext: aktiver tenant_id in Session speichern
- Tenant-Switch-Endpoint + UI
- Neues
-
Frontend-Wechsel: Jinja2 → React SPA
- React-Projekt-Setup (Vite + React + TypeScript)
- API-Client-Layer (fetch/axios gegen /api/* Endpunkte)
- Jinja2-Templates und html_routes.py werden obsolet
- i18n-Integration (DE + EN)
- UI-Plugin-Framework vorbereiten (F-CORE-04)
Priorität 2 — Core-Infrastructure (F-CORE)
-
Service Container / DI (F-CORE-05)
- Zentralen Service-Container implementieren
- Core-Services registrieren: DB, Cache, Event Bus, Auth, Config, Logger
- Plugin-Schnittstelle für Service-Requests definieren
-
Event Bus (F-CORE-01)
- Event-Publish/Subscribe-System implementieren
- Typisierte Events mit Payload
- Asynchrone Verarbeitung (ggf. via Job Queue)
-
Plugin-System (F-PLUGIN-01/02)
- Plugin-Manifest-Format definieren
- Lifecycle-Hooks: install, activate, deactivate, uninstall
- Plugin-Registry + Loader
- Plugin-API-Endpunkt-Registrierung
- Plugin-DB-Migration (F-CORE-03)
- Plugin-Abhängigkeiten
-
API-Versionierung (F-CORE-06)
/api/v1/Prefix für alle API-Routes- OpenAPI/Swagger explizit konfigurieren und dokumentieren
- HTML-Routes entfernen (UI wird React SPA = API-Client)
Priorität 3 — Weitere Core-Infrastructure
- Async Job Queue (F-CORE-07) — Queue-System für Background-Jobs
- Caching (F-CORE-08) — Redis-Anbindung, Query-Cache, Cache-Invalidierung
- Storage-Backend (F-CORE-10) — S3-kompatibler Storage-Service
- User-Profile/Preferences (F-CORE-09) — Profil-Erweiterung, Preferences
- Notification Service (F-CORE-13) — E-Mail-Channel, Preferences, Badge-UI
- PDF Generation (F-CORE-12) — Template-Engine, PDF-Generierung
- Generic Import/Export (F-CORE-11) — Generischer Service, Preview, Dry-Run
Priorität 4 — Auth-Ergänzungen
- Login auf E-Mail umstellen (F-AUTH-01) — username → email
- User-Verwaltung durch Admin (F-AUTH-03) — Admin-CRUD für User, Tenant-Zuordnung
- Passwort-Reset (F-AUTH-05) — Reset-Flow mit E-Mail
- Register-Template entfernen — Self-Registration ist Non-Goal
- Cookie-Security anpassen — SameSite=Strict, Secure immer
Was beibehalten werden kann
- Backend-Services (company_service, contact_service, etc.) — Business-Logik ist solide
- Pydantic-Schemas — Können für API-Validierung weiterverwendet werden
- DB-Modelle — Felder/Beziehungen sind korrekt, müssen nur tenant_id ergänzt werden
- Test-Suite — pytest-Tests können erweitert werden
- DMS/Calendar/Tag-Implementierungen — Als Referenz für spätere Plugin-Entwicklung behalten
6. Zusammenfassung
| Kategorie | Anzahl | Status |
|---|---|---|
| Kritische Konflikte | 4 | Multi-Tenant, Plugin-System, DB, Frontend |
| F-CORE fehlend | 10/13 | Event Bus, Tenant-Isolation, Plugin-Migration, UI-Plugin, Service Container, Job Queue, Caching, User-Profile, Storage, PDF |
| F-CORE teilweise | 3/13 | API-First, Import/Export, Notification |
| F-CORE vollständig | 0/13 | — |
| Auth-Konflikte | 4 | Login (username vs email), User-Verwaltung, Passwort-Reset, Cookie-Security |
| Kompatibel | 7+ | Session-Auth, RBAC, Company/Contact CRUD, Data-Features, Health, DMS/Calendar/Tags (als Referenz) |
Fazit: Die bestehende Codebase ist eine funktionsfähige v0.1-Implementierung (Single-Tenant, SQLite, Jinja2), die den bereinigten v1-Requirements in 4 kritischen Bereichen nicht entspricht: Multi-Tenant, Plugin-System, PostgreSQL, React SPA. 10 von 13 F-CORE-Features fehlen komplett. Die bestehende Business-Logik (Services, Schemas, Modelle) ist jedoch solide und kann als Basis für den Umbau dienen. Der Aufwand für Phase 2 ist erheblich — es handelt sich um eine Architektur-Migration, nicht um inkrementelle Erweiterungen.