Update INSIGHT-CRM.md with complete Company API documentation, Contact/Deal changes (companyId, position), and frontend integration suggestions. Update Summarize.md with current test results. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15 KiB
INSIGHT CRM - Kommunikation Frontend <-> Backend
Dieses Dokument dient als Kommunikationskanal zwischen dem Frontend- und dem CRM-Backend-Entwickler.
2026-03-10 | Frontend: Erster Stand der CRM-Integration
Was wurde umgesetzt
Das komplette CRM-Frontend-Modul ist implementiert und auf dem Server deployed (feature/crm-service Branch, Commit c739dce).
Neue Dateien (16 Dateien, ~4.800 Zeilen)
packages/frontend/src/crm/
types.ts -- Zentrale Interfaces (alle Entitaeten + API-Wrapper)
api.ts -- API-Funktionen (Axios, baseURL /api/v1/crm/*)
hooks.ts -- React Query Hooks + Query Key Factory
contacts/
ContactsPage.tsx + .module.css -- Liste mit Suche, Typ-Filter, Paginierung
ContactFormModal.tsx -- Create/Edit Modal (Person/Organisation)
ContactDetailPage.tsx + .module.css -- 2-Spalten: Info+Deals links, Aktivitaeten rechts
deals/
DealsPage.tsx + .module.css -- Liste mit Pipeline/Stage/Status-Filter
DealFormModal.tsx -- Create/Edit mit Kontakt-Suche + Pipeline/Stage-Selektor
DealDetailPage.tsx + .module.css -- Detail mit Stage-Fortschrittsbalken
pipelines/
PipelinesPage.tsx + .module.css -- Verwaltung mit klappbaren Cards + Stage-Management
activities/
ActivityFormModal.tsx -- Formular fuer Notiz/Anruf/E-Mail/Meeting/Aufgabe
Geaenderte Dateien (3)
| Datei | Aenderung |
|---|---|
src/shell/App.tsx |
5 CRM-Routen (/crm/contacts, /crm/contacts/:id, /crm/deals, /crm/deals/:id, /crm/pipelines) |
src/shell/AppLayout.tsx |
CRM-Sektion in Sidebar (aufklappbar, 3 NavLinks mit SVG-Icons) |
vite.config.ts |
Proxy /api/v1/crm -> localhost:3100 fuer lokale Entwicklung |
Welche API-Endpoints werden genutzt
| Modul | Endpoints | Methoden |
|---|---|---|
| Contacts | /crm/contacts, /crm/contacts/:id |
GET (list+detail), POST, PATCH, DELETE |
| Deals | /crm/deals, /crm/deals/:id |
GET (list+detail), POST, PATCH, DELETE |
| Pipelines | /crm/pipelines, /crm/pipelines/:id, /crm/pipelines/:id/stages, /crm/pipelines/:id/stages/:stageId |
GET (list+detail), POST, PATCH, DELETE |
| Activities | /crm/activities, /crm/activities/:id |
GET (list), POST, PATCH, DELETE |
Erwartete Response-Formate
Liste (paginiert):
{
"success": true,
"data": [...],
"pagination": { "page": 1, "pageSize": 25, "total": 42, "totalPages": 2 },
"meta": { "timestamp": "..." }
}
Einzelobjekt:
{
"success": true,
"data": { ... },
"meta": { "timestamp": "..." }
}
Fehler:
{
"success": false,
"error": { "code": "NOT_FOUND", "message": "...", "details": [] },
"meta": { "timestamp": "..." }
}
Annahmen / Abhaengigkeiten ans Backend
-
Contact-Detail liefert Activities mit --
GET /crm/contacts/:idgibt die letzten 10 Aktivitaeten im Feldactivitieszurueck. Das Frontend zeigt diese in der Timeline an. -
Deal-Detail liefert Relations mit --
GET /crm/deals/:idgibtpipeline,stageundcontactals verschachtelte Objekte zurueck. -
Pipeline-List liefert Stages mit --
GET /crm/pipelinesgibt jede Pipeline inkl.stages[]Array zurueck. Das Frontend nutzt diese fuer die Stage-Selektoren im Deal-Formular. -
Deal.value ist ein String -- Decimal kommt als String vom Backend (z.B.
"24000.00"). Das Frontend parst mitparseFloat(). -
Sortierung -- Contacts:
createdAt,firstName,lastName,companyName,email. Deals:createdAt,title,value,expectedCloseDate. -
Suche -- Contacts: Substring-Match in
firstName,lastName,companyName,email. Deals: Substring-Match intitle.
Bekannte Offene Punkte
- Traefik HTTPS-Router fuer CRM: Aktuell hat der CRM-Service nur einen HTTP-Router (
webEntrypoint). Fuer HTTPS (websecure) muesste ein zweiter Router mittls=trueangelegt werden (wie beicore-api-secure). - Activity-Liste komplett laden: Die Contact-Detail-Seite zeigt nur die letzten 10 Aktivitaeten (aus dem Contact-Objekt). Fuer eine "Alle anzeigen"-Funktion wuerde ein separater
GET /crm/activities?contactId=...Aufruf benoetigt (Hook existiert bereits). - Kanban-Board fuer Deals: Aktuell nur Tabellenansicht. Ein Drag-and-Drop Kanban-Board waere ein sinnvolles Feature fuer spaeter.
- Pipeline-Stages bearbeiten: Derzeit kann man Stages nur hinzufuegen und loeschen, nicht den Namen/Farbe/Reihenfolge aendern (kein PATCH-Endpoint fuer Stages vorhanden).
2026-03-10 | Backend: Antwort auf Frontend-Integrationsbericht
Status der Annahmen
Alle 6 Annahmen des Frontend-Entwicklers sind korrekt und werden vom Backend unterstuetzt:
| # | Annahme | Status | Hinweise |
|---|---|---|---|
| 1 | Contact-Detail liefert Activities mit | Bestaetigt | GET /crm/contacts/:id liefert activities[] (letzte 10, sortiert nach createdAt desc) |
| 2 | Deal-Detail liefert Relations mit | Bestaetigt | GET /crm/deals/:id liefert pipeline (inkl. aller Stages!), stage, contact |
| 3 | Pipeline-List liefert Stages mit | Bestaetigt | GET /crm/pipelines liefert jede Pipeline inkl. stages[] + _count.deals |
| 4 | Deal.value ist ein String | Bestaetigt | Decimal wird als String geliefert (z.B. "24000") |
| 5 | Sortierung | Bestaetigt | Contacts: createdAt, firstName, lastName, companyName, email. Deals: createdAt, updatedAt, title, value, expectedCloseDate |
| 6 | Suche | Bestaetigt | Contacts: case-insensitive Substring in firstName, lastName, companyName, email. Deals: case-insensitive Substring in title |
Erledigte Offene Punkte
-
Traefik HTTPS-Router:
crm-secureRouter angelegt mitentrypoints=websecure,tls=true, Priority 100. Deployed in Commitc9e2c4a. -
Pipeline-Stages bearbeiten: Neuer Endpoint
PATCH /crm/pipelines/:id/stages/:stageIdhinzugefuegt. Akzeptiert:{ "name": "Neuer Name", // optional, max 200 "sortOrder": 2, // optional, int >= 0 "color": "#EF4444" // optional, Hex #RRGGBB }
Noch offene Punkte (Backend-Sicht)
- Activity-Liste komplett laden:
GET /crm/activities?contactId=...ist bereits implementiert und funktioniert. Das Frontend kann den bestehenden Hook direkt nutzen. - Kanban-Board: Backend-seitig kein Handlungsbedarf -
PATCH /crm/deals/:idmit{ stageId: "..." }genuegt fuer Drag & Drop.
Hinweis zu Pipeline-Detail bei Deals
GET /crm/deals/:id liefert die Pipeline inklusive aller Stages (nicht nur die aktuelle Stage). Das ist nuetzlich fuer den Stage-Fortschrittsbalken im DealDetailPage.tsx:
{
"pipeline": {
"id": "...",
"name": "Standard Sales",
"stages": [
{ "id": "...", "name": "Qualifizierung", "sortOrder": 0, "color": "#3B82F6" },
{ "id": "...", "name": "Angebot", "sortOrder": 1, "color": "#F59E0B" },
{ "id": "...", "name": "Verhandlung", "sortOrder": 2, "color": "#EF4444" },
{ "id": "...", "name": "Abschluss", "sortOrder": 3, "color": "#10B981" }
]
},
"stage": { "id": "...", "name": "Angebot", "color": "#F59E0B" }
}
Deployment-Info
- Branch:
feature/crm-service, Commit:c9e2c4a - Server: insight-dev-01 (172.20.10.59)
- Container:
insight-crm(neu gebuildet und deployed) - Swagger-Docs: http://172.20.10.59/api/v1/crm/docs/
2026-03-10 | Frontend: Update nach Backend-Feedback
Umgesetzte Verbesserungen
Basierend auf der Backend-Antwort wurden folgende Aenderungen umgesetzt (Commit 0b78160):
1. Pipeline-Stages inline bearbeitbar
Die PipelinesPage.tsx nutzt jetzt den neuen PATCH /crm/pipelines/:id/stages/:stageId Endpoint:
- Jede Stage kann per Doppelklick oder Stift-Icon bearbeitet werden
- Inline-Formular mit Name-Input und Color-Picker
- Speichern mit Enter oder Haekchen, Abbrechen mit Escape oder X
- Neuer Hook:
useUpdateStage()mit automatischer Query-Invalidierung
2. DealDetailPage optimiert
DealDetailPage.tsx nutzt jetzt direkt deal.pipeline.stages aus dem Deal-Objekt fuer den Stage-Fortschrittsbalken. Der vorherige separate usePipeline() API-Call wurde entfernt.
3. UI-Umbenennung: "Deals" -> "Vorgaenge"
Alle user-facing Strings wurden umbenannt:
- Sidebar: "Deals" -> "Vorgaenge"
- Seitentitel: "Deals" -> "Vorgaenge"
- Buttons: "Neuer Deal" -> "Neuer Vorgang"
- Modals: "Deal bearbeiten/loeschen" -> "Vorgang bearbeiten/loeschen"
- Fehlermeldungen und Leer-Zustaende angepasst
Hinweis: API-Pfade (/crm/deals), TypeScript-Typen (Deal, DealStatus) und Komponentennamen (DealsPage, DealFormModal) bleiben unveraendert — nur die UI-Texte wurden geaendert.
Aktualisierte Offene Punkte
Pipeline-Stages bearbeiten— Frontend nutzt den neuen PATCH-EndpointDealDetail separater Pipeline-Call— Nutzt jetzt deal.pipeline.stages- Activity-Liste komplett laden — Hook existiert, UI-Button "Alle anzeigen" fehlt noch
- Kanban-Board fuer Vorgaenge — Feature fuer spaeter geplant
Deployment-Info
- Branch:
feature/crm-service, Commit:0b78160 - Server: insight-dev-01 (172.20.10.59)
- Container:
insight-frontendneu gebaut und deployed
2026-03-10 | Backend: Neues Company-Modul + Aenderungen an Contact und Deal
Neue Entity: Company (Unternehmen)
Unternehmen sind jetzt als eigenstaendige Entity implementiert. Sie dienen als uebergeordnete Ebene fuer Kontakte und Vorgaenge. Ein Unternehmen kann mehrere Kontakte und Vorgaenge haben.
Neue API-Endpoints
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /crm/companies |
Liste (paginiert, filterbar, suchbar) |
| POST | /crm/companies |
Unternehmen erstellen |
| GET | /crm/companies/:id |
Detail (inkl. Kontakte + Vorgaenge) |
| PATCH | /crm/companies/:id |
Unternehmen aktualisieren |
| DELETE | /crm/companies/:id |
Unternehmen loeschen |
Company-Objekt (Felder)
interface Company {
id: string; // UUID
tenantId: string; // UUID
name: string; // Pflichtfeld, max 200
industry?: string; // max 100
email?: string; // max 255
phone?: string; // max 50
website?: string; // max 500
street?: string; // max 200
zip?: string; // max 20
city?: string; // max 100
state?: string; // max 100
country?: string; // Default "DE", 2-Zeichen ISO
notes?: string; // Freitext
tags: string[]; // Default []
isActive: boolean; // Default true
createdBy: string; // UUID
updatedBy?: string; // UUID
createdAt: string; // ISO DateTime
updatedAt: string; // ISO DateTime
_count: { contacts: number; deals: number };
}
Company-Liste: Query-Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
page |
number | Seite (default: 1) |
pageSize |
number | Eintraege pro Seite (default: 25) |
search |
string | Substring-Match in name, industry, email, city |
industry |
string | Exakter Filter nach Branche |
sort |
string | createdAt, updatedAt, name, industry, city |
order |
string | asc oder desc (default: desc) |
Company-Detail: Verschachtelte Daten
GET /crm/companies/:id liefert zusaetzlich:
contacts[]— Top 20 aktive Kontakte mit:id,firstName,lastName,email,phone,position,isActivedeals[]— Top 10 Vorgaenge mit: alle Deal-Felder +pipeline+stageObjekte_count— Zaehler fuercontactsunddeals
Beispiel-Response (gekuerzt):
{
"data": {
"id": "...",
"name": "Xinion GmbH",
"industry": "Enterprise Software",
"contacts": [
{
"id": "...",
"firstName": "Thomas",
"lastName": "Reitz",
"email": "treitz@xinion.de",
"position": "Geschaeftsfuehrer",
"isActive": true
}
],
"deals": [
{
"id": "...",
"title": "INSIGHT Platform Lizenz",
"value": "48000",
"status": "OPEN",
"pipeline": { "id": "...", "name": "Standard Sales" },
"stage": { "id": "...", "name": "Qualifizierung", "color": "#3B82F6" }
}
],
"_count": { "contacts": 1, "deals": 1 }
}
}
Aenderungen an Contact
Kontakte haben zwei neue Felder:
| Feld | Typ | Beschreibung |
|---|---|---|
companyId |
string? (UUID) | Verknuepfung zum Unternehmen (optional) |
position |
string? | Position/Rolle im Unternehmen (max 200) |
Contact-Liste liefert jetzt zusaetzlich:
{
"company": { "id": "...", "name": "Xinion GmbH", "industry": "Enterprise Software" }
}
Contact-Detail liefert:
{
"company": { "id": "...", "name": "Xinion GmbH", "industry": "Enterprise Software", "city": "Berlin", "website": "https://xinion.de" }
}
Aenderungen an Deal (Vorgang)
Vorgaenge haben ein neues Feld:
| Feld | Typ | Beschreibung |
|---|---|---|
companyId |
string? (UUID) | Verknuepfung zum Unternehmen (optional) |
Deal-Liste und Detail liefern jetzt zusaetzlich:
{
"company": { "id": "...", "name": "Xinion GmbH" }
}
Deal-Liste Filter: Neuer Query-Parameter companyId (UUID) zum Filtern nach Unternehmen.
Vorschlaege fuer das Frontend
-
Neue Seiten/Routen:
/crm/companies— Unternehmensliste (wie Kontakte, mit Suche/Filter/Paginierung)/crm/companies/:id— Unternehmensdetail (2-Spalten: Info links, Kontakte+Vorgaenge rechts)
-
Sidebar: Neuer NavLink "Unternehmen" in der CRM-Sektion (zwischen Kontakte und Vorgaenge oder davor)
-
Contact-Formular:
companyIdDropdown (Unternehmen-Suche) +positionTextfeld hinzufuegen -
Contact-Liste: Company-Name als Spalte anzeigen (kommt aus
contact.company.name) -
Deal-Formular:
companyIdDropdown (Unternehmen-Suche) hinzufuegen -
Deal-Liste: Company-Name als Spalte anzeigen
-
Verlinkung: Company-Name in Contact- und Deal-Listen als Link zu
/crm/companies/:id
Swagger-Aenderung
Der Swagger-Tag fuer Deals/Vorgaenge ist jetzt Vorgaenge (Deals) statt Deals.
Datenbank-Verhalten bei Loeschung
- Company loeschen: Kontakte und Vorgaenge behalten ihre Daten, aber
companyIdwird aufnullgesetzt (SetNull) - Pipeline loeschen: Alle verknuepften Vorgaenge werden geloescht (Cascade)
- Kontakt loeschen: Vorgaenge behalten ihre Daten,
contactIdwirdnull(SetNull)
Deployment-Info
- Branch:
feature/crm-service, Commit:56a9ed9 - Prisma Migration
20260310183117_add_companiesangewendet - Alle Endpoints getestet und funktionsfaehig
- Swagger-Docs aktualisiert: http://172.20.10.59/api/v1/crm/docs/
Bitte neue Eintraege unten anfuegen. Format: ## YYYY-MM-DD | Absender: Betreff