# Technical Design Document (TDD) # Waldseilgarten Herrenberg CRM **Version:** 1.0 **Datum:** 2026-03-14 **Autor:** AI-Assistent (Henry) **Status:** Entwurf --- ## 1. Executive Summary ### 1.1 Ziel Entwicklung eines modernen CRM- und Projektmanagementsystems für den Waldseilgarten Herrenberg mit Fokus auf: - Kunden- und Kontaktverwaltung - Projekt-Tracking - Dokumentenmanagement - E-Mail-Integration ### 1.2 Tech Stack | Schicht | Technologie | |---------|-------------| | Backend | NestJS (Node.js 22) | | Frontend | React 19 + Vite | | Datenbank | PostgreSQL 18 | | Cache | Redis 7 | | Container | Podman | | Proxy | Traefik | ### 1.3 Architekturprinzipien - **Modularität:** Klare Trennung in Feature-Module - **Type-Safety:** TypeScript durchgehend - **API-First:** REST API als zentrale Schnittstelle - **Containerized:** Vollständig containerisiert --- ## 2. Systemarchitektur ### 2.1 High-Level Architektur ``` ┌─────────────────────────────────────────────────────────────┐ │ Client │ │ (React + Vite) │ └───────────────────────┬─────────────────────────────────────┘ │ HTTPS ┌───────────────────────▼─────────────────────────────────────┐ │ Traefik │ │ (Reverse Proxy + SSL) │ └───────────────────────┬─────────────────────────────────────┘ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Frontend │ │ Backend │ │ Worker │ │ (nginx) │ │ (NestJS) │ │ (IMAP) │ │ :3000 │ │ :3001 │ │ │ └──────────────┘ └──────┬───────┘ └──────────────┘ │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ PostgreSQL │ │ Redis │ │ Local │ │ (DB) │ │ (Cache) │ │ Storage │ │ :5432 │ │ :6379 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ ``` ### 2.2 Backend-Module ``` backend/src/ ├── auth/ # Phase 1: Authentifizierung ├── customers/ # Phase 1: Kundenverwaltung ├── projects/ # Phase 1: Projektmanagement ├── dashboard/ # Phase 1: Statistiken ├── documents/ # Phase 2: Dokumentenverwaltung ├── tasks/ # Phase 3: Aufgabenmanagement ├── email/ # Phase 4: E-Mail-Integration ├── calendar/ # Phase 5: Google Calendar └── common/ # Shared Utilities ``` ### 2.3 Datenbank-Schema (Phase 1) ```sql -- Users CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, first_name VARCHAR(100), last_name VARCHAR(100), role VARCHAR(20) DEFAULT 'user', is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Customers CREATE TABLE customers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), company_name VARCHAR(255) NOT NULL, industry VARCHAR(100), website VARCHAR(255), phone VARCHAR(50), email VARCHAR(255), address TEXT, notes TEXT, tags TEXT[], created_by UUID REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Contacts (Ansprechpartner) CREATE TABLE contacts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), customer_id UUID REFERENCES customers(id) ON DELETE CASCADE, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, email VARCHAR(255), phone VARCHAR(50), position VARCHAR(100), is_primary BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Projects CREATE TABLE projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, customer_id UUID REFERENCES customers(id) ON DELETE SET NULL, status VARCHAR(50) DEFAULT 'new', priority VARCHAR(20) DEFAULT 'medium', start_date DATE, end_date DATE, budget DECIMAL(12,2), created_by UUID REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Project Members CREATE TABLE project_members ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id UUID REFERENCES projects(id) ON DELETE CASCADE, user_id UUID REFERENCES users(id) ON DELETE CASCADE, role VARCHAR(50) DEFAULT 'member', joined_at TIMESTAMP DEFAULT NOW(), UNIQUE(project_id, user_id) ); ``` --- ## 3. API-Design ### 3.1 Authentication ```typescript // POST /api/auth/login interface LoginRequest { email: string; password: string; } interface LoginResponse { access_token: string; user: { id: string; email: string; first_name: string; last_name: string; role: string; }; } // POST /api/auth/register interface RegisterRequest { email: string; password: string; first_name: string; last_name: string; } ``` ### 3.2 Customers ```typescript // GET /api/customers interface ListCustomersQuery { page?: number; limit?: number; search?: string; industry?: string; tags?: string[]; } // POST /api/customers interface CreateCustomerRequest { company_name: string; industry?: string; website?: string; phone?: string; email?: string; address?: string; notes?: string; tags?: string[]; } // GET /api/customers/:id interface CustomerResponse { id: string; company_name: string; industry?: string; website?: string; phone?: string; email?: string; address?: string; notes?: string; tags: string[]; contacts: Contact[]; projects: ProjectSummary[]; created_at: string; updated_at: string; } ``` ### 3.3 Projects ```typescript // POST /api/projects interface CreateProjectRequest { name: string; description?: string; customer_id?: string; status?: 'new' | 'active' | 'on_hold' | 'completed' | 'cancelled'; priority?: 'low' | 'medium' | 'high' | 'urgent'; start_date?: string; end_date?: string; budget?: number; } // GET /api/projects/:id interface ProjectResponse { id: string; name: string; description?: string; customer?: CustomerSummary; status: string; priority: string; start_date?: string; end_date?: string; budget?: number; members: ProjectMember[]; documents_count: number; tasks_count: number; created_at: string; updated_at: string; } ``` --- ## 4. Sicherheit ### 4.1 Authentifizierung - JWT-based Authentication - Access Token: 24h Gültigkeit - Refresh Token: 7 Tage Gültigkeit (optional) - bcrypt für Passwort-Hashing (10 rounds) ### 4.2 Autorisierung - Rollenbasierte Zugriffskontrolle (RBAC) - Rollen: `admin`, `manager`, `user` - Guards auf Controller-Ebene ### 4.3 Datenschutz - HTTPS enforced - SQL Injection Prevention (TypeORM) - XSS Prevention (React escaping) - CSRF Protection --- ## 5. Deployment ### 5.1 Container-Setup ```yaml # docker-compose.yml version: '3.8' services: postgres: image: postgres:18-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - ./data/db:/var/lib/postgresql/data networks: - crm-network redis: image: redis:7-alpine command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - ./data/redis:/data networks: - crm-network backend: build: ./backend environment: NODE_ENV: production POSTGRES_HOST: postgres REDIS_HOST: redis labels: - "traefik.enable=true" - "traefik.http.routers.crm-api.rule=Host(`api.crm.waldseilgarten-herrenberg.de`)" networks: - crm-network frontend: build: ./frontend labels: - "traefik.enable=true" - "traefik.http.routers.crm-frontend.rule=Host(`crm.waldseilgarten-herrenberg.de`)" networks: - crm-network networks: crm-network: driver: bridge ``` ### 5.2 Traefik-Konfiguration ```yaml # traefik/dynamic/crm.yml http: routers: crm-api: rule: "Host(`api.waldseilgarten-herrenberg.de`)" service: crm-api entryPoints: - websecure tls: certResolver: le crm-frontend: rule: "Host(`waldseilgarten-herrenberg.de`)" service: crm-frontend entryPoints: - websecure tls: certResolver: le services: crm-api: loadBalancer: servers: - url: "http://waldseilgarten-backend:3001" crm-frontend: loadBalancer: servers: - url: "http://waldseilgarten-frontend:3000" ``` --- ## 6. Testing ### 6.1 Test-Strategie - **Unit Tests:** Jest für Services - **Integration Tests:** Supertest für API - **E2E Tests:** Playwright für Frontend ### 6.2 Test-Abdeckung - Mindestens 80% für kritische Pfade - Auth-Flows vollständig testen - API-Endpunkte validieren --- ## 7. Monitoring & Logging ### 7.1 Logging - Structured Logging (Winston) - Log-Level: ERROR, WARN, INFO, DEBUG - Request-Logging via Middleware ### 7.2 Health Checks ``` GET /api/health { "status": "healthy", "database": "connected", "cache": "connected", "version": "1.0.0" } ``` --- ## 8. Nicht-funktionale Anforderungen | Anforderung | Ziel | |-------------|------| | Performance | API-Response < 200ms (p95) | | Verfügbarkeit | 99.9% Uptime | | Skalierung | Horizontal skalierbar | | Backup | Tägliche DB-Backups | | Wartung | Zero-Downtime Deployments | --- ## 9. Risiken & Mitigation | Risiko | Wahrscheinlichkeit | Impact | Mitigation | |--------|-------------------|--------|------------| | IMAP-Integration komplex | Hoch | Mittel | Frühes Proof-of-Concept | | SeaDrive-Kompatibilität | Mittel | Mittel | Fallback zu lokalem Storage | | Performance bei vielen Dokumenten | Mittel | Hoch | Pagination, Lazy Loading | | Browser-Kompatibilität | Niedrig | Niedrig | Moderne Browser voraussetzen | --- ## 10. Nächste Schritte 1. **Setup** (Tag 1) - Repository initialisieren - Docker-Compose Setup - Datenbank-Migrations 2. **Phase 1: Auth** (Tag 2-3) - Login/Register API - JWT-Implementation - Frontend Auth-Flow 3. **Phase 1: Kunden** (Tag 4-5) - CRUD API - Frontend Forms - Listen-View 4. **Review** (Tag 6) - Code Review - Testing - Deployment auf Staging --- **Ende des TDD**