Files
Henry 28952b6c5f Initial commit: Waldseilgarten CRM Project Documentation
- README with project overview
- TDD (Technical Design Document)
- AI Council Review with critical analysis
- User Stories (27 stories, 120 SP)
- Architecture documentation

Stack: NestJS + React + PostgreSQL + Redis
Server: waldseilgarten (85.199.86.188)
2026-03-14 14:33:02 +00:00

12 KiB

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)

-- 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

// 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

// 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

// 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

# 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

# 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