mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-24 22:36:38 +02:00
docs: update INSIGHT-CRM.md with architect requirements from Konzept v1.0
Extract and categorize new requirements from updated CLAUDE_BRIEFING.docx and INSIGHT_Konzept_v1.0.docx. Add comprehensive CRM task breakdown (Kap 22: full CRM spec, Kap 24: Office 365 integration) with prioritized action items for the CRM backend developer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a85634a906
commit
69f032a3d8
3 changed files with 467 additions and 0 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -1052,4 +1052,471 @@ Wenn ein User mit Rolle `PLATFORM_ADMIN` keiner Tenant-Membership zugeordnet war
|
|||
|
||||
---
|
||||
|
||||
## 2026-03-12 | Architekt: Neue Anforderungen aus Konzeptdokument v1.0 + Briefing
|
||||
|
||||
Der Architekt hat das Konzeptdokument (INSIGHT_Konzept_v1.0.docx) und das Claude Briefing (CLAUDE_BRIEFING.docx) aktualisiert. Folgende Kapitel sind neu oder erweitert und betreffen den CRM-Service direkt:
|
||||
|
||||
- **Kapitel 22** — CRM-Modul (vorher nur Platzhalter, jetzt vollstaendig spezifiziert)
|
||||
- **Kapitel 24** — Office 365 Integration (neu, CRM-relevante Teile)
|
||||
- **Kapitel 14 im Briefing** — Office 365 Kurzreferenz (neu)
|
||||
|
||||
### Hinweis: CORE vs CRM
|
||||
|
||||
Folgende Teile sind **CORE-Aufgaben** (NICHT fuer den CRM-Entwickler):
|
||||
- Kap 24.1: OAuth-Flow + `user_integrations` Tabelle in `platform_core`
|
||||
- Kap 24.8: Azure App-Registrierung im Azure Portal
|
||||
- `.env`-Variablen: `MS_CLIENT_ID`, `MS_CLIENT_SECRET`, `MS_REDIRECT_URI`, `MS_INTEGRATION_ENCRYPTION_KEY`
|
||||
|
||||
Alles Folgende ist **CRM-Arbeit**.
|
||||
|
||||
---
|
||||
|
||||
### A) CRM-Modul Spezifikation (Kap 22) — Neue/Erweiterte Anforderungen
|
||||
|
||||
#### A.1 Kontakttypen & Felder (Kap 22.1)
|
||||
|
||||
Die vollstaendige Felddefinition fuer Person und Unternehmen liegt jetzt vor:
|
||||
|
||||
**Kontakttyp: Person**
|
||||
|
||||
| Feld | Typ | Pflicht | Bemerkung |
|
||||
|------|-----|---------|-----------|
|
||||
| Vorname | String | Ja | |
|
||||
| Nachname | String | Ja | |
|
||||
| Jobtitel | String | Nein | |
|
||||
| Unternehmen | Relation -> Unternehmen | Nein | |
|
||||
| Abteilung | String | Nein | |
|
||||
| E-Mail | Array (String) | Nein | Mehrere, Typ: Arbeit / Privat / Sonstige |
|
||||
| Telefon | Array (String) | Nein | Mehrere, Typ: Buero / Mobil / Fax |
|
||||
| Adresse | Objekt | Nein | Strasse, PLZ, Stadt, Land |
|
||||
| LinkedIn-URL | String (URL) | Nein | |
|
||||
| Geburtsdatum | Date | Nein | Optional, kann ausgeblendet werden |
|
||||
| Quelle | Enum | Nein | Messe, Empfehlung, Website, Kaltakquise, Import, Visitenkarte, Sonstige |
|
||||
| Tags | Array (String) | Nein | Frei vergebbar, tenant-weit geteilt |
|
||||
| Status | Enum | Ja | Aktiv / Inaktiv / Gesperrt (Default: Aktiv) |
|
||||
| Notizen | Text (Markdown) | Nein | |
|
||||
| Benutzerdefinierte Felder | Dynamisch | Nein | Siehe A.6 |
|
||||
|
||||
**Kontakttyp: Unternehmen**
|
||||
|
||||
| Feld | Typ | Pflicht | Bemerkung |
|
||||
|------|-----|---------|-----------|
|
||||
| Firmenname | String | Ja | |
|
||||
| Branche | String | Nein | Freitext oder vordefinierte Kategorien |
|
||||
| Website | String (URL) | Nein | |
|
||||
| Telefon | Array (String) | Nein | Mehrere Nummern |
|
||||
| Adresse Hauptsitz | Objekt | Nein | Strasse, PLZ, Stadt, Land |
|
||||
| Adresse Lieferung | Objekt | Nein | Optional abweichende Lieferadresse |
|
||||
| USt-IdNr. | String | Nein | |
|
||||
| Steuernummer | String | Nein | |
|
||||
| Handelsregisternummer | String | Nein | z.B. HRB 12345 — befuellbar via Datenanreicherung |
|
||||
| Registergericht | String | Nein | z.B. Amtsgericht Muenchen — befuellbar via Datenanreicherung |
|
||||
| Unternehmensgroesse | Enum | Nein | 1-10, 11-50, 51-200, 201-500, 500+ |
|
||||
| Ansprechpartner | Relation -> Personen | Nein | Verknuepfte Personen |
|
||||
| Tags | Array (String) | Nein | |
|
||||
| Status | Enum | Ja | Aktiv / Inaktiv / Gesperrt |
|
||||
| Notizen | Text (Markdown) | Nein | |
|
||||
| Datenanreicherung | Automatisch | Nein | data_enriched_at + data_enriched_source |
|
||||
| Benutzerdefinierte Felder | Dynamisch | Nein | Siehe A.6 |
|
||||
|
||||
**Backend-Aufgabe**: Abgleich mit bestehenden Prisma-Modellen. Fehlende Felder (LinkedIn, Geburtsdatum, Quelle, Unternehmensgroesse, USt-IdNr, Steuernummer, Handelsregisternummer, Registergericht, Adresse Lieferung, data_enriched_at/source) muessen ergaenzt werden.
|
||||
|
||||
#### A.2 Firmendaten-Anreicherung / Data Enrichment (Kap 22.2) — NEU
|
||||
|
||||
"Firmendaten laden"-Button im Unternehmenformular. Stammdaten aus externen Registern abrufen und als Vorschlag in einem Modal anzeigen.
|
||||
|
||||
**Quellen:**
|
||||
1. **Unternehmensregister.de** (kostenlos, oeffentlich) — HR-Nummer, Registergericht, Rechtsform, Sitz, Eintragsdatum
|
||||
2. **North Data API** (kommerziell, API-Key pro Tenant) — Adresse, Branche, Umsatz, Mitarbeiterzahl, Gesellschafter, Verflechtungen
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] `POST /crm/companies/:id/enrich` oder `POST /crm/data-enrichment/company` Endpoint
|
||||
- [ ] Paralleler Abruf: Unternehmensregister.de + North Data API (Timeout je 10 Sek.)
|
||||
- [ ] Ergebnisse normalisieren und zusammenfuehren
|
||||
- [ ] `data_enriched_at` + `data_enriched_source` in Company speichern
|
||||
- [ ] Admin-Einstellung: North Data API-Key pro Tenant (Admin > CRM > Integrationen)
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] "Firmendaten laden" Button im Unternehmenformular
|
||||
- [ ] Anreicherungs-Modal: Linke Spalte = aktueller Wert, Rechte Spalte = Vorschlag (Quelle), Checkbox pro Feld
|
||||
- [ ] "Auswahl uebernehmen" -> Felder im Formular setzen (Speichern erst bei explizitem Speichern)
|
||||
- [ ] CRM-Settings-Seite: North Data API-Key Konfiguration
|
||||
|
||||
#### A.3 Zustaendigkeit / Account Owner (Kap 22.3) — NEU
|
||||
|
||||
Jeder Kontakt/Unternehmen kann mit mehreren internen Mitarbeitern verknuepft werden (m:n).
|
||||
|
||||
| Aspekt | Entscheidung |
|
||||
|--------|-------------|
|
||||
| Modell | m:n — ein Kontakt hat mehrere Owner, ein Mitarbeiter hat mehrere Kontakte |
|
||||
| Rollen pro Zuweisung | `OWNER`, `MEMBER`, `WATCHER` (unterschiedliche Bearbeitungsrechte) |
|
||||
| Mitarbeiter-Referenz | `user_id` aus `platform_core` (kein Kopieren von User-Daten) |
|
||||
| Anzeige | Avatare der zugewiesenen Mitarbeiter in der Kontaktkarte |
|
||||
| Pflicht-Owner | Mindestens 1 Owner pro Kontakt bei Erstellung (Default: erstellender User) |
|
||||
|
||||
**DB-Tabelle:** `crm_contact_owners (contact_id, user_id, role: OWNER|MEMBER|WATCHER)`
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] Contact-Owner CRUD: `POST/DELETE /crm/contacts/:id/owners`
|
||||
- [ ] Bei Kontakt-Erstellung automatisch erstellenden User als OWNER setzen
|
||||
- [ ] Owner-Info in Contact-Detail-Response mitliefern
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] Avatare der Owner in der Kontaktkarte anzeigen
|
||||
- [ ] Owner-Zuweisung UI (User suchen + Rolle waehlen)
|
||||
|
||||
#### A.4 Pipeline & Deal-Management — Erweiterte Spec (Kap 22.4)
|
||||
|
||||
Ergaenzungen zur bestehenden Implementierung:
|
||||
|
||||
- **Forecast-Ansicht**: Aggregierter Dealwert pro Stage gewichtet mit Wahrscheinlichkeit
|
||||
- **Lost-Grund**: Enum + Freitext bei Status Lost: Preis, Timing, Wettbewerber, Kein Bedarf, Sonstige
|
||||
- **Pipeline-Sichtbarkeit**: Enum — Alle Tenant-User / Nur zugewiesene Teams
|
||||
- **Deal-Owner**: m:n analog zu Kontakt-Owner (crm_deal_owners)
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] `lost_reason` Enum + `lost_reason_text` Freitext in Deals
|
||||
- [ ] Deal-Owner CRUD (analog Contact-Owner)
|
||||
- [ ] Forecast-Endpoint: `GET /crm/deals/forecast` (Wert x Wahrscheinlichkeit pro Stage)
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] Lost-Grund Modal bei Stage-Wechsel zu "Lost"
|
||||
- [ ] Kanban-Board (Drag & Drop)
|
||||
- [ ] Forecast-Ansicht
|
||||
|
||||
#### A.5 Aktivitaeten & Aufgaben (Kap 22.5) — Erweiterte Spec
|
||||
|
||||
6 Aktivitaetstypen sind definiert:
|
||||
|
||||
| Typ | Icon | Bemerkung |
|
||||
|-----|------|-----------|
|
||||
| Anruf (Call) | Telefon | Kann Gespraechsnotizen enthalten |
|
||||
| Meeting | Kalender | Datum, Uhrzeit, Ort / Videolink |
|
||||
| E-Mail | Brief | Freitext-Notiz, KEINE echte E-Mail-Integration in MVP |
|
||||
| Aufgabe (Task) | Checkbox | Faelligkeitsdatum, Zuweisung an Mitarbeiter |
|
||||
| Notiz | Stift | Freitext ohne Faelligkeitsdatum |
|
||||
| Follow-Up | Pfeil | Erinnerung zu einem definierten Zeitpunkt |
|
||||
|
||||
**Hinweis**: E-Mail-Integration (Outlook) kommt erst mit Office 365 (Kap 24).
|
||||
|
||||
#### A.6 Benutzerdefinierte Felder / Custom Fields (Kap 22.6) — NEU
|
||||
|
||||
Pro Kontakttyp (Person, Unternehmen) und pro Deal koennen eigene Felder definiert werden.
|
||||
|
||||
**Unterstuetzte Feldtypen:**
|
||||
|
||||
| Typ | Beschreibung | Beispiel |
|
||||
|-----|-------------|---------|
|
||||
| Text | Einzeiliger Freitext | Kundennummer |
|
||||
| Textarea | Mehrzeiliger Freitext | Besondere Hinweise |
|
||||
| Zahl | Integer oder Decimal | Umsatz, Vertragslaufzeit |
|
||||
| Datum | Datumspicker | Vertragsbeginn |
|
||||
| Auswahl (Dropdown) | Vordefinierte Werte | Kundensegment: A / B / C |
|
||||
| Mehrfachauswahl | Mehrere Werte waehlbar | Interessensgebiete |
|
||||
| Checkbox | Boolean Ja/Nein | DSGVO-Einwilligung |
|
||||
| URL | Validierter Link | Portal-Link |
|
||||
|
||||
**DB-Tabellen:**
|
||||
```sql
|
||||
crm_custom_field_defs (id, entity_type: PERSON|COMPANY|DEAL, name, label, field_type,
|
||||
options jsonb, is_required, position)
|
||||
crm_custom_field_values (id, field_def_id, entity_id, value_text, value_number,
|
||||
value_date, value_boolean, value_json)
|
||||
```
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] CRUD fuer Field-Definitions: `GET/POST/PATCH/DELETE /crm/custom-fields`
|
||||
- [ ] Wert-Speicherung bei Entity-Create/Update
|
||||
- [ ] Custom Fields in Entity-Detail-Response mitliefern
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] Admin-Bereich: Custom Fields Verwaltung (Drag & Drop Reihenfolge, Pflichtfeld-Flag)
|
||||
- [ ] Dynamische Formular-Felder in Contact/Deal-Formularen
|
||||
- [ ] Custom Fields als optionale Spalten in Listen-Ansichten
|
||||
- [ ] Custom Fields als Filter in der Suche
|
||||
|
||||
#### A.7 Kontakt-Import (Kap 22.7) — NEU
|
||||
|
||||
**Import via Datei:**
|
||||
- [ ] CSV-Import mit visuellem Spalten-Mapper
|
||||
- [ ] Excel-Import (.xlsx)
|
||||
- [ ] vCard-Import (.vcf, einzeln und ZIP)
|
||||
- [ ] Vorschau der ersten 10 Datensaetze + Validierungsfehler anzeigen
|
||||
- [ ] Duplikat-Erkennung via E-Mail: ueberspringen / zusammenfuehren / als Duplikat markieren
|
||||
|
||||
**Visitenkarten-Scan (Anthropic Vision API):**
|
||||
- [ ] "Visitenkarte scannen" — Kamera-/Datei-Dialog
|
||||
- [ ] Bild base64-kodiert an CRM-Backend senden
|
||||
- [ ] Backend ruft Anthropic Vision API auf (strukturierter Prompt)
|
||||
- [ ] Vorausgefuelltes Kontaktformular zur Bestaetigung
|
||||
- [ ] Rate Limit: max. 50 Scans pro Tenant pro Tag (konfigurierbar)
|
||||
- [ ] Bild wird NICHT dauerhaft gespeichert
|
||||
|
||||
#### A.8 Berechtigungsmodell (Kap 22.8) — NEU
|
||||
|
||||
Ownership-basiertes Sichtbarkeitsmodell:
|
||||
|
||||
| Stufe | Beschreibung | Sieht was? |
|
||||
|-------|-------------|-----------|
|
||||
| Eigene | User sieht nur eigene Datensaetze (Owner) | Eigene Kontakte, Deals, Aktivitaeten |
|
||||
| Team | User sieht alle Datensaetze der eigenen Abteilung | Kontakte aller Kollegen |
|
||||
| Alle | User sieht alle Datensaetze des Tenants | Vollzugriff (lesend) |
|
||||
|
||||
**Berechtigungen nach Rolle:**
|
||||
|
||||
| Rolle | Sichtbarkeit | Erstellen | Bearbeiten | Loeschen |
|
||||
|-------|-------------|-----------|------------|----------|
|
||||
| tenant_admin | Alle | Ja | Alle | Alle |
|
||||
| team_lead | Team | Ja | Team + Eigene | Eigene |
|
||||
| tenant_member | Konfigurierbar | Ja | Eigene + zugewiesene | Eigene |
|
||||
| tenant_readonly | Konfigurierbar | Nein | Nein | Nein |
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] Sichtbarkeitsfilter in allen List-Queries (Contacts, Deals, Activities)
|
||||
- [ ] Tenant-Admin Einstellung: Default-Sichtbarkeit pro Rolle
|
||||
- [ ] Per-User Override moeglich
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] Admin > CRM-Einstellungen > Berechtigungen: Sichtbarkeitsstufe konfigurieren
|
||||
|
||||
#### A.9 Reporting & Dashboards (Kap 22.9) — NEU
|
||||
|
||||
5 Reports/Dashboards sind definiert:
|
||||
|
||||
| Dashboard | Inhalt | Aktualisierung |
|
||||
|-----------|--------|---------------|
|
||||
| Pipeline-Uebersicht | Deals pro Stage, Gesamtvolumen, gewichteter Forecast | Echtzeit |
|
||||
| Aktivitaeten-Uebersicht | Offene Aufgaben, ueberfaellige Aktivitaeten, Volumen/Woche | Echtzeit |
|
||||
| Kontaktwachstum | Neue Kontakte/Monat, aufgeschluesselt nach Quelle | Taeglich |
|
||||
| Win/Loss-Analyse | Won vs Lost Deals, Lost-Gruende als Torte, Durchschnittliche Deal-Dauer | Taeglich |
|
||||
| Mitarbeiter-Performance | Deals pro Mitarbeiter, Aktivitaeten-Anzahl, Response-Zeit | Taeglich |
|
||||
|
||||
- Alle Reports als CSV exportierbar
|
||||
- Datumsbereiche: letzte 7 / 30 / 90 Tage, benutzerdefiniert
|
||||
- Mitarbeiter-Performance nur fuer tenant_admin und team_lead sichtbar
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] Reporting-Endpoints: `GET /crm/reports/pipeline`, `/reports/activities`, `/reports/contacts-growth`, `/reports/win-loss`, `/reports/performance`
|
||||
- [ ] CSV-Export fuer alle Reports
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] CRM Dashboard-Seite mit den 5 Report-Widgets
|
||||
- [ ] Datumbereich-Selektor
|
||||
- [ ] CSV-Export Buttons
|
||||
|
||||
#### A.10 CRM Datenbankschema (Kap 22.10)
|
||||
|
||||
Vollstaendiges Schema laut Architekt:
|
||||
|
||||
```sql
|
||||
-- Kernentitaeten
|
||||
crm_contacts (id, type: PERSON|COMPANY, status, source, created_by, created_at, updated_at)
|
||||
crm_persons (id, contact_id, first_name, last_name, job_title, department, birthday, notes)
|
||||
crm_companies (id, contact_id, name, industry, website, vat_id, tax_id, size_class, notes)
|
||||
crm_contact_emails (id, contact_id, email, type: WORK|PERSONAL|OTHER, is_primary)
|
||||
crm_contact_phones (id, contact_id, phone, type: OFFICE|MOBILE|FAX, is_primary)
|
||||
crm_contact_addresses (id, contact_id, type: MAIN|DELIVERY, street, zip, city, country)
|
||||
|
||||
-- Beziehungen
|
||||
crm_person_company (person_contact_id, company_contact_id)
|
||||
crm_contact_owners (contact_id, user_id, role: OWNER|MEMBER|WATCHER)
|
||||
crm_contact_tags (contact_id, tag)
|
||||
|
||||
-- Pipeline & Deals
|
||||
crm_pipelines (id, name, is_default, visibility)
|
||||
crm_pipeline_stages (id, pipeline_id, name, color, position, probability, is_won_stage, is_lost_stage)
|
||||
crm_deals (id, contact_id, pipeline_id, stage_id, title, value, currency,
|
||||
probability_override, expected_close_date, status: OPEN|WON|LOST,
|
||||
lost_reason, lost_reason_text, notes, created_by)
|
||||
crm_deal_owners (deal_id, user_id, role: OWNER|MEMBER|WATCHER)
|
||||
|
||||
-- Aktivitaeten
|
||||
crm_activities (id, type: CALL|MEETING|EMAIL|TASK|NOTE|FOLLOWUP,
|
||||
contact_id nullable, deal_id nullable,
|
||||
title, body, due_date, completed_at, assigned_to_user_id, created_by)
|
||||
|
||||
-- Custom Fields
|
||||
crm_custom_field_defs (id, entity_type: PERSON|COMPANY|DEAL, name, label, field_type,
|
||||
options jsonb, is_required, position)
|
||||
crm_custom_field_values (id, field_def_id, entity_id, value_text, value_number,
|
||||
value_date, value_boolean, value_json)
|
||||
```
|
||||
|
||||
**Hinweis**: Das aktuelle Prisma-Schema im CRM-Service weicht teilweise ab (z.B. `app_crm` Schema-Prefix statt `crm_` Tabellen-Prefix, flaches Company/Contact-Modell statt Contact+Person+Company Split). Der Architekt hat das Ziel-Schema definiert — Abgleich und Migration sind Backend-Aufgaben.
|
||||
|
||||
#### A.11 CRM Events (Kap 22.11)
|
||||
|
||||
| Event | Ausgeloest von | Empfaenger/Zweck |
|
||||
|-------|---------------|-----------------|
|
||||
| `crm.contact.created` | CRM-Service | Zukuenftige Module (Marketing etc.) |
|
||||
| `crm.contact.updated` | CRM-Service | Zukuenftige Module |
|
||||
| `crm.deal.stage_changed` | CRM-Service | Reporting, Automatisierungen |
|
||||
| `crm.deal.won` | CRM-Service | Reporting, Modul-Integrationen |
|
||||
| `crm.deal.lost` | CRM-Service | Reporting |
|
||||
| `crm.activity.due_soon` | CRM-Service (Scheduler) | Benachrichtigungs-Service |
|
||||
| `core.user.deactivated` | Core-Service | CRM prueft Owner-Reassignment |
|
||||
|
||||
**Backend-Aufgabe:**
|
||||
- [ ] Redis Pub/Sub Events bei Kontakt/Deal/Activity-Aenderungen publishen
|
||||
|
||||
---
|
||||
|
||||
### B) Office 365 Integration — CRM-relevante Teile (Kap 24)
|
||||
|
||||
Die OAuth-Verbindung (Kap 24.1) und Azure App-Registrierung (Kap 24.8) sind **CORE-Aufgaben**. Der CRM-Service nutzt die bestehende MS-Verbindung des Users fuer folgende Features:
|
||||
|
||||
#### B.1 E-Mail Tab im CRM-Kontakt (Kap 24.2) — Read-only
|
||||
|
||||
Pro CRM-Kontakt wird ein "E-Mails"-Tab angezeigt mit allen Outlook-Mails von/an die Kontakt-E-Mail-Adresse.
|
||||
|
||||
**Graph API Abfrage:**
|
||||
```
|
||||
GET /me/messages
|
||||
?$filter=from/emailAddress/address eq '{kontakt_email}'
|
||||
or toRecipients/any(...)
|
||||
&$select=id,subject,from,toRecipients,receivedDateTime,bodyPreview,isRead
|
||||
&$orderby=receivedDateTime desc
|
||||
&$top=25
|
||||
```
|
||||
|
||||
| Feature | Detail |
|
||||
|---------|--------|
|
||||
| Anzeige | Absender, Betreff, Datum, Vorschautext (max. 255 Zeichen) |
|
||||
| Sortierung | Neueste zuerst, 25 pro Seite |
|
||||
| Caching | Redis 5 Min (Key: `user:{id}:mails:contact:{id}`) |
|
||||
| Kein Volltext | Nur bodyPreview, kein vollstaendiger E-Mail-Body |
|
||||
| Kein Senden | Read-only |
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] `GET /crm/contacts/:id/emails` Endpoint (Proxy zu Graph API)
|
||||
- [ ] MS Access Token aus Redis / Refresh via Core
|
||||
- [ ] Redis-Caching (5 Min TTL)
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] "E-Mails" Tab in ContactDetailPage (nur wenn MS-Verbindung aktiv)
|
||||
- [ ] Ausgegraut wenn keine MS-Verbindung, Hinweis "Microsoft 365 verbinden"
|
||||
|
||||
#### B.2 Kalender Tab im CRM-Kontakt (Kap 24.3) — Read-only
|
||||
|
||||
Outlook-Termine bei denen der CRM-Kontakt als Teilnehmer eingetragen ist.
|
||||
|
||||
**Graph API Abfrage:**
|
||||
```
|
||||
GET /me/calendarView
|
||||
?startDateTime={heute}T00:00:00Z
|
||||
&endDateTime={heute+90Tage}T23:59:59Z
|
||||
&$filter=attendees/any(a: a/emailAddress/address eq '{kontakt_email}')
|
||||
&$select=id,subject,start,end,location,attendees,bodyPreview,onlineMeetingUrl
|
||||
```
|
||||
|
||||
| Feature | Detail |
|
||||
|---------|--------|
|
||||
| Anzeige | Kommende 90 Tage + vergangene 90 Tage |
|
||||
| Felder | Titel, Datum/Uhrzeit, Ort, Online-Meeting-Link, Teilnehmer |
|
||||
| Caching | Redis 5 Min |
|
||||
| Kein Schreiben | Read-only |
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] `GET /crm/contacts/:id/calendar` Endpoint
|
||||
- [ ] Redis-Caching
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] "Kalender" Tab in ContactDetailPage
|
||||
|
||||
#### B.3 Aufgaben Sync — Bidirektional mit Microsoft To Do (Kap 24.4)
|
||||
|
||||
CRM-Aufgaben koennen optional nach Microsoft To Do synchronisiert werden.
|
||||
|
||||
**Richtung INSIGHT -> To Do:**
|
||||
- Trigger: Aufgabe erstellt/geaendert im CRM
|
||||
- Action: `POST /me/todo/lists/{defaultListId}/tasks` (oder PATCH wenn ms_task_id bekannt)
|
||||
- `ms_task_id` wird in `crm_activities` gespeichert
|
||||
|
||||
**Richtung To Do -> INSIGHT:**
|
||||
- NestJS `@Cron` Polling alle 5 Min fuer User mit aktiver MS-Verbindung
|
||||
- `GET /me/todo/lists/{listId}/tasks?$filter=lastModifiedDateTime gt {letzter_sync}`
|
||||
- Status-Aenderungen (erledigt/offen) werden uebernommen
|
||||
- Redis-Lock pro User verhindert parallele Sync-Jobs
|
||||
- Nur INSIGHT-erstellte Aufgaben werden synchronisiert (die eine ms_task_id haben)
|
||||
|
||||
**DB-Aenderungen an crm_activities:**
|
||||
```sql
|
||||
+ ms_task_id VARCHAR(255) -- To Do Aufgaben ID
|
||||
+ ms_task_list_id VARCHAR(255) -- To Do Listen ID
|
||||
+ ms_synced_at TIMESTAMPTZ -- Letzter erfolgreicher Sync
|
||||
```
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] ms_task_id, ms_task_list_id, ms_synced_at Felder in Activity-Model
|
||||
- [ ] Graph API Integration: POST/PATCH Tasks
|
||||
- [ ] @Cron Scheduler (alle 5 Min) fuer To Do -> INSIGHT Sync
|
||||
- [ ] Redis-Lock pro User
|
||||
- [ ] Konfliktbehandlung: INSIGHT gewinnt (Last Write Wins mit Timestamp)
|
||||
|
||||
#### B.4 Kontakte Export nach Outlook (Kap 24.5) — Manuell
|
||||
|
||||
Button "Nach Outlook exportieren" im CRM-Kontakt (Person).
|
||||
|
||||
**Ablauf:**
|
||||
1. User klickt "Nach Outlook exportieren"
|
||||
2. Pruefung: MS-Verbindung aktiv? -> Wenn nein: Hinweis
|
||||
3. Existiert Kontakt in Outlook (ms_contact_id)? -> PATCH (Update) / POST (Neu)
|
||||
4. ms_contact_id wird in crm_persons gespeichert
|
||||
|
||||
**Feldzuordnung CRM -> Outlook:**
|
||||
|
||||
| CRM Feld | Outlook Contacts (Graph API) |
|
||||
|----------|------------------------------|
|
||||
| Vorname + Nachname | givenName + surname |
|
||||
| Jobtitel | jobTitle |
|
||||
| Unternehmen | companyName |
|
||||
| Abteilung | department |
|
||||
| E-Mails | emailAddresses[] |
|
||||
| Telefone | businessPhones[] / mobilePhone |
|
||||
| Adresse | businessAddress |
|
||||
| LinkedIn-URL | businessHomePage |
|
||||
| Notizen | personalNotes |
|
||||
|
||||
**DB-Aenderung an crm_persons:**
|
||||
```sql
|
||||
+ ms_contact_id VARCHAR(255) -- Outlook Kontakt ID
|
||||
```
|
||||
|
||||
**Backend-Aufgaben:**
|
||||
- [ ] `POST /crm/contacts/:id/export-to-outlook` Endpoint
|
||||
- [ ] ms_contact_id Feld in Person-Model
|
||||
- [ ] Bei 404 (Kontakt in Outlook geloescht): neuen Kontakt erstellen, ms_contact_id aktualisieren
|
||||
|
||||
**Frontend-Aufgaben:**
|
||||
- [ ] "Nach Outlook exportieren" Button in Kontakt-Header (nur fuer Personen)
|
||||
- [ ] Ausgegraut wenn keine MS-Verbindung
|
||||
|
||||
---
|
||||
|
||||
### C) Zusammenfassung: Priorisierte Aufgabenliste fuer CRM-Entwickler
|
||||
|
||||
**Prio 1 — Kurzfristig (bestehende Features erweitern):**
|
||||
- [ ] Fehlende Kontakt-/Unternehmens-Felder im Prisma-Schema ergaenzen (LinkedIn, Geburtsdatum, Quelle, USt-IdNr etc.)
|
||||
- [ ] Lost-Grund (Enum + Freitext) bei Deals
|
||||
- [ ] Contact/Deal-Owner m:n Modell (crm_contact_owners, crm_deal_owners)
|
||||
- [ ] Redis Pub/Sub Events bei Entity-Aenderungen
|
||||
|
||||
**Prio 2 — Mittelfristig (neue Features):**
|
||||
- [ ] Custom Fields (Definition + Wert-Speicherung + Admin-UI)
|
||||
- [ ] Firmendaten-Anreicherung (Unternehmensregister.de + North Data)
|
||||
- [ ] Kontakt-Import (CSV, Excel, vCard) mit Spalten-Mapper + Duplikat-Erkennung
|
||||
- [ ] Berechtigungsmodell (Eigene/Team/Alle Sichtbarkeit)
|
||||
- [ ] Kanban-Board fuer Deals (Drag & Drop)
|
||||
- [ ] Forecast-Ansicht
|
||||
|
||||
**Prio 3 — Spaeter (abhaengig von Core-Vorarbeiten):**
|
||||
- [ ] Office 365: E-Mail Tab (benoetigt OAuth-Infrastruktur im Core)
|
||||
- [ ] Office 365: Kalender Tab
|
||||
- [ ] Office 365: Aufgaben Sync mit Microsoft To Do
|
||||
- [ ] Office 365: Kontakte Export nach Outlook
|
||||
- [ ] Visitenkarten-Scan (Anthropic Vision API)
|
||||
- [ ] CRM Reporting & Dashboards (5 Reports + CSV-Export)
|
||||
|
||||
---
|
||||
|
||||
*Bitte neue Eintraege unten anfuegen. Format: `## YYYY-MM-DD | Absender: Betreff`*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue