mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 03:06:39 +02:00
- Stage-Editing, DealDetail-Optimierung, Deals→Vorgänge Renaming - Offene Punkte aktualisiert Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
211 lines
9.3 KiB
Markdown
211 lines
9.3 KiB
Markdown
# 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):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [...],
|
|
"pagination": { "page": 1, "pageSize": 25, "total": 42, "totalPages": 2 },
|
|
"meta": { "timestamp": "..." }
|
|
}
|
|
```
|
|
|
|
**Einzelobjekt:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": { ... },
|
|
"meta": { "timestamp": "..." }
|
|
}
|
|
```
|
|
|
|
**Fehler:**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": { "code": "NOT_FOUND", "message": "...", "details": [] },
|
|
"meta": { "timestamp": "..." }
|
|
}
|
|
```
|
|
|
|
### Annahmen / Abhaengigkeiten ans Backend
|
|
|
|
1. **Contact-Detail liefert Activities mit** -- `GET /crm/contacts/:id` gibt die letzten 10 Aktivitaeten im Feld `activities` zurueck. Das Frontend zeigt diese in der Timeline an.
|
|
|
|
2. **Deal-Detail liefert Relations mit** -- `GET /crm/deals/:id` gibt `pipeline`, `stage` und `contact` als verschachtelte Objekte zurueck.
|
|
|
|
3. **Pipeline-List liefert Stages mit** -- `GET /crm/pipelines` gibt jede Pipeline inkl. `stages[]` Array zurueck. Das Frontend nutzt diese fuer die Stage-Selektoren im Deal-Formular.
|
|
|
|
4. **Deal.value ist ein String** -- Decimal kommt als String vom Backend (z.B. `"24000.00"`). Das Frontend parst mit `parseFloat()`.
|
|
|
|
5. **Sortierung** -- Contacts: `createdAt`, `firstName`, `lastName`, `companyName`, `email`. Deals: `createdAt`, `title`, `value`, `expectedCloseDate`.
|
|
|
|
6. **Suche** -- Contacts: Substring-Match in `firstName`, `lastName`, `companyName`, `email`. Deals: Substring-Match in `title`.
|
|
|
|
### Bekannte Offene Punkte
|
|
|
|
- [ ] **Traefik HTTPS-Router fuer CRM**: Aktuell hat der CRM-Service nur einen HTTP-Router (`web` Entrypoint). Fuer HTTPS (`websecure`) muesste ein zweiter Router mit `tls=true` angelegt werden (wie bei `core-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
|
|
|
|
- [x] **Traefik HTTPS-Router**: `crm-secure` Router angelegt mit `entrypoints=websecure`, `tls=true`, Priority 100. Deployed in Commit `c9e2c4a`.
|
|
|
|
- [x] **Pipeline-Stages bearbeiten**: Neuer Endpoint `PATCH /crm/pipelines/:id/stages/:stageId` hinzugefuegt. Akzeptiert:
|
|
```json
|
|
{
|
|
"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/:id` mit `{ 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`:
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
- [x] ~~Pipeline-Stages bearbeiten~~ — Frontend nutzt den neuen PATCH-Endpoint
|
|
- [x] ~~DealDetail 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-frontend` neu gebaut und deployed
|
|
|
|
---
|
|
|
|
*Bitte neue Eintraege unten anfuegen. Format: `## YYYY-MM-DD | Absender: Betreff`*
|