- 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)
542 lines
24 KiB
Markdown
542 lines
24 KiB
Markdown
# Systemarchitektur
|
|
# Waldseilgarten Herrenberg CRM
|
|
|
|
**Version:** 1.0
|
|
**Datum:** 2026-03-14
|
|
|
|
---
|
|
|
|
## 1. Architektur-Übersicht
|
|
|
|
Das Waldseilgarten CRM folgt einer **Layered Architecture** mit klaren Trennungen zwischen:
|
|
- **Presentation Layer** (React Frontend)
|
|
- **API Layer** (NestJS Controllers)
|
|
- **Business Layer** (NestJS Services)
|
|
- **Data Layer** (TypeORM + PostgreSQL)
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ PRESENTATION LAYER │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ React │ │ Zustand │ │ TanStack │ │
|
|
│ │ Components │ │ Store │ │ Query │ │
|
|
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
|
|
│ │ │
|
|
│ ▼ HTTPS │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ API LAYER │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ NestJS Controllers │ │
|
|
│ │ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │ │
|
|
│ │ │ Auth │ │ Customers│ │ Projects│ │Documents │ │ │
|
|
│ │ │Controller│ │Controller│ │Controller│ │Controller│ │ │
|
|
│ │ └────┬────┘ └────┬─────┘ └────┬────┘ └────┬─────┘ │ │
|
|
│ └───────┼───────────┼────────────┼───────────┼───────────┘ │
|
|
│ │ │ │ │ │
|
|
│ ▼ ▼ ▼ ▼ │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ BUSINESS LAYER │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ NestJS Services │ │
|
|
│ │ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │ │
|
|
│ │ │ Auth │ │ Customers│ │ Projects│ │Documents │ │ │
|
|
│ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │
|
|
│ │ └────┬────┘ └────┬─────┘ └────┬────┘ └────┬─────┘ │ │
|
|
│ └───────┼───────────┼────────────┼───────────┼───────────┘ │
|
|
│ │ │ │ │ │
|
|
│ ▼ ▼ ▼ ▼ │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ DATA LAYER │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ TypeORM Repository │ │
|
|
│ └─────────────────────────┬───────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ PostgreSQL 18 │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ Redis 7 │ │
|
|
│ │ (Cache / Sessions) │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Backend-Architektur
|
|
|
|
### 2.1 Modulstruktur
|
|
|
|
```
|
|
backend/src/
|
|
├── app.module.ts # Root-Modul
|
|
├── main.ts # Bootstrap
|
|
│
|
|
├── common/ # Shared Resources
|
|
│ ├── decorators/
|
|
│ ├── filters/ # Exception Filters
|
|
│ ├── guards/ # Auth Guards
|
|
│ ├── interceptors/ # Logging, Transform
|
|
│ └── pipes/ # Validation Pipes
|
|
│
|
|
├── config/ # Konfiguration
|
|
│ ├── database.config.ts
|
|
│ ├── app.config.ts
|
|
│ └── redis.config.ts
|
|
│
|
|
├── auth/ # Phase 1
|
|
│ ├── auth.module.ts
|
|
│ ├── auth.controller.ts
|
|
│ ├── auth.service.ts
|
|
│ ├── dto/
|
|
│ │ ├── login.dto.ts
|
|
│ │ └── register.dto.ts
|
|
│ ├── entities/
|
|
│ │ └── user.entity.ts
|
|
│ └── guards/
|
|
│ └── jwt-auth.guard.ts
|
|
│
|
|
├── customers/ # Phase 1
|
|
│ ├── customers.module.ts
|
|
│ ├── customers.controller.ts
|
|
│ ├── customers.service.ts
|
|
│ ├── dto/
|
|
│ │ ├── create-customer.dto.ts
|
|
│ │ └── update-customer.dto.ts
|
|
│ └── entities/
|
|
│ ├── customer.entity.ts
|
|
│ └── contact.entity.ts
|
|
│
|
|
├── projects/ # Phase 1
|
|
│ ├── projects.module.ts
|
|
│ ├── projects.controller.ts
|
|
│ ├── projects.service.ts
|
|
│ ├── dto/
|
|
│ └── entities/
|
|
│ ├── project.entity.ts
|
|
│ └── project-member.entity.ts
|
|
│
|
|
├── documents/ # Phase 2
|
|
│ ├── documents.module.ts
|
|
│ ├── documents.controller.ts
|
|
│ ├── documents.service.ts
|
|
│ ├── storage/
|
|
│ │ ├── local.storage.ts
|
|
│ │ └── seadrive.storage.ts
|
|
│ └── entities/
|
|
│ └── document.entity.ts
|
|
│
|
|
├── tasks/ # Phase 3
|
|
│ ├── tasks.module.ts
|
|
│ ├── tasks.controller.ts
|
|
│ ├── tasks.service.ts
|
|
│ └── entities/
|
|
│ └── task.entity.ts
|
|
│
|
|
└── email/ # Phase 4
|
|
├── email.module.ts
|
|
├── email.controller.ts
|
|
├── email.service.ts
|
|
├── imap/
|
|
│ └── imap.service.ts
|
|
└── entities/
|
|
└── email.entity.ts
|
|
```
|
|
|
|
### 2.2 Request Flow
|
|
|
|
```
|
|
Request
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Traefik │ → SSL-Terminierung, Routing
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Middleware │ → CORS, Helmet, Compression
|
|
│ (Global) │
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Guards │ → JWT Validation
|
|
│ (Optional) │
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Pipes │ → DTO Validation
|
|
│ (Transform) │
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Controller │ → Route Handler
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Service │ → Business Logic
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Repository │ → TypeORM
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ PostgreSQL │
|
|
└─────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Datenbank-Schema
|
|
|
|
### 3.1 Entity Relationship Diagram
|
|
|
|
```
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ users │ │ customers │ │ projects │
|
|
├──────────────┤ ├──────────────┤ ├──────────────┤
|
|
│ id (PK) │ │ id (PK) │ │ id (PK) │
|
|
│ email │◄──────┤ created_by │ │ customer_id │──────►
|
|
│ password_hash│ │ company_name │ │ name │
|
|
│ first_name │ │ industry │ │ description │
|
|
│ last_name │ │ website │ │ status │
|
|
│ role │ │ phone │ │ priority │
|
|
│ is_active │ │ email │ │ start_date │
|
|
│ created_at │ │ address │ │ end_date │
|
|
└──────────────┘ │ notes │ │ budget │
|
|
│ tags[] │ │ created_by │◄─────
|
|
│ created_at │ │ created_at │
|
|
└──────────────┘ └──────────────┘
|
|
│ │
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ contacts │ │project_members
|
|
├──────────────┤ ├──────────────┤
|
|
│ id (PK) │ │ id (PK) │
|
|
│ customer_id │──────►│ project_id │
|
|
│ first_name │ │ user_id │
|
|
│ last_name │ │ role │
|
|
│ email │ │ joined_at │
|
|
│ phone │ └──────────────┘
|
|
│ position │
|
|
│ is_primary │
|
|
└──────────────┘
|
|
```
|
|
|
|
### 3.2 Zusätzliche Tabellen (Spätere Phasen)
|
|
|
|
```
|
|
documents:
|
|
- id (PK)
|
|
- name
|
|
- original_name
|
|
- storage_path
|
|
- mime_type
|
|
- size_bytes
|
|
- project_id (FK)
|
|
- uploaded_by (FK)
|
|
- created_at
|
|
|
|
tasks:
|
|
- id (PK)
|
|
- title
|
|
- description
|
|
- status
|
|
- priority
|
|
- due_date
|
|
- project_id (FK)
|
|
- assigned_to (FK)
|
|
- created_by (FK)
|
|
|
|
emails:
|
|
- id (PK)
|
|
- message_id (IMAP)
|
|
- subject
|
|
- from_address
|
|
- to_addresses
|
|
- body_text
|
|
- body_html
|
|
- received_at
|
|
- project_id (FK, nullable)
|
|
- customer_id (FK, nullable)
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Frontend-Architektur
|
|
|
|
### 4.1 Komponenten-Struktur
|
|
|
|
```
|
|
frontend/src/
|
|
├── components/
|
|
│ ├── ui/ # shadcn/ui Basis-Komponenten
|
|
│ │ ├── button.tsx
|
|
│ │ ├── input.tsx
|
|
│ │ ├── dialog.tsx
|
|
│ │ └── ...
|
|
│ │
|
|
│ ├── layout/ # Layout-Komponenten
|
|
│ │ ├── Sidebar.tsx
|
|
│ │ ├── Header.tsx
|
|
│ │ └── MainLayout.tsx
|
|
│ │
|
|
│ ├── forms/ # Formular-Komponenten
|
|
│ │ ├── CustomerForm.tsx
|
|
│ │ ├── ProjectForm.tsx
|
|
│ │ └── LoginForm.tsx
|
|
│ │
|
|
│ └── data-display/ # Daten-Visualisierung
|
|
│ ├── DataTable.tsx
|
|
│ ├── StatCard.tsx
|
|
│ └── ActivityFeed.tsx
|
|
│
|
|
├── pages/ # Route-Komponenten
|
|
│ ├── auth/
|
|
│ │ └── Login.tsx
|
|
│ ├── dashboard/
|
|
│ │ └── Dashboard.tsx
|
|
│ ├── customers/
|
|
│ │ ├── CustomerList.tsx
|
|
│ │ └── CustomerDetail.tsx
|
|
│ ├── projects/
|
|
│ │ ├── ProjectList.tsx
|
|
│ │ └── ProjectDetail.tsx
|
|
│ └── documents/
|
|
│ └── DocumentList.tsx
|
|
│
|
|
├── hooks/ # Custom Hooks
|
|
│ ├── useAuth.ts
|
|
│ ├── useCustomers.ts
|
|
│ └── useProjects.ts
|
|
│
|
|
├── services/ # API-Clients
|
|
│ └── api.ts # Axios-Instance
|
|
│
|
|
├── store/ # Zustand Store
|
|
│ ├── authStore.ts
|
|
│ └── uiStore.ts
|
|
│
|
|
├── types/ # TypeScript Types
|
|
│ └── index.ts
|
|
│
|
|
└── utils/ # Hilfsfunktionen
|
|
├── formatters.ts
|
|
└── validators.ts
|
|
```
|
|
|
|
### 4.2 State Management
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────┐
|
|
│ Zustand Store │
|
|
├──────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ authStore │ │ uiStore │ │
|
|
│ │ │ │ │ │
|
|
│ │ • user │ │ • sidebar │ │
|
|
│ │ • token │ │ • theme │ │
|
|
│ │ • isAuth │ │ • notifications│ │
|
|
│ │ • login() │ │ • modalState │ │
|
|
│ │ • logout() │ │ • setTheme() │ │
|
|
│ └──────────────┘ └──────────────┘ │
|
|
│ │
|
|
└──────────────────────────────────────────────────────┘
|
|
|
|
┌──────────────────────────────────────────────────────┐
|
|
│ TanStack Query │
|
|
│ (Server State) │
|
|
├──────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ • useCustomers() → GET /api/customers │
|
|
│ • useCustomer(id) → GET /api/customers/:id │
|
|
│ • useCreateCustomer() → POST /api/customers │
|
|
│ • useUpdateCustomer() → PUT /api/customers/:id │
|
|
│ │
|
|
│ Features: │
|
|
│ • Caching │
|
|
│ • Background Refetching │
|
|
│ • Optimistic Updates │
|
|
│ • Error Handling │
|
|
│ │
|
|
└──────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Deployment-Architektur
|
|
|
|
### 5.1 Server-Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Ubuntu 24.04 LTS │
|
|
│ (waldseilgarten) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────────┐ │
|
|
│ │ Podman Runtime │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
|
|
│ │ │ Traefik │ │ Backend │ │ Frontend │ │ │
|
|
│ │ │ :80/:443 │ │ :3001 │ │ :3000 │ │ │
|
|
│ │ └─────────────┘ └─────────────┘ └────────────┘ │ │
|
|
│ │ │ │
|
|
│ │ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
|
|
│ │ │ PostgreSQL │ │ Redis │ │ Worker │ │ │
|
|
│ │ │ :5432 │ │ :6379 │ │ (IMAP) │ │ │
|
|
│ │ └─────────────┘ └─────────────┘ └────────────┘ │ │
|
|
│ │ │ │
|
|
│ └─────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────────┐ │
|
|
│ │ Volumes │ │
|
|
│ │ │ │
|
|
│ │ ~/projects/waldseilgarten-crm/data/ │ │
|
|
│ │ ├── db/ → PostgreSQL Daten │ │
|
|
│ │ ├── redis/ → Redis Persistenz │ │
|
|
│ │ └── uploads/ → Dokumente │ │
|
|
│ │ │ │
|
|
│ └─────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 5.2 Netzwerk-Architektur
|
|
|
|
```
|
|
Internet
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Cloudflare │ (Optional: CDN, DDoS-Protection)
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Router │ 85.199.86.188
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Traefik │ Port 80/443
|
|
│ (Reverse │
|
|
│ Proxy) │
|
|
└──┬───────┬──┘
|
|
│ │
|
|
▼ ▼
|
|
┌──────┐ ┌──────┐
|
|
│:3000 │ │:3001 │
|
|
│Frontend│ │Backend│
|
|
└──────┘ └──────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Sicherheitsarchitektur
|
|
|
|
### 6.1 Authentifizierungs-Flow
|
|
|
|
```
|
|
┌─────────┐ ┌─────────┐
|
|
│ Client │ │ Server │
|
|
└────┬────┘ └────┬────┘
|
|
│ │
|
|
│ POST /api/auth/login │
|
|
│ { email, password } │
|
|
│───────────────────────────────────────▶│
|
|
│ │
|
|
│ │ bcrypt.compare()
|
|
│ │
|
|
│ { access_token, user } │
|
|
│◀───────────────────────────────────────│
|
|
│ │
|
|
│ Store in memory (Zustand) │
|
|
│ │
|
|
│ GET /api/customers │
|
|
│ Authorization: Bearer {token} │
|
|
│───────────────────────────────────────▶│
|
|
│ │
|
|
│ │ JWT.verify()
|
|
│ │
|
|
│ { customers } │
|
|
│◀───────────────────────────────────────│
|
|
│ │
|
|
```
|
|
|
|
### 6.2 Autorisierungs-Matrix
|
|
|
|
| Feature | Admin | Manager | User |
|
|
|---------|-------|---------|------|
|
|
| Benutzer verwalten | ✅ | ❌ | ❌ |
|
|
| Alle Kunden sehen | ✅ | ✅ | ✅ |
|
|
| Alle Projekte sehen | ✅ | ✅ | ⚠️* |
|
|
| Projekt anlegen | ✅ | ✅ | ❌ |
|
|
| Eigene Daten ändern | ✅ | ✅ | ✅ |
|
|
| Reports exportieren | ✅ | ✅ | ❌ |
|
|
| System-Einstellungen | ✅ | ❌ | ❌ |
|
|
|
|
*User sieht nur zugewiesene Projekte
|
|
|
|
---
|
|
|
|
## 7. Monitoring & Observability
|
|
|
|
### 7.1 Health Checks
|
|
|
|
```
|
|
GET /api/health
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2026-03-14T14:30:00Z",
|
|
"version": "1.0.0",
|
|
"checks": {
|
|
"database": {
|
|
"status": "up",
|
|
"responseTime": "12ms"
|
|
},
|
|
"cache": {
|
|
"status": "up",
|
|
"responseTime": "3ms"
|
|
},
|
|
"storage": {
|
|
"status": "up",
|
|
"freeSpace": "45GB"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 7.2 Logging-Struktur
|
|
|
|
```typescript
|
|
{
|
|
"timestamp": "2026-03-14T14:30:00Z",
|
|
"level": "info",
|
|
"context": "CustomersService",
|
|
"message": "Customer created",
|
|
"metadata": {
|
|
"customerId": "uuid",
|
|
"userId": "uuid",
|
|
"duration": "45ms"
|
|
},
|
|
"requestId": "req-uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
**Ende der Architektur-Dokumentation**
|