INSIGHT-MVP/Summarize.md
Thomas Reitz a55643a0dd docs(crm): Phase 2.2-2.4 Frontend-TODOs abgehakt + Summarize.md aktualisiert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 21:09:16 +01:00

360 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# INSIGHT MVP - Aenderungsprotokoll
## Stand: 2026-03-12
### Aktueller Sprint: CRM Phase 2 (Feature-Branch: feature/crm-service)
---
### Aenderungen 2026-03-12: CRM Phase 2 — Forecast, Import, Enrichment (Frontend komplett)
#### Phase 2.3: Forecasting
- `crm/forecast/ForecastPage.tsx` — Prognose-Dashboard unter `/crm/forecast`
- Pipeline-Filter (Dropdown) + Zeitraum-Toggle (Monat/Quartal/Jahr)
- Summary-Cards: Offene Vorgaenge, Gesamtwert, Gewichteter Wert, Zeitraum
- Tabelle: Stage | Wahrscheinlichkeit | Vorgaenge | Gesamtwert | Gewichteter Wert
- `crm/pipelines/PipelinesPage.tsx` — Probability-Feld (0100%) pro Pipeline-Stage
#### Phase 2.2: CSV/Excel Import
- `crm/import/ImportPage.tsx` — 3-Schritt-Wizard in CRM-Einstellungen → Tab "Import"
- Schritt 1: Typ-Auswahl (Kontakte/Unternehmen/Vorgaenge) + Datei-Upload (CSV, XLSX, max 10MB)
- Schritt 2: Spalten-Mapping (Auto-Match + manuell), Duplikat-Strategie, Kopfzeilen-Option
- Schritt 3: Ergebnis (created/updated/skipped/errors + Fehlerdetails)
- API-Konvertierungen: `PERSON→contact`, mapping `Record→Array [{sourceColumn,targetField}]`
#### Phase 2.4: Datenanreicherung
- `crm/companies/CompanyDetailPage.tsx` — "Anreichern"-Button im Header
- POST /companies/:id/enrich → Suggestions-Modal
- Tabelle: Feld | Aktuell | Vorschlag | Quelle + "Uebernehmen"-Button (PATCH)
- suggestions-Konvertierung: Backend-Record → UI-Array
- `crm/settings/CrmSettingsPage.tsx` — North Data API-Key in Tab "Integrationen"
#### Kontakt-Entity UI/UX Redesign (aus dieser Sprint-Session)
- `components/Drawer.tsx` + `Drawer.module.css` — Wiederverwendbarer Right-Side-Drawer
- `crm/contacts/ContactFormModal.tsx` — Modal → Drawer, Zwei-Tab-Struktur (Allgemein/Details)
- `crm/contacts/ContactDetailPage.tsx`:
- Header: Name (Unternehmen) in Klammern, Aktiv/Inaktiv-Badge (Pill mit farbigem Dot)
- Kontaktdaten-Card: immer alle Allgemein-Felder (leere Felder = "—"), 2 Sub-Spalten
- Lexware-Section entfernt (Kontakte werden nicht separat in Lexware gepflegt)
#### TypeScript
- `npx tsc --noEmit` in packages/frontend: 0 Fehler (alle Commits)
---
### Aktueller Sprint: Sprint 1 (Alpha)
---
### Aenderungen 2026-03-12: CRM UI/UX Redesign Kontakt-Entitaet
#### Drawer-Komponente (neu)
- `packages/frontend/src/components/Drawer.tsx` Wiederverwendbares Right-Side-Drawer-Pattern mit Portal, ESC-Key, Backdrop-Click, optionalem Footer
- `packages/frontend/src/components/Drawer.module.css` Animiertes Slide-In von rechts, sticky Header + Footer, scrollbarer Body
#### ContactFormModal Redesign (Modal → Drawer + Tabs)
- Gewechselt von `<Modal>` (zentriert) zu `<Drawer>` (von rechts, 540px)
- Zwei-Tab-Struktur:
- Tab "Allgemein": Vorname, Nachname, Unternehmen (Autocomplete), Position, Abteilung, E-Mail, Telefon, Mobil, LinkedIn
- Tab "Details & Adresse": Geburtsdatum, Quelle, Status, Website, Adresse, Notizen, Tags, Custom Fields
- "Adresse vom Unternehmen uebernehmen" Checkbox: wird angezeigt wenn Unternehmen verlinkt ist; bei aktivierter Checkbox werden Adressfelder ausgeblendet und die Adresse wird aus dem verlinkten Unternehmen uebernommen
- "Typ"-Feld entfernt (Kontakte sind immer Personen; ORGANIZATION-Typ bleibt intern erhalten)
- Sticky Footer (Abbrechen / Anlegen|Speichern) via HTML5 `form` Attribut
- Adress-Duplikate bereinigt
#### ContactDetailPage Redesign
- **Header**: Subtitle "Position @ Unternehmen" unter dem Namen (z.B. "Geschaeftsfuehrerin @ team neusta SE"), Status-Dot inline
- **Kontaktdaten-Card**: Zwei Sub-Spalten (Kommunikation links, Kontext rechts), Adresse als volle Breite darunter
- Entfernt: Vorname/Nachname (im Header), Firma-Duplikat (nur noch "Unternehmen" als Link)
- Hinzugefuegt: Mobil als `tel:`-Link, LinkedIn mit Icon, Geburtsdatum, Quelle, Abteilung
- **Neue Card "Notizen & Tags"**: Tags als Badges, Notizen-Text, Custom Fields
- **Layout**: Rechte Spalte (Aktivitaeten) auf `minmax(380px, 40%)` verbreitert (min. 1/3 fuer kuenftigen O365-Feed)
- **CSS**: `.infoColumns` (2-spaltig), `.addressRow`, `.subtitle`, `.nameRow` neu
#### TypeScript
- `npx tsc --noEmit` in packages/frontend: 0 Fehler
---
### Aenderungen in dieser Session
#### 1. Projektinitialisierung & Infrastruktur-Definition
**Was wurde gemacht:**
1. **SSH Keys erstellt**
- Deploy-Key (`.keys/deploy_ed25519`) fuer Server-Zugriff
- CI/CD-Key (`.keys/cicd_ed25519`) fuer Forgejo Actions Pipeline
2. **Infrastruktur-Definition erstellt** (`docs/INFRASTRUCTURE.md`)
- ProxmoxVE VM-Spezifikation: Ubuntu 24.04 LTS, 4 vCPU, 8 GB RAM, 60 GB SSD
- Docker-Netzwerk-Architektur mit 3 isolierten Netzwerken
- Komplette Service-Landschaft definiert
- Schritt-fuer-Schritt VM-Setup Anleitung
3. **Zugangsdaten-Dokument erstellt** (`docs/ACCESS.md`)
- Server-IP: 172.20.10.59 (insight-dev-01)
- Git-Server: 172.20.10.11 (GAIA-GIT)
- Alle SSH-Keys, Ports, Befehle dokumentiert
4. **Projektstruktur aufgesetzt** (packages/core-service, packages/frontend, config, .forgejo)
5. **Basis-Konfigurationsdateien** (.gitignore, .env.example, README.md)
#### 2. Forgejo Git-Server Konfiguration
**Was wurde auf dem Git-Server (172.20.10.11) gemacht:**
1. **Docker Engine 29.3 installiert** (fuer Forgejo Actions Runner)
2. **Forgejo Actions aktiviert** (`[actions] ENABLED = true` in app.ini)
3. **Container Registry aktiviert** (`[packages] ENABLED = true` in app.ini)
4. **Forgejo Runner v6.3.1 installiert und registriert**
- Runner-Name: `insight-runner`
- Labels: `ubuntu-latest` (docker://node:20)
- Laeuft als Systemd-Service (`forgejo-runner.service`)
5. **Repository Secrets angelegt:**
- `SSH_DEPLOY_KEY` - CI/CD Private Key
- `DEPLOY_HOST` - 172.20.10.59
- `DEPLOY_USER` - deploy
- `REGISTRY_USER` - gitadmin
- `REGISTRY_PASSWORD` - Forgejo Access Token
6. **Branch Protection eingerichtet:**
- `main`: Kein direkter Push, 1 Approval erforderlich
- `develop`: Kein direkter Push, 1 Approval erforderlich
7. **Forgejo Setup-Anleitung erstellt** (`docs/FORGEJO_SETUP.md`)
#### 3. Server-Setup (insight-dev-01)
**Was wurde auf dem Entwicklungsserver (172.20.10.59) gemacht:**
1. **SSH Public Keys hinterlegt** in `/home/deploy/.ssh/authorized_keys`
- Deploy-Key (`insight-deploy@xinion.lan`) - fuer manuellen Zugriff
- CI/CD-Key (`insight-cicd@xinion.lan`) - fuer Forgejo Actions Pipeline
2. **SSH-Zugang getestet** - Key-basierter Login als `deploy` funktioniert
#### 4. Docker Compose & Service-Konfiguration
**Erstellte Dateien:**
1. **`docker-compose.yml`** - Alle Basis-Services:
- Traefik 3 (API Gateway, Reverse Proxy, Rate Limiting)
- PostgreSQL 16-alpine (Performance-Tuning: 1GB shared_buffers, 4GB cache)
- PgBouncer (Connection Pooling, Transaction Mode)
- Redis 7-alpine (Cache, Sessions, Token-Revocation)
- step-ca (Interne Certificate Authority fuer mTLS - geplant)
- Core-Service (NestJS) mit Traefik-Labels
- Frontend (React) mit Traefik-Labels
- 3 isolierte Docker-Netzwerke (insight-web, insight-db, insight-cache)
- Health-Checks fuer alle Services
2. **`docker-compose.observability.yml`** - Monitoring-Stack:
- Prometheus (Metrics-Sammlung, 30 Tage Retention)
- Grafana (Dashboards, automatisch provisionierte Datenquellen)
- Loki (Log-Aggregation)
- Promtail (Docker Log-Collector)
- Tempo (Distributed Tracing, OTLP gRPC)
- cAdvisor (Container-Metriken)
- PostgreSQL Exporter (DB-Metriken)
3. **Konfigurationsdateien:**
- `config/traefik/dynamic/tls.yml` - TLS deaktiviert (Alpha/Dev)
- `config/traefik/dynamic/middlewares.yml` - Security-Headers, CORS, Compression
- `config/prometheus/prometheus.yml` - Scrape-Konfiguration
- `config/loki/loki.yml` - Log-Storage-Konfiguration
- `config/promtail/promtail.yml` - Docker-Log-Collector
- `config/tempo/tempo.yml` - Tracing-Backend
- `config/grafana/provisioning/datasources/datasources.yml` - Auto-Provisioning
- `config/postgres/init/01-init-extensions.sql` - DB-Extensions (uuid-ossp, pgcrypto, pg_trgm)
#### 5. NestJS Core-Service Implementierung
**Projekt-Setup:**
- `package.json` mit allen Dependencies (NestJS 10, Prisma 6, Passport, JWT, bcrypt, TOTP)
- `tsconfig.json` mit strict: true, noImplicitAny, strictNullChecks
- `Dockerfile` (Multi-Stage: base, deps, development, build, production)
- `nest-cli.json` Konfiguration
**Implementierte Module:**
1. **Auth-Modul** (`src/core/auth/`)
- `AuthService`: Login (E-Mail/Passwort), Token-Refresh, Logout, Token-Revocation
- `AuthController`: POST /login, /refresh, /logout
- `JwtStrategy`: RS256 Passport-Strategy
- `TotpService`: TOTP 2FA (Google Authenticator kompatibel)
- `LoginDto`: Validierung mit class-validator
- Account-Lockout nach 5 Fehlversuchen (15 Min Sperre)
- Refresh-Token als HttpOnly Cookie (secure/sameSite umgebungsabhaengig)
- Token-Rotation mit Redis-basierter Familien-Erkennung
2. **Users-Modul** (`src/core/users/`)
- `UsersService`: CRUD, Bcrypt Cost 12, Passwort-Hashing
- `UsersController`: GET /me, GET /users, POST /users, PATCH /users/:id
- DTOs: CreateUserDto, UpdateUserDto
- Paginierung mit Meta-Informationen
3. **Tenants-Modul** (`src/core/tenants/`)
- `TenantsService`: CRUD, Member-Management
- `TenantsController`: CRUD + POST /:id/members, DELETE /:id/members/:userId
- DTOs: CreateTenantDto, UpdateTenantDto, AddMemberDto
- Slug-Validierung (URL-freundlich)
4. **Infrastruktur-Module:**
- `PrismaService`: PostgreSQL-Verbindung (platform_core)
- `TenantPrismaService`: Dynamische Tenant-DB-Verbindungen mit Caching
- `RedisService`: Token-Blocklist, Refresh-Token-Familien, generischer Cache
- `HealthController`: GET /health (DB + Redis Status)
5. **Common (Guards, Decorators, Filter):**
- `@Public()` Decorator fuer oeffentliche Routen
- `@Roles()` Decorator fuer rollenbasierte Zugriffskontrolle
- `@CurrentUser()` Decorator fuer User-Extraktion aus JWT
- `JwtAuthGuard` (global) mit Token-Revocation-Check
- `RolesGuard` fuer Rollen-Pruefung
- `GlobalExceptionFilter` fuer strukturierte Fehlerantworten
6. **Config:**
- `validateConfig()` mit class-validator fuer Umgebungsvariablen
#### 6. Prisma-Schemas & Migration
1. **`core.schema.prisma`** (platform_core Datenbank):
- `User` - Plattform-Benutzer (mit Login-Tracking, 2FA)
- `AuthProvider` - Multi-Provider Auth (LOCAL, MS_SSO, M2M)
- `Tenant` - Mandanten mit JSON-Settings
- `TenantMembership` - User-Tenant-Zuordnung (M:N)
- `Module` - Verfuegbare Plattform-Module
- `TenantModule` - Module pro Tenant
- `AuditLog` - Plattform-weites Audit-Log
2. **`tenant.schema.prisma`** (tenant_{slug} Datenbanken):
- `Contact` - CRM-Kontakte (Person/Organisation)
- `Activity` - CRM-Aktivitaeten (Notiz, Anruf, E-Mail, Meeting, Task)
- Referenz-Schema fuer Sprint 2 (CRM-Modul)
3. **Erste Migration erstellt** (`prisma/migrations/20260308000000_init/`)
- 7 Tabellen, alle Indizes und Foreign Keys
- `migration_lock.toml` fuer Prisma
4. **Seed-Script erstellt** (`prisma/seed.ts`)
- Erstellt Platform-Admin: `admin@xinion.de` / `ChangeMe123!`
- Bcrypt Cost 12, Rolle: PLATFORM_ADMIN
#### 7. React Frontend-Shell
**Projekt-Setup:**
- `package.json` mit React 18, Vite 6, React Router 6, TanStack Query 5, Axios
- `tsconfig.json` mit strict TypeScript
- `vite.config.ts` mit API-Proxy und Path-Aliases
- `Dockerfile` (Multi-Stage: development mit Vite, production mit Nginx)
- `nginx.conf` (SPA-Routing, Security-Headers, Caching)
**Implementierte Komponenten:**
1. **Auth-System** (`src/auth/`)
- `AuthContext` + `useAuth()` Hook: Login, Logout, Silent Refresh
- `LoginPage`: E-Mail/Passwort + optionaler TOTP 2FA-Code
- Access-Token NUR im Memory (kein localStorage!)
- Automatischer Silent Refresh via HttpOnly Cookie
2. **API-Client** (`src/api/client.ts`)
- Axios-Instanz mit automatischem Token-Handling
- Request-Interceptor fuer Authorization-Header
- Response-Interceptor fuer automatisches Token-Refresh bei 401
3. **App-Shell** (`src/shell/`)
- `App`: React Router mit PrivateRoute-Guard
- `AppLayout`: Sidebar-Navigation + Outlet
- `DashboardPage`: Willkommens-Seite
4. **Admin-Bereich** (`src/admin/`)
- `AdminUsersPage`: Benutzer-Tabelle mit Paginierung
- `AdminTenantsPage`: Mandanten-Tabelle mit Member-Count
5. **Styling:**
- CSS Custom Properties (Farben, Layout, Schatten, Radien)
- CSS Modules fuer komponentenspezifische Styles
- Responsive Sidebar-Layout
#### 8. CI/CD Pipelines
1. **`.forgejo/workflows/ci.yml`** - Continuous Integration:
- Trigger: Push auf alle Branches + Pull Requests
- Core-Service: npm ci, Prisma Generate, Lint, Type-Check, Test, Build
- Frontend: npm ci, Lint, Type-Check, Build
2. **`.forgejo/workflows/deploy.yml`** - Deployment:
- Trigger: Push auf main/develop
- Build Docker-Images (Core + Frontend)
- Push in Forgejo Container Registry
- SSH-Deploy auf insight-dev-01
- Health-Check Verifizierung
#### 9. IP-basierte Deployment-Anpassung (HTTP statt HTTPS)
**Grund:** Kein DNS-Eintrag vorhanden, Zugriff nur ueber IP 172.20.10.59.
**Geaenderte Dateien:**
1. **`auth.controller.ts`** - Cookie secure/sameSite umgebungsabhaengig
- `secure: true` -> `secure: process.env.NODE_ENV === 'production'`
- `sameSite: 'strict'` -> `isProduction ? 'strict' : 'lax'`
- Betrifft `setRefreshTokenCookie()` und `logout()`
2. **`docker-compose.yml`** - HTTP + IP Umstellung
- HTTPS-Redirect entfernt
- TLS-Entrypoint deaktiviert, Port 443 entfernt
- Alle Host-Rules: `insight-dev.xinion.lan` -> `172.20.10.59`
- Alle Entrypoints: `websecure` -> `web`
- URL-Defaults auf `http://172.20.10.59`
- PostgreSQL Memory reduziert (1GB/4GB/256MB fuer 8GB RAM VM)
- JWT-Keys Volume-Mount hinzugefuegt: `./keys:/app/keys:ro`
3. **`config/traefik/dynamic/tls.yml`** - TLS-Konfiguration deaktiviert
4. **`config/traefik/dynamic/middlewares.yml`**
- HSTS-Headers entfernt
- CSP: `wss://insight-dev.xinion.lan` -> `ws://172.20.10.59`
- CORS: `https://insight-dev.xinion.lan` -> `http://172.20.10.59`
5. **`main.ts`** - CORS-Fallback auf `http://172.20.10.59`
6. **`env.validation.ts`** - APP_URL Default auf `http://172.20.10.59`
7. **`.env.example`** - Alle URLs auf `http://172.20.10.59`
8. **`package-lock.json`** - Generiert fuer core-service und frontend (npm ci braucht diese)
9. **Dokumentation aktualisiert:**
- `docs/INFRASTRUCTURE.md` - HTTP statt HTTPS, IP statt DNS
- `docs/ACCESS.md` - Ports, URLs, Default-Zugangsdaten
- `README.md` - Setup-Anleitung, URLs, Seed-Befehle
---
### Naechste Schritte
- [x] SSH Deploy Keys auf insight-dev-01 Server hinterlegen
- [x] `docker-compose.yml` erstellen (alle Basis-Services)
- [x] `docker-compose.observability.yml` erstellen
- [x] NestJS Core-Service implementieren (Auth, Users, Tenants)
- [x] Prisma-Schemas erstellen (core + tenant)
- [x] React Frontend-Shell implementieren
- [x] CI/CD Pipelines (.forgejo/workflows/) definieren
- [x] Codebase auf HTTP + IP (172.20.10.59) umstellen
- [x] Seed-Script erstellen (admin@xinion.de)
- [x] Prisma-Migration erstellen (init)
- [x] package-lock.json generieren
- [x] Dokumentation aktualisieren
- [ ] Commit & Push auf develop
- [ ] LVM-Festplatte auf Server erweitern (60GB -> voll nutzbar)
- [ ] Docker + Docker Compose auf insight-dev-01 installieren
- [ ] Repo klonen, .env + JWT-Keys auf Server erstellen
- [ ] Services starten, Migration + Seed ausfuehren
- [ ] Erster End-to-End Test (Login -> Dashboard)
---
### Offene Fragen / Abhaengigkeiten
- DNS-Eintrag `insight-dev.xinion.lan` wird spaeter eingerichtet (dann HTTPS aktivieren)
- LVM auf Server muss erweitert werden (60GB Disk, nur ~56GB sichtbar)