Files
crm-system/docs/requirements-review.md
T
leocrm-bot 0d4cbe24dd chore: clean main for new system architecture
- 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
2026-06-28 23:07:21 +02:00

376 lines
28 KiB
Markdown

# Requirements Review: requirements.md
**Datum:** 2026-06-28
**Reviewer:** Requirements Analyst (automatisiert)
**Datei:** `/a0/usr/workdir/dev-projects/leocrm/requirements.md`
**Zeilen:** 2131
**Feature-IDs:** ~141 aktive + 16 archivierte = ~157 total
**Status der Datei:** Finalisiert — ready_for_ui (laut Header)
---
## Section 1: Konsistenz-Issues
### 1.1 Plugin-System vs. Core-Feature Widerspruch (CRITICAL)
**Der zentrale Widerspruch der Datei.**
**F-PLUGIN-01 (Zeile 848-851)** deklariert:
> „Die Module sollen als Plugins realisiert sein, sodass das CRM später durch Plugins erweitert werden kann. Module (Mail, Kalender, Dateien, Tags) sind Plugins."
**F-PLUGIN-02 (Zeile 857-860)** definiert Plugin-Schnittstelle, Lifecycle-Hooks, Plugin-Manifest.
**Gleichzeitig** werden genau diese Module als detaillierte Core-Features mit konkreten HTTP-Endpunkten, DB-Schemas und Test-Szenarien spezifiziert:
- **F-DMS-01 bis F-DMS-07 (Zeilen 991-1083):** DMS mit `POST /api/dms/folders`, `PATCH /api/dms/files/{id}`, etc.
- **F-CAL-01 bis F-CAL-18 (Zeilen 1397-1662):** Kalender mit `POST /api/calendar/entries`, `GET /api/calendar/kanban`, etc.
- **F-MAIL-01 bis F-MAIL-19 (Zeilen 1668-1951):** Mail mit `POST /api/mail/send`, IMAP IDLE, SMTP, PGP, etc.
- **F-TAG-01 bis F-TAG-04 (Zeilen 1173-1223):** Tags mit `POST /api/tags/assign`, etc.
**Widerspruch:** Wenn Module Plugins sind, dann gehören ihre detaillierten Feature-Spezifikationen (Endpunkte, DB-Schemas, Test-Szenarien) NICHT in die Core-Requirements. Der Core definiert die Plugin-Schnittstelle; das Plugin definiert seine eigenen Features. So wie es jetzt ist, wird das Plugin-System deklariert, aber dann werden die „Plugin-Module" im Core-Requirements-Dokument detailliert spezifiziert — als wären sie Core-Features.
**F-CORE-01 bis F-CORE-13 (Zeilen 864-953)** definieren Core-Infrastruktur (Event Bus, Tenant-Isolation, Plugin-Migration, Service Container, API-First, Async Queue, Caching, Storage, Import/Export, PDF-Gen, Notification Service). Diese sind allesamt Architekturentscheidungen, keine Requirements.
**Fazit:** Die Datei versucht gleichzeitig zu sagen „ diese Module sind Plugins" UND „ diese Module sind Core-Features mit konkreten Implementierungsdetails". Das ist ein architektonischer Widerspruch, der in der Architektur-Phase aufgelöst werden muss — nicht in den Requirements.
### 1.2 Multi-Tenant (F-AUTH-07) vs. ältere Requirements ohne Tenant-Kontext (WARNING)
**F-AUTH-07 (Zeile 135-138)** deklariert Multi-Tenant als v1-Feature:
> „Das System ist Multi-Tenant-fähig. Mehrere Firmen (Tenants) können im System verwaltet werden. Daten sind pro Tenant isoliert."
**F-CORE-02 (Zeile 871-874)** spezifiziert `tenant_id` auf allen Tabellen, ORM-Middleware für automatisches Query-Scoping.
**Annahme 1 (Zeile 1978):** „v1 ist Multi-Tenant (Multi-Company) — mehrere Firmen (Tenants) im System."
**Aber:** Die früher geschriebenen Requirements (F-AUTH-01 bis F-CONT-07, Zeilen 57-410) erwähnen Tenant-Kontext an keiner Stelle:
- F-AUTH-01 (Login): kein Tenant-Bezug
- F-AUTH-03 (User-Verwaltung): kein Tenant-Bezug — aber in Multi-Tenant muss ein User einem Tenant zugeordnet sein
- F-COMP-01 (Firma anlegen): kein `tenant_id` in Feld-Tabelle (Zeile 156-186)
- F-CONT-01 (Kontakt anlegen): kein `tenant_id` in Feld-Tabelle (Zeile 300-333)
- F-COMP-05 (Pagination): kein Tenant-Filter erwähnt
- F-COMP-06 (Suche): kein Tenant-Scoping erwähnt
**Fazit:** Multi-Tenant wurde später hinzugefügt und die frühen Requirements wurden nicht nachträglich aktualisiert. Das führt zu einer Lücke: Wie verhält sich F-COMP-01 (Firma anlegen) in Multi-Tenant-Kontext? Wird die Firma automatisch dem aktiven Tenant zugeordnet? Kann ein User Firmen in mehreren Tenants anlegen? Diese Fragen sind in den Requirements nicht beantwortet.
### 1.3 KI-Copilot (F-AI-01) mit voller API-Kontrolle vs. ältere UI-only-Flow-Requirements (WARNING)
**F-AI-01 (Zeile 798-806)** deklariert:
> „Der Copilot hat Zugriff auf die volle API und soll alles steuern können — Daten abfragen, erstellen, bearbeiten, löschen, Aktionen auslösen, Workflows triggern."
**F-CORE-06 (Zeile 899-902)** deklariert API-First:
> „Alle Core-Features und Plugin-Features sind primär über die API nutzbar. Die UI ist ein API-Client."
**Aber:** Mehrere Requirements beschreiben nur UI-Flows ohne API-Bezug:
- F-UI-01 (Responsive Design, Zeile 495-503): nur CSS-Breakpoints, kein API-Bezug
- F-UI-02 (i18n, Zeile 509-517): nur Frontend-Library, kein API-Bezug
- F-UI-03 (Toast-Notifications, Zeile 523-531): nur Frontend-Komponente
- F-UI-04 (Loading-States, Zeile 537-545): nur Frontend-State
- F-UI-05 (Empty-States, Zeile 551-559): nur Frontend-Komponente
- F-UI-06 (Confirmation-Dialogs, Zeile 565-573): nur Frontend-Modal
- F-UI-08 (Datenansichten, Zeile 579-582): nur Frontend-Toggle
**Einschränkung:** Diese UI-Requirements sind legitimerweise UI-only — sie beschreiben Präsentationslogik, keine Datenoperationen. F-CORE-06 sollte explizit ausschließen, dass reine UI-Präsentations-Features keine API-Entpunkte benötigen. Aktuell ist die Formulierung „alle Features über API nutzbar" zu breit und suggeriert, dass auch Toast-Notifications einen API-Endpunkt haben müssten.
**Zusätzlicher Befund:** F-AI-01 und F-CORE-06 wurden retroaktiv hinzugefügt. Die ursprünglichen Requirements (v0.1, archiviert in Appendix A, Zeile 2089-2128) beschreiben Jinja2-Templates und SQLite — eine völlig andere Architektur. Die Datei hat also mindestens drei Evolutionsschichten:
1. v0.1: Single-Tenant, Jinja2, SQLite (archiviert)
2. v0.3: React SPA, PostgreSQL, RBAC (Hauptteil)
3. v0.5+: Multi-Tenant, Plugin-System, API-First, KI-Copilot, Mail/Kalender/DMS (hinzugefügt)
Die Schichten wurden nicht vollständig integriert — Rückbezüge fehlen.
### 1.4 Auth-Mechanismus-Unschärfe (WARNING)
**F-AUTH-01 (Zeile 58):** „Session-basierte Auth mit HttpOnly+Secure+SameSite=Strict Cookie"
**F-AUTH-02 (Zeile 72-78):** Test-Szenario sagt „Token wird entfernt" und Akzeptanzkriterium sagt „Server-Token-Blacklist optional für v1" — das suggeriert Token-basierte Auth (JWT?), nicht Session-basierte Auth.
**F-INT-02 (Zeile 714-722):** „API-Endpunkte sind via Session-Cookie authentifiziert" aber erwähnt auch „Optional: API-Key für externe Integrationen".
**F-SEC-03 (Zeile 616-624):** „Session läuft nach 8h ab" — aber „Token gültig <8h" und „Token nach 8h → API gibt 401" — wieder Token-Sprache.
**Fazit:** Die Datei wechselt inkonsistent zwischen „Session" und „Token". Entweder es ist Session-basiert (Cookie + Server-Side Session Store) oder Token-basiert (JWT Stateless). Das muss entschieden und einheitlich formuliert werden.
---
## Section 2: Requirements vs. Bauanleitung Assessment
### 2.1 Enthaltene Implementierungsdetails
Die Datei enthält massiv Implementierungsdetails, die in eine Requirements-Spec nicht gehören:
#### HTTP-Endpunkte (Architektur, nicht Requirement)
Jedes einzelne Akzeptanzkriterium spezifiziert konkrete HTTP-Endpunkte mit Pfaden, HTTP-Methoden, Query-Parametern und Response-Codes:
- `POST /api/auth/login` (Zeile 65)
- `GET /api/companies/{id}` (Zeile 207)
- `DELETE /api/companies/{id}?cascade=true|false` (Zeile 235)
- `GET /api/contacts?page=1&page_size=25&sort_by=last_name&sort_order=asc` (Zeile 396)
- `POST /api/dms/files/upload` (Zeile 1013)
- `GET /api/dms/files/{id}/preview` (Zeile 1041)
- `POST /api/calendar/entries` (Zeile 1439)
- `GET /api/calendar/kanban?period=this_week` (Zeile 1419)
- `POST /api/mail/send` (Zeile 1693)
- `GET /api/mail/search?q=angebot&folder=inbox` (Zeile 1709)
- ...und dutzende weitere
**Problem:** Der Endpunkt-Pfad ist eine Architekturentscheidung. Ein Requirement sagt „User kann sich einloggen" — der Pfad `/api/auth/login` ist Implementierung.
#### DB-Schema-Definitionen (Architektur, nicht Requirement)
- **F-COMP-01 (Zeilen 156-186):** Vollständige Feld-Tabelle mit Typen: `String(100)`, `Integer`, `Decimal`, `Picklist`, `FK→Company`, `Text(32000)`, etc. — das ist ein DB-Schema
- **F-CONT-01 (Zeilen 300-333):** Vollständige Feld-Tabelle für Kontakte mit Typen
- **F-COMP-07 (Zeile 277):** `audit_log` Tabellenname
- **F-COMP-08 (Zeile 291):** `deletion_log` Tabellenname
- **F-CONT-07 (Zeile 424):** `company_contacts` N:M-Tabellenname
- **F-CORE-02 (Zeile 872):** `tenant_id` Feld auf allen Tabellen
- **F-MAIL-03 (Zeile 1709):** `tsvector`-Index, `mail_body_tsv`, `mail_subject_tsv`
- **F-CAL-12 (Zeile 1572):** `user_calendar_visibility` Tabellenname
- **F-CAL-15 (Zeile 1614):** `assigned_to: user_id` Feldname
**Problem:** Feldnamen, -typen und Tabellennamen sind Implementierungsdetails, die in das DB-Schema der Architektur gehören.
#### Technologie-Entscheidungen (Architektur, nicht Requirement)
- **F-CORE-07 (Zeile 907):** „Celery + Redis oder RQ + Redis" — Technologie-Wahl
- **F-CORE-08 (Zeile 914):** „Redis als Cache-Backend" — Technologie-Wahl
- **F-CORE-10 (Zeile 928):** „S3-kompatibles Storage (z.B. MinIO)" — Technologie-Wahl
- **F-MAIL-02 (Zeile 1693):** „DOMPurify" — Library-Wahl
- **F-MAIL-12 (Zeile 1846):** „python-gnupg" — Library-Wahl
- **F-UI-02 (Zeile 517):** „react-i18next" — Library-Wahl
- **F-DMS-04 (Zeile 1034):** „PDF.js" — Library-Wahl
- **F-DATA-03 (Zeile 459):** „Pydantic-Schemas" — Library-Wahl
- **F-INFRA-03 (Zeile 666):** „Python logging mit JSON-Formatter" — Library-Wahl
#### Protokoll-Details (Architektur, nicht Requirement)
- **F-MAIL-01 (Zeile 1670):** „IMAP4rev1 (RFC 3501)", „IMAP IDLE (RFC 2177)"
- **F-MAIL-02 (Zeile 1693):** „multipart/mixed", „SMTP-Versand"
- **F-MAIL-05 (Zeile 1733):** „References- und In-Reply-To-Header (RFC 5322)"
- **F-MAIL-18 (Zeile 1929):** „AES-256, Key via Env-Var"
- **F-CAL-08 (Zeile 1516):** „RRULE (RFC 5545)"
- **F-CAL-09 (Zeile 1530):** „RFC 5545 konform"
- **F-MAIL-18 (Zeile 1929):** „IMAP MOVE (RFC 6851)"
#### Frontend-Komponenten-Namen (Architektur, nicht Requirement)
- **F-CAL-01 (Zeile 1405):** `CalendarView` Komponente
- **F-CAL-02 (Zeile 1419):** `KanbanCalendar` Komponente
- **F-FILEUI-01 (Zeile 1321):** `FileBrowser`, `SidebarTree`, `MainView` Komponenten
- **F-FILEUI-02 (Zeile 1335):** `Breadcrumb` Komponente
- **F-FILEUI-03 (Zeile 1349):** `ContextMenu` Komponente
- **F-FILEUI-04 (Zeile 1363):** Multi-Select-State in `FileBrowser`
- **F-MAIL-05 (Zeile 1741):** `ThreadView` Komponente
#### Farbcodes und UI-Implementierung (Architektur, nicht Requirement)
- **F-CAL-06 (Zeile 1485):** `{appointment+normal: "#3B82F6", task+normal: "#F59E0B", *+follow_up: "#F97316", *+private: "#9CA3AF"}` — konkrete Hex-Codes
- **F-COMP-04 (Zeile 235):** `deleted_at = NOW` — SQL-Ausdruck
- **F-FILEUI-02 (Zeile 1335):** „Materialized Path oder rekursive Abfrage" — DB-Pattern
- **F-FILEUI-06 (Zeile 1391):** „HTML5 Drag & Drop API" — Browser-API
- **F-FILEUI-05 (Zeile 1377):** „XMLHttpRequest (für Progress-Events) oder WebSocket" — Technologie
#### Algorithmus- und Logik-Details (Architektur, nicht Requirement)
- **F-MAIL-07 (Zeilen 1762-1771):** Regelauswertungs-Reihenfolge, Background-Worker-Trigger
- **F-MAIL-08 (Zeile 1786):** `vacation_sent_log`, No-Reply-Erkennung: „noreply", „no-reply", „donotreply"
- **F-CAL-08 (Zeile 1516):** Recurrence-Instanz-Generierung, Exception-Handling
- **F-CAL-15 (Zeile 1614):** Notification-Versand bei Zuweisung
### 2.2 Schätzung des Anteils
| Kategorie | Zeilen (geschätzt) | Anteil |
|-----------|--------------------|--------|
| **Genuine Requirements (das WAS)** | ~700-750 | ~35% |
| — Projektbeschreibung, Domain Knowledge | ~25 | |
| — Feature-Anforderung-Texte („User kann...") | ~250 | |
| — Test-Szenarien (Verhalten, nicht Implementation) | ~300 | |
| — Non-funktionale Anforderungen | ~20 | |
| — Annahmen, Non-Goals, Checkliste, Open Questions | ~155 | |
| **Architektur/Implementierung (das HOW)** | ~1380-1430 | ~65% |
| — HTTP-Endpunkte in Akzeptanzkriterien | ~400 | |
| — DB-Schema-Definitionen (Feld-Tabellen, Typen) | ~150 | |
| — F-CORE-01 bis F-CORE-13 (Architekturentscheidungen) | ~100 | |
| — F-PLUGIN-01/02 (Plugin-System-Architektur) | ~20 | |
| — F-WF-01 (Workflow-Engine-Architektur) | ~10 | |
| — Protokoll-Details (RFCs, IMAP, SMTP) | ~80 | |
| — Technologie-/Library-Wahlen | ~60 | |
| — Frontend-Komponenten-Namen | ~40 | |
| — Farbcodes, SQL-Ausdrücke, Algorithmus-Details | ~50 | |
| — Redundanzen (F-FILE vs F-DMS, F-SCHED vs F-CORE-07) | ~100 | |
| — Historische/archivierte Requirements (Appendix A) | ~40 | |
| — Formatierung, Leerzeilen, Trennlinien | ~370 | |
**Fazit:** Die Datei ist zu ~35% eine Requirements-Spec und zu ~65% eine Architektur-/Implementierungs-Dokumentation. Sie hat den Charakter einer Bauanleitung angenommen, nicht den einer Anforderungsspezifikation.
---
## Section 3: Empfehlung
### 3.1 Was in requirements.md bleiben sollte
**Genuine Requirements — das WAS:**
1. **Projektbeschreibung** (Zeilen 10-14) — Was ist das Projekt?
2. **Domain Knowledge** (Zeilen 17-31) — Fachliche Begriffe und Referenzen
3. **Tech-Stack-Entscheidungen** (Zeilen 34-52) — Hohe-Level-Entscheidungen (Backend, DB, Frontend, Deployment)
4. **Feature-Anforderungstexte** — Die „Anforderung:"-Absätze jedes Features, bereinigt um Implementierungsdetails:
- F-AUTH-01 bis F-AUTH-08: Was muss die Auth können?
- F-COMP-01 bis F-COMP-08: Was muss Firmen-Management können?
- F-CONT-01 bis F-CONT-07: Was muss Kontakt-Management können?
- F-DATA-01 bis F-DATA-06: Was muss Daten-Management können?
- F-UI-01 bis F-UI-08: Was muss die UI bieten?
- F-SEC-01 bis F-SEC-03: Welche Sicherheitsanforderungen?
- F-INFRA-01 bis F-INFRA-04: Welche Infrastrukturanforderungen?
- F-MIG-01: Was muss Migration/Import können?
- F-INT-01: Welche Integrationsanforderung?
- F-TEST-01: Welche Test-Strategie?
- F-ENV-01: Welche Environment-Anforderung?
- F-DOC-01: Welche Doku-Anforderung?
- F-PERF-01: Welche Performance-Anforderung?
- F-SEARCH-01: Was muss die globale Suche können?
- F-NAV-01: Welche Navigation?
- F-SET-01: Welche Einstellungen?
- F-DMS-01 bis F-DMS-07: Was muss DMS können? (ohne Endpunkte)
- F-LINK-01 bis F-LINK-06: Was muss Verknüpfung können? (ohne Endpunkte)
- F-TAG-01 bis F-TAG-04: Was muss Tagging können? (ohne Endpunkte)
- F-PERM-01 bis F-PERM-06: Welche Berechtigungs-Requirements? (ohne Endpunkte)
- F-FILEUI-01 bis F-FILEUI-06: Welche UI-Requirements für Datei-Browser? (ohne Komponentennamen)
- F-CAL-01 bis F-CAL-18: Was muss Kalender können? (ohne Endpunkte, ohne Farbcodes)
- F-MAIL-01 bis F-MAIL-19: Was muss Mail können? (ohne Protokoll-Details)
- F-AI-01: Was muss der KI-Copilot können?
- F-SCHED-01: Welche Background-Job-Anforderung?
5. **Test-Szenarien** — Aber bereinigt: nur Verhalten beschreiben („User klickt X → Y passiert"), keine Implementierung („`deleted_at = NOW` gesetzt", „`tsvector`-Index")
6. **Non-funktionale Anforderungen** (Zeilen 1957-1973) — Bleiben, aber Metriken ohne Library-Namen
7. **Annahmen** (Zeilen 1976-1999) — Bleiben
8. **Non-Goals** (Zeilen 2001-2046) — Bleiben
9. **Discovery-Checkliste** (Zeilen 2049-2073) — Bleibt
10. **Open Questions** (Zeilen 2077-2085) — Bleibt
### 3.2 Was nach architecture.md verschoben werden sollte
**Architektur/Implementierung — das HOW:**
1. **F-CORE-01 bis F-CORE-13 (Zeilen 864-953):** Komplett in architecture.md
- Event Bus, Tenant-Isolation (`tenant_id`), Plugin-Migration, UI-Plugin-Framework, Service Container/DI, API-First (Endpunkt-Versionierung `/api/v1/`), Async Job Queue (Celery/Redis), Caching (Redis), Storage-Backend (S3/MinIO), Import/Export Service, PDF-Gen, Notification Service
2. **F-PLUGIN-01, F-PLUGIN-02 (Zeilen 848-860):** Plugin-System-Architektur → architecture.md
- Plugin-Schnittstelle, Manifest-Format, Lifecycle-Hooks, Abhängigkeiten
3. **F-WF-01 (Zeile 812-815):** Workflow-Engine-Architektur → architecture.md
- Hybrid-Ansatz, Code-Engine vs. konfigurierbare Regeln
4. **Alle HTTP-Endpunkt-Spezifikationen:** → architecture.md (API-Contract-Sektion)
- `POST /api/auth/login`, `GET /api/companies/{id}`, etc.
- Request/Response-Body-Formate
- Query-Parameter-Spezifikationen
- HTTP-Status-Codes
5. **Alle DB-Schema-Definitionen:** → architecture.md (DB-Schema-Sektion)
- Feld-Tabellen mit Typen (F-COMP-01 Zeilen 156-186, F-CONT-01 Zeilen 300-333)
- Tabellennamen (`audit_log`, `deletion_log`, `company_contacts`, `user_calendar_visibility`)
- `tenant_id`-Feld-Spezifikation
- `tsvector`-Index-Spezifikation
6. **Protokoll-Details:** → architecture.md
- IMAP4rev1, IMAP IDLE, IMAP MOVE, SMTP-Auth
- RFC 5545 (RRULE), RFC 5322 (Threading)
- PGP-Verschlüsselung (python-gnupg)
- DOMPurify-Sanitization
- AES-256-Verschlüsselung für Passwörter
7. **Frontend-Komponenten-Architektur:** → architecture.md (Frontend-Architektur-Sektion)
- Komponenten-Namen (`CalendarView`, `KanbanCalendar`, `FileBrowser`, `Breadcrumb`, `ContextMenu`, `ThreadView`)
- State-Management (`Multi-Select-State`, `user_calendar_visibility`)
- HTML5 Drag & Drop API, XMLHttpRequest
- Materialized Path Pattern
8. **Farbcodes und UI-Mappings:** → architecture.md oder design-system.md
- Hex-Codes für Kalender-Typen
- Farb-Mapping-Logik
9. **Algorithmus-Details:** → architecture.md
- Mail-Regel-Auswertung
- Auto-Reply-Logik (No-Reply-Erkennung, `vacation_sent_log`)
- Recurrence-Instanz-Generierung
- Thread-Gruppierung
10. **F-FILE-01 bis F-FILE-04 (Zeilen 955-985):** Duplikate von F-DMS/F-PERM — entfernen oder konsolidieren
11. **F-SCHED-01 (Zeile 784-792):** Duplikat von F-CORE-07 — konsolidieren
12. **Appendix A: Historische Anforderungen (Zeilen 2089-2128):** In separates `changelog.md` oder entfernen
### 3.3 Wie die Widersprüche (Plugin vs. Core-Feature) aufgelöst werden können
**Option A: Module sind Core-Features (empfohlen für v1/v2)**
- Entferne F-PLUGIN-01, F-PLUGIN-02, F-CORE-01 bis F-CORE-13 aus requirements.md
- Module (Mail, Kalender, DMS, Tags) sind Core-Features mit Requirements
- Plugin-System ist ein Non-Goal für v1/v2 („Plugin-System für spätere Versionen")
- Vorteil: Konsistent, weniger Komplexität, schneller implementierbar
- Nachteil: Weniger Erweiterbarkeit
**Option B: Module sind Plugins**
- Core-Requirements definieren nur Plugin-Schnittstelle und Core-Infrastruktur
- Plugin-Requirements (Mail, Kalender, DMS) werden in separate Plugin-Specs ausgelagert
- Core-Requirements sagen: „Das System unterstützt Plugins. Plugin 'Mail' muss X können. Plugin 'Kalender' muss Y können."
- Die detaillierten Feature-Spezifikationen (F-MAIL-*, F-CAL-*, F-DMS-*) wandern in Plugin-Requirements
- Vorteil: Saubere Trennung, Erweiterbarkeit
- Nachteil: Mehr Dokumentation, mehr Komplexität, Over-Engineering für ein Mini-CRM
**Empfehlung: Option A für v1/v2.**
Ein Mini-CRM mit 10 concurrent Users braucht kein Plugin-System. Das Plugin-System ist ein Architektur-Non-Goal für v1/v2. Die Module werden als Core-Features implementiert. Wenn Erweiterbarkeit später benötigt wird, kann ein Plugin-System in v3+ hinzugefügt werden. F-PLUGIN-01, F-PLUGIN-02, F-CORE-01 bis F-CORE-13 werden zu Non-Goals.
---
## Section 4: Spezifische Konflikte (Tabelle)
| ID/Zeile | Issue | Severity | Vorschlag |
|----------|-------|----------|-----------|
| F-PLUGIN-01 (848) vs F-DMS/F-CAL/F-MAIL | Module als Plugins deklariert, aber als Core-Features mit Endpunkten/DB-Schemas spezifiziert | **critical** | Plugin-System als Non-Goal für v1/v2; Module als Core-Features deklarieren |
| F-FILE-01-04 (955-985) vs F-DMS-01-07 (991-1083) | F-FILE und F-DMS beschreiben dasselbe Modul mit unterschiedlichen IDs. F-FILE-01 (Datei-Explorer) = F-DMS-01 (Ordner-Struktur), F-FILE-03 (PDF-Preview) = F-DMS-04, F-FILE-04 (OnlyOffice) = F-DMS-05 | **critical** | F-FILE-01 bis F-FILE-04 entfernen; durch F-DMS-Referenzen ersetzen |
| F-FILE-03 (973) vs F-DMS-04 (1033) | Beide spezifizieren PDF-Preview im Browser — Duplikat | **critical** | F-FILE-03 entfernen; F-DMS-04 behalten (detaillierter) |
| F-FILE-04 (982) vs F-DMS-05 (1047) | Beide spezifizieren OnlyOffice-Integration — Duplikat | **critical** | F-FILE-04 entfernen; F-DMS-05 behalten (detaillierter) |
| F-FILE-02 (964) vs F-PERM-03/04 (1257-1279) | F-FILE-02 (Datei-Sharing) ist vereinfachte Version von F-PERM-03/04 — Redundanz | **warning** | F-FILE-02 entfernen; F-PERM-03/04 als maßgeblich deklarieren |
| F-SCHED-01 (784) vs F-CORE-07 (906) | Beide beschreiben Background-Jobs/Async-Queue — F-SCHED-01 ist vereinfachte Version von F-CORE-07 | **warning** | F-SCHED-01 entfernen; F-CORE-07 in architecture.md verschieben; Requirement „lange Operationen als Background-Job" in requirements.md behalten |
| F-DATA-01/02 (430-452) vs F-CORE-11 (934) | CSV/Excel-Export (F-DATA) überlappt mit Generic Import/Export Service (F-CORE-11) | **warning** | F-CORE-11 in architecture.md; F-DATA-01/02 in requirements.md behalten (das WAS); F-CORE-11 beschreibt das HOW |
| F-AUTH-07 (135) vs F-AUTH-01-F-CONT-07 (57-410) | Multi-Tenant deklariert, aber frühe Requirements erwähnen Tenant-Kontext nicht | **warning** | Frühe Requirements um Tenant-Bezug ergänzen: „Firma wird dem aktiven Tenant zugeordnet", „Suche ist Tenant-gefiltert" |
| F-AUTH-01 (58) vs F-AUTH-02 (72-78) | F-AUTH-01: „Session-basiert", F-AUTH-02: „Token wird entfernt", „Server-Token-Blacklist" — inkonsistente Terminologie | **warning** | Einheitlich „Session" verwenden; Token-Blacklist entfernen oder klar als Session-Invalidierung benennen |
| F-SEC-03 (616) vs F-AUTH-01 (58) | F-SEC-03 spricht von „Token" („Token gültig <8h", „Token nach 8h → 401"), F-AUTH-01 von „Session-Cookie" | **warning** | Einheitlich Session-basiert formulieren; „Session läuft nach 8h ab" |
| F-CORE-06 (899) vs F-UI-01-06 (495-573) | API-First („alle Features über API") vs. reinen UI-Features ohne API-Bezug (Toast, Loading-States, Empty-States) | **warning** | F-CORE-06 einschränken: „Alle Daten- und Funktions-Features über API nutzbar; reine UI-Präsentations-Features (Loading-States, Toasts) ausgenommen" |
| F-AUTH-06 (126) vs F-AUTH-04 (98) | F-AUTH-06 (Multi-User mit Rollen) überlappt mit F-AUTH-04 (RBAC) — F-AUTH-06 ist detailliertere Version | **warning** | Zusammenführen oder F-AUTH-06 als Erweiterung von F-AUTH-04 kennzeichnen |
| F-AUTH-08 (144) vs F-AUTH-04/06 (98-129) | F-AUTH-08 (Feld-Ebene-Granularität) erweitert F-AUTH-04/06, wird aber nicht kreuzreferenziert | **warning** | F-AUTH-08 als Unterpunkt von F-AUTH-04/06 integrieren oder explizit referenzieren |
| F-SEARCH-01 (821) vs F-COMP-06 (255)/F-CONT-06 (402) | Globale Suche überlappt mit Firmen-/Kontakt-Suche — keine klare Abgrenzung | **warning** | F-SEARCH-01 als übergeordnete Suche deklarieren; F-COMP-06/F-CONT-06 als Modul-Suche mit Querverweis |
| F-INT-01 (700) vs F-MAIL-02 (1683) | E-Mail-Integration für Passwort-Reset (F-INT-01) ist Subset des vollen Mail-Moduls (F-MAIL-02) | **info** | F-INT-01 als v1-Requirement behalten; F-MAIL-02 als v2-Erweiterung kennzeichnen; F-INT-01 bei F-MAIL-02 referenzieren |
| F-CAL-10 (1536) vs Non-Goals (2028) | F-CAL-10 (Ressourcen-Booking) als „Optional für später (post-v2)" markiert, hat aber volle Test-Szenarien und Akzeptanzkriterien | **warning** | Entweder zu Non-Goals verschieben oder als v2-Feature belassen mit klarer Markierung „post-v2" |
| F-COMP-01 Feldtabelle (156-186) | DB-Schema mit Typen (String(100), Integer, Decimal) in Requirements | **info** | Feldliste als „Felder, die erfasst werden" in requirements.md; Typen und Constraints in architecture.md |
| F-CONT-01 Feldtabelle (300-333) | DB-Schema mit Typen in Requirements | **info** | Analog zu F-COMP-01 |
| F-COMP-04 (235) | `deleted_at = NOW` (SQL-Ausdruck) in Akzeptanzkriterium | **info** | „Firma wird als gelöscht markiert (Soft-Delete)" — ohne SQL |
| F-CONT-07 (424) | `company_contacts` Tabellenname in Akzeptanzkriterium | **info** | „N:M-Verknüpfung wird erstellt" — ohne Tabellennamen |
| F-CAL-06 (1485) | Hex-Farbcodes in Akzeptanzkriterium | **info** | „Farbe wird basierend auf Typ zugeordnet" — Farbwerte in design-system.md |
| F-CAL-08 (1516) | RRULE (RFC 5545) in Akzeptanzkriterium | **info** | „Wiederholungsmuster werden unterstützt" — RFC-Referenz in architecture.md |
| F-MAIL-03 (1709) | `tsvector`-Index in Akzeptanzkriterium | **info** | „Volltext-Suche über alle Mails" — Index-Strategie in architecture.md |
| F-MAIL-01 (1677) | „IMAP IDLE-Listener läuft als Background-Task" in Akzeptanzkriterium | **info** | „Neue Mails werden innerhalb von 5 Sekunden angezeigt" — Implementierung in architecture.md |
| F-MAIL-02 (1693) | „DOMPurify" in Akzeptanzkriterium | **info** | „HTML wird sanitisiert" — Library in architecture.md |
| F-MAIL-12 (1846) | „python-gnupg" in Akzeptanzkriterium | **info** | „PGP-Verschlüsselung wird unterstützt" — Library in architecture.md |
| F-FILEUI-01 (1321) | `FileBrowser`, `SidebarTree`, `MainView` Komponentennamen | **info** | „Datei-Browser mit Baum-Ansicht und Hauptbereich" — Komponentennamen in architecture.md |
| F-FILEUI-02 (1335) | „Materialized Path oder rekursive Abfrage" in Akzeptanzkriterium | **info** | „Pfad wird aus Ordner-Hierarchie generiert" — Pattern in architecture.md |
| F-FILEUI-06 (1391) | „HTML5 Drag & Drop API" in Akzeptanzkriterium | **info** | „Drag & Drop wird unterstützt" — API in architecture.md |
| F-FILEUI-05 (1377) | „XMLHttpRequest oder WebSocket" in Akzeptanzkriterium | **info** | „Upload-Progress wird angezeigt" — Technologie in architecture.md |
| F-CORE-07 (907) | „Celery + Redis oder RQ + Redis" — Technologie-Wahl in Requirements | **info** | Komplett in architecture.md |
| F-CORE-08 (914) | „Redis als Cache-Backend" — Technologie-Wahl in Requirements | **info** | Komplett in architecture.md |
| F-CORE-10 (928) | „S3-kompatibles Storage (z.B. MinIO)" — Technologie-Wahl in Requirements | **info** | Komplett in architecture.md |
| F-CORE-02 (872) | `tenant_id`-Feld-Spezifikation in Requirements | **info** | „Daten sind pro Tenant isoliert" — `tenant_id` in architecture.md |
| DISCOVERY_CHECK (2131) | Behauptet `features_with_ids=127/127` — tatsächlich sind es ~141 aktive Feature-IDs | **warning** | Zählung korrigieren oder klären, welche Features gezählt wurden |
| F-DATA-05 fehlt | Springt von F-DATA-04 (Zeile 472) zu F-DATA-06 (Zeile 481) — F-DATA-05 existiert nicht | **info** | Entweder F-DATA-05 nachtragen oder Nummerierung korrigieren |
| F-UI-07 fehlt | Springt von F-UI-06 (Zeile 565) zu F-UI-08 (Zeile 579) — F-UI-07 existiert nicht | **info** | Entweder F-UI-07 nachtragen oder Nummerierung korrigieren |
| F-COMP-07 (269) vs F-COMP-08 (283) | Audit-Log und DSGVO-Löschung haben überlappende Belange (beide behandeln Logging von Löschungen), Interaktion nicht dokumentiert | **info** | Klarstellen: Audit-Log = schreibende Aktionen; DSGVO-Löschung = harte Löschung inkl. Audit-Log-Einträgen, separate `deletion_log` |
| NF-06 (1966) | Code-Struktur (`api/`, `models/`, `schemas/`, `services/`, `tests/`) in nicht-funktionaler Anforderung | **info** | In architecture.md verschieben; in requirements.md: „Code-Struktur ist klar getrennt" |
| Appendix A (2089-2128) | Historische v0.1-Requirements mit veralteten Tech-Stack (Jinja2, SQLite, Python 3.11) | **info** | In `changelog.md` verschieben oder entfernen; verwirrend in requirements.md |
---
## Zusammenfassung
| Metrik | Wert |
|--------|------|
| Gesamtzeilen | 2131 |
| Aktive Feature-IDs | ~141 |
| Genuine Requirements-Anteil | ~35% |
| Architektur/Implementierungs-Anteil | ~65% |
| Critical Issues | 4 |
| Warning Issues | 14 |
| Info Issues | 21 |
| Empfehlung | Requirements bereinigen, ~65% nach architecture.md verschieben, Plugin-System als Non-Goal für v1/v2 |
**Urteil:** Die Datei ist eine Mischung aus Requirements-Spec und Architektur-Dokument. Sie hat den Charakter einer Bauanleitung angenommen. Für eine saubere Trennung sollten ~65% des Inhalts in architecture.md verschoben werden. Die verbleibende requirements.md sollte nur das WAS beschreiben — nicht das HOW.