mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 00:16:41 +02:00
docs: add CRM service handoff document for new dev session
Comprehensive briefing for a new Claude Code chat to build the CRM container service, including: protected paths, architecture overview, JWT validation, database schema conventions, Docker integration, multi-tenancy rules, and quick-start guide. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
15ea7627e8
commit
b18fe9376c
1 changed files with 505 additions and 0 deletions
505
docs/CRM_HANDOFF.md
Normal file
505
docs/CRM_HANDOFF.md
Normal file
|
|
@ -0,0 +1,505 @@
|
||||||
|
# CRM-Service Handoff — Briefing fuer neuen Claude Code Chat
|
||||||
|
|
||||||
|
> **Zweck:** Dieses Dokument enthaelt alle technischen Informationen, damit ein
|
||||||
|
> neuer Claude Code Chat den CRM-Service im Monorepo entwickeln kann, ohne
|
||||||
|
> bestehende Funktionalitaet zu beschaedigen.
|
||||||
|
>
|
||||||
|
> **Stand:** 2026-03-10 | **Basis:** INSIGHT MVP v1.0.0-alpha
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Dein Auftrag
|
||||||
|
|
||||||
|
Entwickle den CRM-Service als eigenstaendiges Package unter
|
||||||
|
`packages/crm-service/` im bestehenden Monorepo. Der Service ist ein
|
||||||
|
NestJS-Backend, das als eigener Docker-Container laeuft und sich in die
|
||||||
|
INSIGHT-Plattform integriert.
|
||||||
|
|
||||||
|
**Lese zuerst:** `docs/INTEGRATION.md` — dort steht, wie Container-Apps
|
||||||
|
sich in die Plattform integrieren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Was du NICHT anfassen darfst
|
||||||
|
|
||||||
|
> **KRITISCH:** Diese Dateien/Verzeichnisse gehoeren dem Core-Service.
|
||||||
|
> Aenderungen daran koennen die gesamte Plattform zerstoeren.
|
||||||
|
|
||||||
|
| Pfad | Grund |
|
||||||
|
|------|-------|
|
||||||
|
| `packages/core-service/**` | Bestehender Backend-Service (Auth, Users, Tenants) |
|
||||||
|
| `packages/frontend/**` | Bestehende React-App (wird spaeter separat erweitert) |
|
||||||
|
| `config/traefik/**` | Traefik-Konfiguration (nur lesen, nicht aendern) |
|
||||||
|
| `.forgejo/workflows/**` | CI/CD Pipeline (wird spaeter fuer CRM erweitert) |
|
||||||
|
| `docker-compose.yml` | Haupt-Compose (nur lesen — du erstellst ein Override) |
|
||||||
|
| `.keys/**` | JWT-Schluessel und SSH-Keys |
|
||||||
|
| `prisma/core.schema.prisma` | Core-Datenbank-Schema |
|
||||||
|
|
||||||
|
**Ausnahmen:** Du darfst folgende Dateien ergaenzen (nicht ueberschreiben):
|
||||||
|
- `.env.example` — Neue CRM-spezifische Variablen **anhaengen**
|
||||||
|
- `docs/` — Eigene Dokumentation hinzufuegen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Verzeichnisstruktur (Ziel)
|
||||||
|
|
||||||
|
```
|
||||||
|
INSIGHT-MVP/
|
||||||
|
├── packages/
|
||||||
|
│ ├── core-service/ ← NICHT ANFASSEN
|
||||||
|
│ ├── frontend/ ← NICHT ANFASSEN
|
||||||
|
│ └── crm-service/ ← DEIN BEREICH
|
||||||
|
│ ├── Dockerfile
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── nest-cli.json
|
||||||
|
│ ├── .dockerignore
|
||||||
|
│ ├── prisma/
|
||||||
|
│ │ └── crm.schema.prisma ← Eigenes Schema!
|
||||||
|
│ └── src/
|
||||||
|
│ ├── main.ts
|
||||||
|
│ ├── app.module.ts
|
||||||
|
│ ├── config/
|
||||||
|
│ ├── contacts/
|
||||||
|
│ ├── activities/
|
||||||
|
│ ├── pipelines/
|
||||||
|
│ └── ...
|
||||||
|
├── docker-compose.crm.yml ← Docker Override fuer CRM
|
||||||
|
└── docs/
|
||||||
|
└── CRM_HANDOFF.md ← Diese Datei
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Bestehende Architektur (Referenz)
|
||||||
|
|
||||||
|
### 4.1 Docker-Netzwerke
|
||||||
|
|
||||||
|
| Netzwerk | Typ | Dein Zugriff |
|
||||||
|
|----------|-----|-------------|
|
||||||
|
| `insight-web` | bridge | **JA** — Pflicht fuer Traefik-Routing |
|
||||||
|
| `insight-db` | internal | **JA** — Fuer Datenbankzugriff |
|
||||||
|
| `insight-cache` | internal | **JA** — Fuer Redis-Zugriff |
|
||||||
|
|
||||||
|
### 4.2 Verfuegbare Infrastruktur-Services
|
||||||
|
|
||||||
|
| Service | Hostname (Docker) | Port | Zugriff |
|
||||||
|
|---------|-------------------|------|---------|
|
||||||
|
| PostgreSQL | `postgres` | 5432 | Direkt (nur Migrationen) |
|
||||||
|
| PgBouncer | `pgbouncer` | 6432 | Pooled (Runtime) |
|
||||||
|
| Redis | `redis` | 6379 | Cache + Events |
|
||||||
|
| Core-API | `core` | 3000 | REST-Aufrufe |
|
||||||
|
| Traefik | `traefik` | 80 | Gateway |
|
||||||
|
|
||||||
|
### 4.3 Datenbank-Verbindung
|
||||||
|
|
||||||
|
```
|
||||||
|
# Runtime (via PgBouncer — Connection Pooling)
|
||||||
|
DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@pgbouncer:6432/${DB_NAME}
|
||||||
|
|
||||||
|
# Migrationen (direkt — PgBouncer unterstuetzt kein DDL)
|
||||||
|
DATABASE_URL_DIRECT=postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **DB_USER:** `insight` (Standard)
|
||||||
|
- **DB_NAME:** `platform_core` (gemeinsame DB)
|
||||||
|
- **Dein Schema:** `app_crm` (eigenes Schema innerhalb der gleichen DB)
|
||||||
|
- **Pool-Mode:** `transaction` (kein `LISTEN/NOTIFY`, kein `SET`)
|
||||||
|
|
||||||
|
### 4.4 Redis
|
||||||
|
|
||||||
|
```
|
||||||
|
Host: redis
|
||||||
|
Port: 6379
|
||||||
|
Passwort: optional (${REDIS_PASSWORD})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key-Prefix fuer CRM:** `app:crm:*`
|
||||||
|
|
||||||
|
Bereits belegte Prefixes (NICHT verwenden):
|
||||||
|
- `blocked_token:*` — Token-Revocation
|
||||||
|
- `platform_*` — Core-Settings
|
||||||
|
- `favicon:*` — Favicon-Cache
|
||||||
|
- `sso:state:*` — SSO CSRF
|
||||||
|
- `refresh_token_family:*` — Token-Rotation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Authentifizierung & Autorisierung
|
||||||
|
|
||||||
|
### 5.1 JWT-Token-Architektur
|
||||||
|
|
||||||
|
Der CRM-Service empfaengt Requests mit einem `Authorization: Bearer <token>`
|
||||||
|
Header. Der Token wurde vom Core-Service ausgestellt (RS256).
|
||||||
|
|
||||||
|
**JWT-Payload:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"sub": "user-uuid",
|
||||||
|
"email": "user@example.com",
|
||||||
|
"role": "USER | TENANT_ADMIN | PLATFORM_ADMIN",
|
||||||
|
"tenantId": "tenant-uuid",
|
||||||
|
"tenantSlug": "tenant_acme",
|
||||||
|
"jti": "unique-token-id",
|
||||||
|
"iat": 1710000000,
|
||||||
|
"exp": 1710000900
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Token-Validierung implementieren
|
||||||
|
|
||||||
|
Du brauchst den oeffentlichen JWT-Schluessel:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# In docker-compose.crm.yml
|
||||||
|
volumes:
|
||||||
|
- ./keys/jwt-public.pem:/app/keys/jwt-public.pem:ro
|
||||||
|
```
|
||||||
|
|
||||||
|
**NestJS-Implementierung:**
|
||||||
|
```typescript
|
||||||
|
// Passport JWT Strategy (wie im Core-Service)
|
||||||
|
// Algorithmus: RS256
|
||||||
|
// Public Key: aus /app/keys/jwt-public.pem
|
||||||
|
// Header: Authorization: Bearer <token>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional — Token-Revocation pruefen:**
|
||||||
|
```typescript
|
||||||
|
// Redis-Key: blocked_token:{jti}
|
||||||
|
// Wenn vorhanden → Token ist gesperrt → 401
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Rollen
|
||||||
|
|
||||||
|
| Rolle | CRM-Zugriff |
|
||||||
|
|-------|-------------|
|
||||||
|
| `PLATFORM_ADMIN` | Voller Zugriff auf alle Mandanten |
|
||||||
|
| `TENANT_ADMIN` | Voller Zugriff auf eigenen Mandanten |
|
||||||
|
| `USER` | Lese-/Schreibzugriff auf eigene Daten |
|
||||||
|
|
||||||
|
### 5.4 Multi-Tenancy
|
||||||
|
|
||||||
|
**Jeder CRM-Request muss mandanten-bezogen sein!**
|
||||||
|
|
||||||
|
Der `tenantId` kommt aus dem JWT-Payload. Alle Datenbankabfragen muessen
|
||||||
|
nach `tenantId` gefiltert werden:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- IMMER so:
|
||||||
|
SELECT * FROM app_crm.contacts WHERE tenant_id = :tenantId;
|
||||||
|
|
||||||
|
-- NIEMALS so:
|
||||||
|
SELECT * FROM app_crm.contacts; -- Datenleck!
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Datenbank-Schema (Empfehlung)
|
||||||
|
|
||||||
|
Verwende ein eigenes Prisma-Schema unter `packages/crm-service/prisma/crm.schema.prisma`.
|
||||||
|
|
||||||
|
**Schema-Name:** `app_crm`
|
||||||
|
|
||||||
|
```prisma
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
output = "../node_modules/.prisma/crm-client"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
directUrl = env("DATABASE_URL_DIRECT")
|
||||||
|
schemas = ["app_crm"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtig:**
|
||||||
|
- Eigener Prisma-Client-Output (`crm-client`), damit kein Konflikt mit dem Core-Client
|
||||||
|
- Eigenes Schema `app_crm` — keine Tabellen im `public` Schema anlegen
|
||||||
|
- `tenantId` als Pflichtfeld in jeder Tabelle (Multi-Tenancy)
|
||||||
|
- `createdBy` / `updatedBy` als UUID fuer Audit-Trail (User-IDs aus Core)
|
||||||
|
|
||||||
|
### 6.1 Referenz: Bestehende Tenant-Schema-Entwuerfe
|
||||||
|
|
||||||
|
Im Core-Service existiert bereits ein Entwurf unter
|
||||||
|
`packages/core-service/prisma/tenant.schema.prisma` mit Modellen fuer
|
||||||
|
`Contact` und `Activity`. Diese dienen als Referenz — du kannst sie
|
||||||
|
uebernehmen oder anpassen.
|
||||||
|
|
||||||
|
**Contact-Modell (Referenz):**
|
||||||
|
- Typen: PERSON, ORGANIZATION
|
||||||
|
- Felder: Name, Firma, Kontaktdaten, Adresse, Tags, Notizen
|
||||||
|
- Tracking: `createdBy`, `updatedBy` (User-UUIDs)
|
||||||
|
|
||||||
|
**Activity-Modell (Referenz):**
|
||||||
|
- Typen: NOTE, CALL, EMAIL, MEETING, TASK
|
||||||
|
- Felder: Subject, Beschreibung, Zeitplanung, Status
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Docker-Integration
|
||||||
|
|
||||||
|
### 7.1 docker-compose.crm.yml (Beispiel)
|
||||||
|
|
||||||
|
Erstelle diese Datei im Projekt-Root:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.crm.yml
|
||||||
|
# Start: docker compose -f docker-compose.yml -f docker-compose.crm.yml up -d
|
||||||
|
|
||||||
|
services:
|
||||||
|
crm:
|
||||||
|
build:
|
||||||
|
context: ./packages/crm-service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
target: development
|
||||||
|
container_name: insight-crm
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=${NODE_ENV:-development}
|
||||||
|
- APP_PORT=3100
|
||||||
|
- DATABASE_URL=postgresql://${DB_USER:-insight}:${DB_PASSWORD}@pgbouncer:6432/${DB_NAME:-platform_core}?schema=app_crm
|
||||||
|
- DATABASE_URL_DIRECT=postgresql://${DB_USER:-insight}:${DB_PASSWORD}@postgres:5432/${DB_NAME:-platform_core}?schema=app_crm
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
||||||
|
- JWT_PUBLIC_KEY_PATH=/app/keys/jwt-public.pem
|
||||||
|
volumes:
|
||||||
|
- ./packages/crm-service:/app
|
||||||
|
- /app/node_modules
|
||||||
|
- ./.keys/jwt-public.pem:/app/keys/jwt-public.pem:ro
|
||||||
|
networks:
|
||||||
|
- insight-web
|
||||||
|
- insight-db
|
||||||
|
- insight-cache
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.crm.rule=PathPrefix(`/api/v1/crm`)"
|
||||||
|
- "traefik.http.routers.crm.entrypoints=web"
|
||||||
|
- "traefik.http.services.crm.loadbalancer.server.port=3100"
|
||||||
|
- "traefik.http.routers.crm.middlewares=cors-headers@file,security-headers@file"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3100/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 15s
|
||||||
|
depends_on:
|
||||||
|
pgbouncer:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
insight-web:
|
||||||
|
external: true
|
||||||
|
insight-db:
|
||||||
|
external: true
|
||||||
|
insight-cache:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 Traefik-Route
|
||||||
|
|
||||||
|
| Route-Prefix | Service | Port |
|
||||||
|
|-------------|---------|------|
|
||||||
|
| `/api/v1/crm/*` | crm | 3100 |
|
||||||
|
|
||||||
|
**Bereits belegte Routen:**
|
||||||
|
- `/api/*` → core-service:3000
|
||||||
|
- `/health` → core-service:3000
|
||||||
|
- `/*` → frontend:8080 (Catch-all, Priority 1)
|
||||||
|
|
||||||
|
**Wichtig:** Die CRM-Route `/api/v1/crm` hat hoehere Prioritaet als der
|
||||||
|
Core-Catch-all `/api`, weil sie spezifischer ist. Traefik matched die
|
||||||
|
laengste Prefix-Uebereinstimmung zuerst.
|
||||||
|
|
||||||
|
### 7.3 Port-Konvention
|
||||||
|
|
||||||
|
| Service | Port |
|
||||||
|
|---------|------|
|
||||||
|
| Core-Service | 3000 |
|
||||||
|
| CRM-Service | **3100** |
|
||||||
|
| Frontend | 8080 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. NestJS-Konfiguration (Orientierung am Core-Service)
|
||||||
|
|
||||||
|
### 8.1 Tech-Stack (identisch zum Core)
|
||||||
|
|
||||||
|
| Komponente | Version | Zweck |
|
||||||
|
|-----------|---------|-------|
|
||||||
|
| NestJS | >= 10 | Framework |
|
||||||
|
| TypeScript | strict | Sprache |
|
||||||
|
| Prisma | >= 6 | ORM |
|
||||||
|
| ioredis | >= 5 | Redis-Client |
|
||||||
|
| passport-jwt | latest | JWT-Validierung |
|
||||||
|
| class-validator | latest | DTO-Validierung |
|
||||||
|
| class-transformer | latest | Typ-Transformation |
|
||||||
|
|
||||||
|
### 8.2 main.ts Konfiguration (kopiere das Pattern)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Wichtige Einstellungen (gleich wie Core):
|
||||||
|
// - helmet() fuer Security-Headers
|
||||||
|
// - cookieParser() fuer Cookies
|
||||||
|
// - JSON Body Limit: 12MB
|
||||||
|
// - Global Prefix: api/v1/crm (ACHTUNG: nicht api/v1 — das ist der Core!)
|
||||||
|
// - Global ValidationPipe (whitelist, forbidNonWhitelisted, transform)
|
||||||
|
// - CORS mit credentials: true
|
||||||
|
// - Port: 3100
|
||||||
|
```
|
||||||
|
|
||||||
|
**ACHTUNG beim Global Prefix:**
|
||||||
|
```typescript
|
||||||
|
// RICHTIG:
|
||||||
|
app.setGlobalPrefix('api/v1/crm', { exclude: ['/health'] });
|
||||||
|
|
||||||
|
// FALSCH (wuerde Core-Routes ueberlagern):
|
||||||
|
app.setGlobalPrefix('api/v1');
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.3 Swagger
|
||||||
|
|
||||||
|
Stelle Swagger unter `/api/v1/crm/docs` bereit (nur Development).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. CI/CD (spaeter)
|
||||||
|
|
||||||
|
Die CI/CD Pipeline wird **spaeter separat** erweitert. Fokussiere dich
|
||||||
|
auf die Entwicklung. Die Pipeline-Erweiterung beinhaltet:
|
||||||
|
|
||||||
|
1. Neuer CI-Job `crm-service` (analog zu `core-service`)
|
||||||
|
2. Docker-Image: `git.xinion.lan/gitadmin/insight-crm:TAG`
|
||||||
|
3. Deploy-Job erweitert um CRM-Container
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Konventionen
|
||||||
|
|
||||||
|
### 10.1 Git
|
||||||
|
|
||||||
|
- **Branch:** `feature/crm-service` (von `develop` abzweigen)
|
||||||
|
- **Commits:** Conventional Commits mit `feat(crm):`, `fix(crm):`, etc.
|
||||||
|
- **Kein Push auf `main`** — nur ueber Merge von `develop`
|
||||||
|
|
||||||
|
### 10.2 Code-Style
|
||||||
|
|
||||||
|
- **Strict TypeScript** — kein `any`
|
||||||
|
- **ESLint + Prettier** (gleiche Config wie Core)
|
||||||
|
- **DTOs** mit class-validator fuer alle Inputs
|
||||||
|
- **Guards** fuer Authentifizierung und Autorisierung
|
||||||
|
|
||||||
|
### 10.3 Datenbank
|
||||||
|
|
||||||
|
- Schema: `app_crm`
|
||||||
|
- Tabellen-Prefix: keiner (Schema ist schon der Namespace)
|
||||||
|
- Migrations: `npx prisma migrate dev --schema=prisma/crm.schema.prisma`
|
||||||
|
- Seed: `npx ts-node prisma/seed.ts`
|
||||||
|
|
||||||
|
### 10.4 Redis-Keys
|
||||||
|
|
||||||
|
```
|
||||||
|
app:crm:{feature}:{id}
|
||||||
|
```
|
||||||
|
|
||||||
|
Beispiele:
|
||||||
|
```
|
||||||
|
app:crm:pipeline:config:tenant_acme
|
||||||
|
app:crm:cache:contacts:tenant_acme:page1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. API-Design (Empfehlung)
|
||||||
|
|
||||||
|
Alle CRM-Endpunkte unter `/api/v1/crm/`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Kontakte
|
||||||
|
GET /api/v1/crm/contacts — Liste (paginiert, filterbar)
|
||||||
|
POST /api/v1/crm/contacts — Erstellen
|
||||||
|
GET /api/v1/crm/contacts/:id — Detail
|
||||||
|
PATCH /api/v1/crm/contacts/:id — Aktualisieren
|
||||||
|
DELETE /api/v1/crm/contacts/:id — Loeschen
|
||||||
|
|
||||||
|
# Aktivitaeten
|
||||||
|
GET /api/v1/crm/activities — Liste
|
||||||
|
POST /api/v1/crm/activities — Erstellen
|
||||||
|
GET /api/v1/crm/activities/:id — Detail
|
||||||
|
PATCH /api/v1/crm/activities/:id — Aktualisieren
|
||||||
|
DELETE /api/v1/crm/activities/:id — Loeschen
|
||||||
|
|
||||||
|
# Pipelines (Sales-Pipeline)
|
||||||
|
GET /api/v1/crm/pipelines — Liste
|
||||||
|
POST /api/v1/crm/pipelines — Erstellen
|
||||||
|
...
|
||||||
|
|
||||||
|
# Deals
|
||||||
|
GET /api/v1/crm/deals — Liste
|
||||||
|
POST /api/v1/crm/deals — Erstellen
|
||||||
|
...
|
||||||
|
|
||||||
|
# Health
|
||||||
|
GET /health — Health-Check (public)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Zusammenfassung der Regeln
|
||||||
|
|
||||||
|
1. **Arbeite NUR in `packages/crm-service/` und `docker-compose.crm.yml`**
|
||||||
|
2. **Aendere NICHTS am Core-Service, Frontend oder der Infrastruktur**
|
||||||
|
3. **Eigenes Prisma-Schema** mit eigenem Client-Output
|
||||||
|
4. **Eigener Docker-Container** auf Port 3100
|
||||||
|
5. **JWT-Validierung** mit dem shared Public Key (RS256)
|
||||||
|
6. **Multi-Tenancy** — jede Query filtert nach `tenantId` aus dem JWT
|
||||||
|
7. **Redis-Keys** mit Prefix `app:crm:`
|
||||||
|
8. **Git-Branch:** `feature/crm-service` von `develop`
|
||||||
|
9. **Conventional Commits:** `feat(crm):`, `fix(crm):`
|
||||||
|
10. **Strict TypeScript** — kein `any`, volle Validierung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Schnellstart
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Branch erstellen
|
||||||
|
git checkout develop
|
||||||
|
git checkout -b feature/crm-service
|
||||||
|
|
||||||
|
# 2. Package anlegen
|
||||||
|
mkdir -p packages/crm-service
|
||||||
|
cd packages/crm-service
|
||||||
|
npm init -y
|
||||||
|
|
||||||
|
# 3. NestJS installieren
|
||||||
|
npm install @nestjs/common @nestjs/core @nestjs/config @nestjs/platform-express
|
||||||
|
npm install @nestjs/passport @nestjs/jwt passport passport-jwt
|
||||||
|
npm install @prisma/client ioredis class-validator class-transformer
|
||||||
|
npm install helmet cookie-parser
|
||||||
|
npm install -D typescript @types/node @nestjs/cli prisma
|
||||||
|
npm install -D @types/passport-jwt @types/cookie-parser
|
||||||
|
|
||||||
|
# 4. Prisma initialisieren
|
||||||
|
npx prisma init --schema=prisma/crm.schema.prisma
|
||||||
|
|
||||||
|
# 5. Schema erstellen (app_crm)
|
||||||
|
# ... (siehe Abschnitt 6)
|
||||||
|
|
||||||
|
# 6. Migration ausfuehren
|
||||||
|
npx prisma migrate dev --schema=prisma/crm.schema.prisma --name init
|
||||||
|
|
||||||
|
# 7. Entwickeln
|
||||||
|
npm run start:dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **Fuer den neuen Chat:**
|
||||||
|
> Oeffne dieses Dokument zu Beginn mit: *"Lies bitte `docs/CRM_HANDOFF.md`
|
||||||
|
> und `docs/INTEGRATION.md` bevor du mit der Entwicklung startest."*
|
||||||
Loading…
Add table
Reference in a new issue