INSIGHT-MVP/packages/crm-service/Summarize.md
Thomas Reitz 9d496d2e53 feat(crm): integrate Lexware Office for vouchers and contact sync
Adds complete Lexware Office integration to CRM service:
- Rate-limited HTTP client (Token Bucket, 2 req/s)
- Bidirectional contact sync (manual import + ERP-push)
- Voucher caching (quotes, orders, invoices, credit notes)
- Deal-voucher linking (m:n join table with audit)
- Cron jobs: voucher refresh (4h), ERP push (30min)
- Distributed locks via Redis for job deduplication
- Health check extended with Lexware status
- Prisma schema: LexwareVoucher, DealVoucher, VoucherType enum
- Companies/Contacts/Deals services extended with Lexware data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:28:41 +01:00

7.9 KiB

CRM-Service - Zusammenfassung

Stand: 2026-03-10

Was wurde erstellt

Der CRM-Service als eigenstaendiges NestJS-Package unter packages/crm-service/.

Struktur

packages/crm-service/
  package.json          — Dependencies (NestJS 10, Prisma, Passport, ioredis, @nestjs/axios, @nestjs/schedule)
  tsconfig.json         — Strict TypeScript
  nest-cli.json         — NestJS CLI Config
  Dockerfile            — Multi-Stage (base, deps, development, build, production)
  .dockerignore         — Excludes
  prisma/
    crm.schema.prisma   — Eigenes Schema (app_crm) mit eigenem Client-Output
    migrations/         — SQL-Migrationen
  src/
    main.ts             — Bootstrap (Port 3100, Prefix: api/v1/crm, Swagger)
    app.module.ts       — Root Module mit globalem JwtAuthGuard + ExceptionFilter + ScheduleModule
    config/             — Umgebungsvariablen-Validierung (inkl. LEXWARE_*)
    prisma/             — CrmPrismaService (eigener Client)
    redis/              — RedisService (Token-Blocklist, Cache, Distributed Locks)
    auth/               — JWT Strategy (RS256), JwtAuthGuard, RolesGuard, TenantGuard
    common/             — Decorators (@Public, @Roles, @CurrentUser), Pagination, ExceptionFilter
    companies/          — CRUD: Unternehmen (mit Lexware ERP-Push bei Update)
    contacts/           — CRUD: Kontakte (mit Lexware ERP-Push bei Update)
    activities/         — CRUD: Aktivitaeten (NOTE, CALL, EMAIL, MEETING, TASK)
    pipelines/          — CRUD: Sales-Pipelines mit Stages (inkl. Stage-Update)
    deals/              — CRUD: Vorgaenge mit Pipeline/Stage/Contact/Company + DealVouchers
    health/             — Health-Check (DB, Redis, Lexware)
    lexware/            — Lexware Office Integration (NEU)
      lexware.module.ts              — Feature Module (HttpModule + ScheduleModule)
      lexware-client.service.ts      — Rate-limitierter HTTP Client (Token Bucket, 2 req/s)
      lexware-contacts.service.ts    — Kontakt-Suche, Link, Import, Push, Sync
      lexware-vouchers.service.ts    — Beleg-Abruf, Cache, Deal-Verknuepfung
      lexware-sync.service.ts        — Cron-Jobs (Beleg-Sync 4h, ERP-Push 30min)
      lexware-contacts.controller.ts — REST Endpoints Kontakt-Operationen
      lexware-vouchers.controller.ts — REST Endpoints Beleg-Operationen
      dto/                           — Validierungs-DTOs
      interfaces/                    — TypeScript Interfaces fuer Lexware API
      utils/
        rate-limiter.ts              — Token Bucket (max 2, 2/s Refill)
        lexware-mapper.ts            — Bidirektionales Mapping CRM <-> Lexware

Datenbank-Modelle (app_crm Schema)

  • Company — Unternehmen mit Lexware-Verknuepfung (lexwareContactId, lexwareContactVersion, lexwareSyncedAt)
  • Contact — Kontakte mit optionaler Lexware-Verknuepfung
  • Activity — Aktivitaeten verknuepft mit Kontakten
  • Pipeline — Konfigurierbare Sales-Pipelines pro Tenant
  • PipelineStage — Stufen innerhalb einer Pipeline
  • Deal — Vorgaenge mit dealVouchers-Relation zu Lexware-Belegen
  • LexwareVoucher (NEU) — Gecachte Belege aus Lexware Office (Angebote, Auftraege, Rechnungen, Gutschriften)
  • DealVoucher (NEU) — Join-Table Deal <-> Beleg (m:n mit Audit-Trail)

Entity-Beziehungen

Company (1) --< (n) Contact          — companyId (optional, SetNull)
Company (1) --< (n) Deal             — companyId (optional, SetNull)
Company (1) --< (n) LexwareVoucher   — companyId (optional, SetNull)
Contact (1) --< (n) Activity         — contactId (Cascade)
Contact (1) --< (n) Deal             — contactId (optional, SetNull)
Contact (1) --< (n) LexwareVoucher   — contactId (optional, SetNull)
Pipeline (1) --< (n) PipelineStage   — pipelineId (Cascade)
Pipeline (1) --< (n) Deal            — pipelineId (Cascade)
PipelineStage (1) --< (n) Deal       — stageId
Deal (1) --< (n) DealVoucher         — dealId (Cascade)
LexwareVoucher (1) --< (n) DealVoucher — voucherId (Cascade)

API-Endpunkte

Methode Pfad Beschreibung
GET/POST /api/v1/crm/companies Liste / Erstellen
GET/PATCH/DELETE /api/v1/crm/companies/:id Detail / Update / Delete
GET/POST /api/v1/crm/contacts Liste / Erstellen
GET/PATCH/DELETE /api/v1/crm/contacts/:id Detail / Update / Delete
GET/POST /api/v1/crm/activities Liste / Erstellen
GET/PATCH/DELETE /api/v1/crm/activities/:id Detail / Update / Delete
GET/POST /api/v1/crm/pipelines Liste / Erstellen
GET/PATCH/DELETE /api/v1/crm/pipelines/:id Detail / Update / Delete
POST/DELETE /api/v1/crm/pipelines/:id/stages Stage hinzufuegen/entfernen
PATCH /api/v1/crm/pipelines/:id/stages/:stageId Stage bearbeiten
GET/POST /api/v1/crm/deals Liste / Erstellen
GET/PATCH/DELETE /api/v1/crm/deals/:id Detail / Update / Delete
GET /health Health-Check (DB, Redis, Lexware)
Lexware Kontakte
GET /api/v1/crm/lexware/contacts/search Lexware-Kontakte suchen
POST /api/v1/crm/lexware/contacts/link-company Company verknuepfen
POST /api/v1/crm/lexware/contacts/link-contact Contact verknuepfen
DELETE /api/v1/crm/lexware/contacts/unlink-company/:id Verknuepfung loesen
DELETE /api/v1/crm/lexware/contacts/unlink-contact/:id Verknuepfung loesen
POST /api/v1/crm/lexware/contacts/import-company Company aus Lexware importieren
POST /api/v1/crm/lexware/contacts/import-contact Contact aus Lexware importieren
POST /api/v1/crm/lexware/contacts/push/:type/:id CRM -> Lexware pushen
POST /api/v1/crm/lexware/contacts/sync/:type/:id Lexware -> CRM synchronisieren
Lexware Belege
GET /api/v1/crm/lexware/vouchers/company/:id Belege fuer Unternehmen
GET /api/v1/crm/lexware/vouchers/contact/:id Belege fuer Kontakt
GET /api/v1/crm/lexware/vouchers/deal/:id Belege fuer Vorgang
POST /api/v1/crm/lexware/vouchers/deal/:id/link Beleg mit Vorgang verknuepfen
DELETE /api/v1/crm/lexware/vouchers/deal/:id/unlink/:vid Verknuepfung loesen
POST /api/v1/crm/lexware/vouchers/refresh/company/:id Cache aktualisieren
POST /api/v1/crm/lexware/vouchers/refresh/contact/:id Cache aktualisieren

Lexware Office Integration — Details

  • Rate Limiter: In-Memory Token Bucket, 2 Requests/Sekunde (Lexware API Limit)
  • Beleg-Caching: PostgreSQL-Tabelle lexware_vouchers, alle 4h Cron-Refresh + manueller Refresh
  • ERP-Push: Companies/Contacts mit Tag "ERP" werden automatisch (30min Cron) + bei Update nach Lexware gepusht
  • Distributed Locks: Redis SET NX EX verhindert Doppelausfuehrung von Cron-Jobs
  • Optimistic Locking: lexwareContactVersion fuer sichere Updates
  • Graceful Degradation: Ohne LEXWARE_API_KEY → Modul deaktiviert, Health = "unconfigured"

Docker-Integration

  • docker-compose.crm.yml im Projekt-Root
  • Port: 3100
  • Neue Env-Variablen: LEXWARE_API_KEY, LEXWARE_API_URL
  • Traefik HTTP + HTTPS Routing: /api/v1/crm/*

Sicherheit

  • JWT RS256 Validierung mit shared Public Key
  • Token-Revocation via Redis
  • Multi-Tenancy: Alle Queries filtern nach tenantId
  • Globaler ValidationPipe (whitelist + forbidNonWhitelisted)
  • Strict TypeScript, kein any

Deployment-Status

Erfolgreich deployed auf insight-dev-01 (172.20.10.59) am 2026-03-10

  • Prisma Migrationen:
    • 20260310163211_init — Initiales Schema
    • 20260310183117_add_companies — Company-Entity
    • 20260310_add_lexware_integration — Lexware Office Integration (AUSSTEHEND)

Naechste Schritte

  1. Migration 20260310_add_lexware_integration auf Server anwenden
  2. LEXWARE_API_KEY in .env auf Server setzen
  3. Container neu bauen und deployen
  4. Lexware-Endpunkte auf Server testen
  5. Frontend: Lexware-Integration in Company/Contact/Deal-Detail-Seiten
  6. Activity-Liste komplett laden (UI-Button "Alle anzeigen")
  7. Kanban-Board fuer Vorgaenge