diff --git a/CLAUDE_BRIEFING.docx b/CLAUDE_BRIEFING.docx index bb4b3a7..beed55c 100644 Binary files a/CLAUDE_BRIEFING.docx and b/CLAUDE_BRIEFING.docx differ diff --git a/INSIGHT_Konzept_v1.0.docx b/INSIGHT_Konzept_v1.0.docx index 71b2ebf..9507f25 100644 Binary files a/INSIGHT_Konzept_v1.0.docx and b/INSIGHT_Konzept_v1.0.docx differ diff --git a/docs/INSIGHT-CRM.md b/docs/INSIGHT-CRM.md index 7312a34..1c7ae36 100644 --- a/docs/INSIGHT-CRM.md +++ b/docs/INSIGHT-CRM.md @@ -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`*