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

460 lines
12 KiB
Markdown

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