cms.c2sgmbh/CLAUDE.md
Martin Porwoll 669f27d238 docs: add Workflows and Timeline process fields documentation
- Add Workflows Collection to CLAUDE.md with full API documentation
- Document Timeline process-specific fields (stepNumber, duration, responsible, etc.)
- Add Workflows API endpoint to URLs section
- Add complexity parameter validation to /api/workflows (returns 400 for invalid values)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-13 14:37:41 +00:00

782 lines
24 KiB
Markdown

# Payload CMS Multi-Tenant Project
## Projektübersicht
Multi-Tenant CMS für 4 Websites unter einer Payload CMS 3.x Instanz:
- porwoll.de
- complexcaresolutions.de
- gunshin.de
- zweitmein.ng
## Tech Stack
- **CMS:** Payload CMS 3.x
- **Framework:** Next.js 15.4.7
- **Sprache:** TypeScript
- **Datenbank:** PostgreSQL 17 (separater Server)
- **Connection Pool:** PgBouncer 1.24.1 (Transaction-Mode)
- **Reverse Proxy:** Caddy 2.10.2 mit Let's Encrypt
- **Process Manager:** PM2
- **Package Manager:** pnpm
- **Cache:** Redis (optional, mit In-Memory-Fallback)
- **Job Queue:** BullMQ (Redis-basiert)
## Architektur
```
Internet → 37.24.237.181 → Caddy (443) → Payload (3000)
PgBouncer (6432)
PostgreSQL (10.10.181.101:5432)
```
| Server | IP | Funktion |
| --------------------- | ------------- | ---------- |
| sv-payload (LXC 700) | 10.10.181.100 | App Server |
| sv-postgres (LXC 701) | 10.10.181.101 | Datenbank |
## Wichtige Pfade
```
/home/payload/payload-cms/ # Projektroot
├── src/
│ ├── payload.config.ts # Haupt-Konfiguration
│ ├── collections/ # Alle Collections
│ │ ├── Users.ts
│ │ ├── Media.ts
│ │ ├── Tenants.ts
│ │ ├── Posts.ts
│ │ ├── Categories.ts
│ │ ├── Portfolios.ts
│ │ ├── PortfolioCategories.ts
│ │ ├── FAQs.ts
│ │ ├── Team.ts
│ │ ├── ServiceCategories.ts
│ │ ├── Services.ts
│ │ ├── EmailLogs.ts
│ │ ├── AuditLogs.ts
│ │ └── ...
│ ├── app/(payload)/api/ # Custom API Routes
│ │ ├── users/login/route.ts # Custom Login mit Audit
│ │ ├── send-email/route.ts
│ │ ├── email-logs/
│ │ │ ├── export/route.ts
│ │ │ └── stats/route.ts
│ │ └── test-email/route.ts
│ ├── lib/
│ │ ├── email/ # E-Mail-System
│ │ │ ├── tenant-email-service.ts
│ │ │ ├── payload-email-adapter.ts
│ │ │ ├── newsletter-service.ts # Newsletter Double Opt-In
│ │ │ └── newsletter-templates.ts # E-Mail-Templates
│ │ ├── security/ # Security-Module
│ │ │ ├── rate-limiter.ts
│ │ │ ├── csrf.ts
│ │ │ ├── ip-allowlist.ts
│ │ │ └── data-masking.ts
│ │ ├── queue/ # BullMQ Job Queue
│ │ │ ├── queue-service.ts
│ │ │ ├── jobs/email-job.ts
│ │ │ ├── jobs/pdf-job.ts
│ │ │ ├── workers/email-worker.ts
│ │ │ └── workers/pdf-worker.ts
│ │ ├── pdf/ # PDF-Generierung
│ │ │ └── pdf-service.ts
│ │ ├── search.ts # Volltextsuche
│ │ └── redis.ts # Redis Cache Client
│ └── hooks/ # Collection Hooks
│ ├── sendFormNotification.ts
│ ├── sendNewsletterConfirmation.ts # Newsletter Double Opt-In
│ ├── invalidateEmailCache.ts
│ └── auditLog.ts
├── tests/ # Test Suite
│ ├── unit/security/ # Security Unit Tests
│ └── int/ # Integration Tests
├── scripts/
│ ├── run-queue-worker.ts # Queue Worker Starter
│ └── backup/ # Backup-System
│ ├── backup-db.sh # PostgreSQL Backup-Skript
│ ├── restore-db.sh # PostgreSQL Restore-Skript
│ ├── setup-backup.sh # Interaktives Setup
│ └── README.md # Backup-Dokumentation
├── .env # Umgebungsvariablen
├── ecosystem.config.cjs # PM2 Config
└── .next/ # Build Output
```
## Umgebungsvariablen (.env)
> **Hinweis:** Sensible Credentials (DB_PASSWORD, SMTP_PASS, etc.) werden aus `~/.pgpass`
> und Umgebungsvariablen gelesen. Niemals Klartext-Passwörter in diese Datei schreiben!
```env
# Datenbank (Passwort in ~/.pgpass oder als Umgebungsvariable)
DATABASE_URI=postgresql://payload:${DB_PASSWORD}@127.0.0.1:6432/payload_db
PAYLOAD_SECRET=a53b254070d3fffd2b5cfcc3
PAYLOAD_PUBLIC_SERVER_URL=https://pl.c2sgmbh.de
NEXT_PUBLIC_SERVER_URL=https://pl.c2sgmbh.de
NODE_ENV=production
PORT=3000
# E-Mail (Global Fallback)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=user@example.com
SMTP_PASS=secret
SMTP_FROM_ADDRESS=noreply@c2sgmbh.de
SMTP_FROM_NAME=Payload CMS
# Redis Cache
REDIS_URL=redis://localhost:6379
# Security
CSRF_SECRET=your-csrf-secret
SEND_EMAIL_ALLOWED_IPS= # Optional: Komma-separierte IPs/CIDRs
BLOCKED_IPS= # Optional: Global geblockte IPs
```
## PgBouncer Connection Pooling
PgBouncer läuft auf dem App-Server und pooled Datenbankverbindungen:
```bash
# Konfiguration
/etc/pgbouncer/pgbouncer.ini
/etc/pgbouncer/userlist.txt # chmod 600
# Service
sudo systemctl status pgbouncer
sudo systemctl restart pgbouncer
# Statistiken abfragen
# Pool-Statistiken (Passwort aus ~/.pgpass)
PGPASSWORD="$DB_PASSWORD" psql -h 127.0.0.1 -p 6432 -U payload -d pgbouncer -c "SHOW POOLS;"
PGPASSWORD="$DB_PASSWORD" psql -h 127.0.0.1 -p 6432 -U payload -d pgbouncer -c "SHOW STATS;"
```
**Konfiguration:**
| Parameter | Wert | Beschreibung |
|-----------|------|--------------|
| pool_mode | transaction | Verbindung wird nach Transaktion freigegeben |
| default_pool_size | 20 | Standard-Pool-Größe pro DB/User |
| min_pool_size | 5 | Mindestens gehaltene Verbindungen |
| reserve_pool_size | 5 | Reserve für Lastspitzen |
| max_db_connections | 50 | Max. Verbindungen zu PostgreSQL |
| max_client_conn | 200 | Max. Clients zu PgBouncer |
**Verbindungen:**
- App → PgBouncer: `127.0.0.1:6432` (DATABASE_URI)
- PgBouncer → PostgreSQL: `10.10.181.101:5432` (TLS 1.3, `server_tls_sslmode = require`)
**Direkte Verbindung (für Migrationen/CLI):**
PgBouncer im Transaction-Mode kann Probleme mit lang laufenden Migrationen verursachen.
Für solche Fälle das `db-direct.sh` Skript verwenden:
```bash
# Migrationen direkt an PostgreSQL (umgeht PgBouncer)
./scripts/db-direct.sh migrate
# Interaktive psql-Session
./scripts/db-direct.sh psql
# Schema-Änderungen
./scripts/db-direct.sh migrate:create
```
Das Skript liest Credentials aus `~/.pgpass` (chmod 600).
## Multi-Tenant Plugin
Verwendet `@payloadcms/plugin-multi-tenant` für Mandantenfähigkeit.
**Aktuelle Tenants:**
| ID | Name | Slug |
|----|------|------|
| 1 | porwoll.de | porwoll |
| 4 | Complex Care Solutions GmbH | c2s |
| 5 | Gunshin | gunshin |
**User-Tenant-Zuweisung:** Tabelle `users_tenants`
## Wichtige Befehle
```bash
# Entwicklung
pnpm dev
# Production Build
pnpm build
# Migrationen
pnpm payload migrate:create
pnpm payload migrate
# ImportMap nach Plugin-Änderungen
pnpm payload generate:importmap
# PM2
pm2 status
pm2 logs payload
pm2 logs queue-worker
pm2 restart payload
pm2 restart queue-worker
# Tests
pnpm test # Alle Tests
pnpm test:security # Security Tests
pnpm test:access-control # Access Control Tests
pnpm test:coverage # Mit Coverage-Report
# Datenbank prüfen
# Verwende ./scripts/db-direct.sh psql oder:
PGPASSWORD="$DB_PASSWORD" psql -h 10.10.181.101 -U payload -d payload_db
# Backup
/home/payload/backups/postgres/backup-db.sh --verbose # Manuelles Backup
scripts/backup/setup-backup.sh # Backup-System einrichten
```
## Workflow nach Code-Änderungen
1. Code ändern
2. `pnpm build`
3. `pm2 restart payload`
4. Testen unter https://pl.c2sgmbh.de/admin
## Bekannte Besonderheiten
- **ES Modules:** package.json hat `"type": "module"`, daher PM2 Config als `.cjs`
- **Plugin ImportMap:** Nach Plugin-Änderungen `pnpm payload generate:importmap` ausführen
- **User-Tenant-Zuweisung:** Neue User müssen manuell Tenants zugewiesen bekommen
- **Admin Login:** Custom Route mit Audit-Logging, unterstützt JSON und `_payload` FormData
## Build-Konfiguration
Der Build ist für speichereffizientes Kompilieren optimiert:
- `package.json`: `--max-old-space-size=2048` (2GB Heap-Limit)
- `next.config.mjs`: `experimental.cpus: 1`, `workerThreads: false`
**WICHTIG:** Der Server hat 8GB RAM ohne Swap. Bei laufendem VS Code Server kann der Build mit reduziertem Memory ausgeführt werden:
```bash
pm2 stop payload # Speicher freigeben
NODE_OPTIONS="--no-deprecation --max-old-space-size=1024" ./node_modules/.bin/next build
pm2 start payload
```
Ohne PM2-Stop und mit VS Code wird der Build vom OOM Killer beendet (Exit code 137).
## Mehrsprachigkeit (i18n)
Das System unterstützt Deutsch (default) und Englisch:
- **Admin UI:** `@payloadcms/translations` für DE/EN
- **Content:** Localization mit Fallback auf Deutsch
- **Datenbank:** 36 `_locales` Tabellen für lokalisierte Felder
- **API:** `?locale=de` oder `?locale=en` Parameter
- **Frontend:** Routing über `/[locale]/...`
```bash
# Locales in der Datenbank prüfen
# Verwende ./scripts/db-direct.sh psql oder:
PGPASSWORD="$DB_PASSWORD" psql -h 10.10.181.101 -U payload -d payload_db -c "\dt *_locales"
```
## URLs
- **Admin Panel:** https://pl.c2sgmbh.de/admin
- **API:** https://pl.c2sgmbh.de/api
- **API-Dokumentation (Swagger UI):** https://pl.c2sgmbh.de/api/docs
- **OpenAPI JSON:** https://pl.c2sgmbh.de/api/openapi.json
- **E-Mail API:** https://pl.c2sgmbh.de/api/send-email (POST, Auth erforderlich)
- **Test-E-Mail:** https://pl.c2sgmbh.de/api/test-email (POST, Admin erforderlich)
- **E-Mail Stats:** https://pl.c2sgmbh.de/api/email-logs/stats (GET, Auth erforderlich)
- **PDF-Generierung:** https://pl.c2sgmbh.de/api/generate-pdf (POST/GET, Auth erforderlich)
- **Newsletter Anmeldung:** https://pl.c2sgmbh.de/api/newsletter/subscribe (POST, öffentlich)
- **Newsletter Bestätigung:** https://pl.c2sgmbh.de/api/newsletter/confirm (GET/POST)
- **Newsletter Abmeldung:** https://pl.c2sgmbh.de/api/newsletter/unsubscribe (GET/POST)
- **Timeline API:** https://pl.c2sgmbh.de/api/timelines (GET, öffentlich, tenant required)
- **Workflows API:** https://pl.c2sgmbh.de/api/workflows (GET, öffentlich, tenant required)
## Security-Features
### Rate-Limiting
Zentraler Rate-Limiter mit vordefinierten Limits:
- `publicApi`: 60 Requests/Minute
- `auth`: 5 Requests/15 Minuten (Login)
- `email`: 10 Requests/Minute
- `search`: 30 Requests/Minute
- `form`: 5 Requests/10 Minuten
### CSRF-Schutz
- Double Submit Cookie Pattern
- Origin-Header-Validierung
- Token-Endpoint: `GET /api/csrf-token`
- Admin-Panel hat eigenen CSRF-Schutz
### IP-Allowlist
- Konfigurierbar via `SEND_EMAIL_ALLOWED_IPS`
- Unterstützt IPs, CIDRs (`192.168.1.0/24`) und Wildcards (`10.10.*.*`)
- Globale Blocklist via `BLOCKED_IPS`
### Data-Masking
- Automatische Maskierung sensibler Daten in Logs
- Erkennt Passwörter, Tokens, API-Keys, SMTP-Credentials
- Safe-Logger-Factory für konsistentes Logging
## E-Mail-System
Multi-Tenant E-Mail-System mit tenant-spezifischer SMTP-Konfiguration:
**Architektur:**
- Globaler SMTP als Fallback (via .env)
- Tenant-spezifische SMTP in Tenants Collection
- Transporter-Caching mit automatischer Invalidierung
- EmailLogs Collection für Audit-Trail
**Tenant E-Mail-Konfiguration:**
```
Tenants → email → fromAddress, fromName, replyTo
→ email → useCustomSmtp (Checkbox)
→ email → smtp → host, port, secure, user, pass
```
**API-Endpoint `/api/send-email`:**
```bash
curl -X POST https://pl.c2sgmbh.de/api/send-email \
-H "Content-Type: application/json" \
-H "Cookie: payload-token=..." \
-d '{
"to": "empfaenger@example.com",
"subject": "Betreff",
"html": "<p>Inhalt</p>",
"tenantId": 1
}'
```
**Sicherheit:**
- Authentifizierung erforderlich
- Tenant-Zugriffskontrolle (User muss Tenant-Mitglied sein)
- Rate-Limiting: 10 E-Mails/Minute pro User
- SMTP-Passwort nie in API-Responses
### Newsletter Double Opt-In
DSGVO-konformes Newsletter-System mit Double Opt-In:
**Flow:**
1. User meldet sich an → Status: `pending`, Token wird generiert
2. Double Opt-In E-Mail wird automatisch gesendet
3. User klickt Bestätigungs-Link → Status: `confirmed`
4. Willkommens-E-Mail wird gesendet
5. Abmeldung jederzeit über Link in E-Mails möglich
**API-Endpoints:**
```bash
# Newsletter-Anmeldung
curl -X POST https://pl.c2sgmbh.de/api/newsletter/subscribe \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"firstName": "Max",
"tenantId": 1,
"source": "footer"
}'
# Bestätigung (via Link aus E-Mail)
GET https://pl.c2sgmbh.de/api/newsletter/confirm?token=<uuid>
# Abmeldung (via Link aus E-Mail)
GET https://pl.c2sgmbh.de/api/newsletter/unsubscribe?token=<uuid>
```
**Features:**
- Automatischer E-Mail-Versand bei Anmeldung
- Token-Ablauf nach 48 Stunden
- Willkommens-E-Mail nach Bestätigung
- Abmelde-Bestätigung per E-Mail
- Rate-Limiting: 5 Anmeldungen/10 Minuten pro IP
- Erneute Anmeldung nach Abmeldung möglich
## BullMQ Job Queue
Das System verwendet BullMQ für asynchrone Job-Verarbeitung mit Redis als Backend.
### PM2 Worker
Der Queue-Worker läuft als separater PM2-Prozess:
```bash
# Worker-Status prüfen
pm2 status
pm2 logs queue-worker
# Worker neustarten
pm2 restart queue-worker
```
### Email Queue
E-Mails können asynchron über die Queue versendet werden:
```typescript
import { queueEmail } from '@/lib/queue'
await queueEmail({
tenantId: 1,
to: 'empfaenger@example.com',
subject: 'Betreff',
html: '<p>Inhalt</p>',
source: 'form-submission'
})
```
### PDF Queue
PDF-Generierung erfolgt über Playwright (HTML/URL zu PDF):
**API-Endpoint `/api/generate-pdf`:**
```bash
# PDF aus HTML generieren
curl -X POST https://pl.c2sgmbh.de/api/generate-pdf \
-H "Content-Type: application/json" \
-H "Cookie: payload-token=..." \
-d '{
"source": "html",
"html": "<h1>Test</h1><p>Inhalt</p>",
"filename": "test.pdf"
}'
# Job-Status abfragen
curl "https://pl.c2sgmbh.de/api/generate-pdf?jobId=abc123" \
-H "Cookie: payload-token=..."
```
**Programmatisch:**
```typescript
import { queuePdfFromHtml, queuePdfFromUrl, getPdfJobStatus } from '@/lib/queue'
// HTML zu PDF
const job = await queuePdfFromHtml('<h1>Test</h1>', { filename: 'test.pdf' })
// URL zu PDF
const job2 = await queuePdfFromUrl('https://example.com', { format: 'A4' })
// Status abfragen
const status = await getPdfJobStatus(job.id)
```
### Worker-Konfiguration
Über `ecosystem.config.cjs`:
- `QUEUE_EMAIL_CONCURRENCY`: Parallele E-Mail-Jobs (default: 3)
- `QUEUE_PDF_CONCURRENCY`: Parallele PDF-Jobs (default: 2)
- `QUEUE_DEFAULT_RETRY`: Retry-Versuche (default: 3)
- `QUEUE_REDIS_DB`: Redis-Datenbank für Queue (default: 1)
## Redis Caching
Redis wird für API-Response-Caching und E-Mail-Transporter-Caching verwendet:
```typescript
import { redis } from '@/lib/redis'
// Cache setzen (TTL in Sekunden)
await redis.set('key', JSON.stringify(data), 'EX', 60)
// Cache lesen
const cached = await redis.get('key')
// Pattern-basierte Invalidierung
await redis.keys('posts:*').then(keys => keys.length && redis.del(...keys))
```
## Backup-System
Automatisches tägliches PostgreSQL-Backup mit lokalem Speicher und S3-Offsite-Backup.
**Setup auf neuem Server:**
```bash
cd /home/payload/payload-cms/scripts/backup
./setup-backup.sh
```
**Konfigurationsdateien (nicht im Repo):**
- `~/.pgpass` - PostgreSQL-Credentials (chmod 600)
- `~/.s3cfg` - S3-Credentials (chmod 600)
**Backup-Speicherorte:**
| Ort | Pfad | Retention |
|-----|------|-----------|
| Lokal | `/home/payload/backups/postgres/` | 30 Tage |
| S3 | `s3://c2s/backups/postgres/` | 30 Tage |
**Cron-Job:** Täglich um 03:00 Uhr
**Manuelles Backup:**
```bash
/home/payload/backups/postgres/backup-db.sh --verbose
```
**Restore aus Backup:**
```bash
# Lokal
gunzip -c /home/payload/backups/postgres/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz | \
psql -h 10.10.181.101 -U payload -d payload_db
# Aus S3
s3cmd get s3://c2s/backups/postgres/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz
gunzip -c payload_db_*.sql.gz | psql -h 10.10.181.101 -U payload -d payload_db
```
Dokumentation: `scripts/backup/README.md`
## Datenbank-Direktzugriff
```bash
# Verwende ./scripts/db-direct.sh psql oder:
PGPASSWORD="$DB_PASSWORD" psql -h 10.10.181.101 -U payload -d payload_db
# Nützliche Queries
SELECT * FROM tenants;
SELECT * FROM users_tenants;
SELECT * FROM email_logs ORDER BY created_at DESC LIMIT 10;
SELECT * FROM audit_logs ORDER BY created_at DESC LIMIT 10;
\dt -- Alle Tabellen
```
## Collections Übersicht
| Collection | Slug | Beschreibung |
|------------|------|--------------|
| Users | users | Benutzer mit isSuperAdmin Flag |
| Tenants | tenants | Mandanten mit E-Mail-Konfiguration |
| Media | media | Medien mit 11 responsive Image Sizes |
| Pages | pages | Seiten mit Blocks |
| Posts | posts | Blog/News/Presse mit Kategorien |
| Categories | categories | Kategorien für Posts |
| Portfolios | portfolios | Portfolio-Galerien (Fotografie) |
| PortfolioCategories | portfolio-categories | Kategorien für Portfolios |
| Testimonials | testimonials | Kundenbewertungen |
| FAQs | faqs | Häufig gestellte Fragen (FAQ) |
| Team | team | Team-Mitglieder und Mitarbeiter |
| ServiceCategories | service-categories | Kategorien für Leistungen |
| Services | services | Leistungen und Dienstleistungen |
| NewsletterSubscribers | newsletter-subscribers | Newsletter mit Double Opt-In |
| SocialLinks | social-links | Social Media Links |
| Forms | forms | Formular-Builder |
| FormSubmissions | form-submissions | Formular-Einsendungen mit Status-Workflow |
| EmailLogs | email-logs | E-Mail-Protokollierung |
| AuditLogs | audit-logs | Security Audit Trail |
| CookieConfigurations | cookie-configurations | Cookie-Banner Konfiguration |
| CookieInventory | cookie-inventory | Cookie-Inventar |
| ConsentLogs | consent-logs | Consent-Protokollierung |
| Timelines | timelines | Chronologische Events (Geschichte, Meilensteine) |
| Workflows | workflows | Komplexe Prozesse mit Phasen und Schritten |
## Timeline Collection
Dedizierte Collection für komplexe chronologische Darstellungen:
**Timeline-Typen:**
- `history` - Unternehmensgeschichte
- `milestones` - Projektmeilensteine
- `releases` - Produkt-Releases
- `career` - Karriere/Lebenslauf
- `events` - Ereignisse
- `process` - Prozess/Ablauf
**Event-Features:**
- Flexible Datumsformate (Jahr, Monat+Jahr, vollständig, Zeitraum, Freitext)
- Kategorien (Meilenstein, Gründung, Produkt, Team, Auszeichnung, etc.)
- Wichtigkeitsstufen (Highlight, Normal, Minor)
- Bilder und Galerien
- Links und Metadaten
- Rich-Text-Beschreibungen
**Display-Optionen:**
- Layouts: vertikal, alternierend, horizontal, kompakt
- Sortierung: aufsteigend/absteigend
- Gruppierung nach Jahr
- Verschiedene Marker-Stile
**Prozess-spezifische Felder (type=process):**
- `stepNumber` - Explizite Schritt-Nummerierung
- `duration` - Dauer (z.B. "2-3 Tage")
- `responsible` - Verantwortliche Person/Rolle
- `actionRequired` - Wer muss aktiv werden (customer, internal, both, automatic)
- `deliverables` - Ergebnisse/Dokumente des Schritts
**API-Endpoint:**
```bash
# Liste aller Timelines eines Tenants
curl "https://pl.c2sgmbh.de/api/timelines?tenant=1"
# Nach Typ filtern
curl "https://pl.c2sgmbh.de/api/timelines?tenant=1&type=history"
# Einzelne Timeline
curl "https://pl.c2sgmbh.de/api/timelines?tenant=1&slug=company-history"
# Mit Sprache
curl "https://pl.c2sgmbh.de/api/timelines?tenant=1&locale=en"
```
## Workflows Collection
Komplexe Prozess- und Workflow-Darstellungen mit Phasen, Abhängigkeiten und Status-Tracking.
**Workflow-Typen:**
- `project` - Projektabläufe
- `business` - Geschäftsprozesse
- `approval` - Genehmigungs-Workflows
- `onboarding` - Mitarbeiter-/Kundeneinführung
- `support` - Support/Service-Prozesse
- `development` - Entwicklungsprozesse
- `marketing` - Marketing-Workflows
- `other` - Sonstige
**Eigenschaften:**
- `estimatedDuration` - Geschätzte Gesamtdauer
- `complexity` - simple, medium, complex, very_complex
- `isIterative` - Kann wiederholt werden
- `allowParallelPhases` - Parallele Phasen möglich
**Display-Optionen:**
- Layouts: vertical, horizontal, flowchart, kanban, gantt
- Farbschema: phase, status, priority, brand
- Optionale Anzeige: Nummern, Zeiten, Verantwortliche, Fortschritt
**Phasen-Struktur:**
```
Workflow
└── Phasen (Array)
├── name, description, icon, color
├── estimatedDuration, responsible
├── deliverables (Array)
└── Schritte (Array)
├── name, description, stepType, priority
├── estimatedDuration, responsible
├── dependencies (dependsOnSteps, canRunParallel, isBlocking)
├── conditions (für Entscheidungen)
├── checklist (Array)
├── resources (Dokumente, Links, Tools)
└── outputs (Ergebnisse)
```
**API-Endpoint:**
```bash
# Liste aller Workflows eines Tenants
curl "https://pl.c2sgmbh.de/api/workflows?tenant=1"
# Nach Typ filtern
curl "https://pl.c2sgmbh.de/api/workflows?tenant=1&type=project"
# Nach Komplexität filtern
curl "https://pl.c2sgmbh.de/api/workflows?tenant=1&complexity=medium"
# Einzelner Workflow
curl "https://pl.c2sgmbh.de/api/workflows?tenant=1&slug=web-project"
# Mit Sprache
curl "https://pl.c2sgmbh.de/api/workflows?tenant=1&locale=en"
```
**Validierung:**
- `tenant` - Pflichtparameter (Tenant-Isolation)
- `type` - Validiert gegen erlaubte Typen (400 bei Fehler)
- `complexity` - Validiert gegen erlaubte Werte (400 bei Fehler)
- `locale` - de (default) oder en
## FormSubmissions CRM-Workflow
Die FormSubmissions Collection wurde zu einem leichtgewichtigen CRM erweitert:
**Status-Workflow:**
- 🆕 Neu → 👀 Gelesen → 🔄 In Bearbeitung → ⏳ Warten → ✅ Erledigt → 🗑️ Archiviert
**Features:**
- Priorität (Hoch/Normal/Niedrig)
- Zuständigkeits-Zuweisung an User
- Interne Notizen mit Auto-Autor und Zeitstempel
- Antwort-Tracking (Methode, Zeitstempel, Zusammenfassung)
- Tags zur Kategorisierung
- Auto-Markierung als gelesen beim ersten Öffnen
**Dateien:**
- `src/collections/FormSubmissionsOverrides.ts` - Feld-Definitionen
- `src/hooks/formSubmissionHooks.ts` - Automatisierungen
## Globals
| Global | Slug | Beschreibung |
|--------|------|--------------|
| SiteSettings | site-settings | Allgemeine Website-Einstellungen |
| Navigation | navigation | Navigationsmenü |
| SEOSettings | seo-settings | SEO-Einstellungen |
| PrivacyPolicySettings | privacy-policy-settings | Datenschutz-Einstellungen |
## Test Suite
```bash
# Alle Tests ausführen
pnpm test
# Security Tests
pnpm test:security
# Coverage Report
pnpm test:coverage
```
**Test Coverage Thresholds:**
- Lines: 35%
- Functions: 50%
- Branches: 65%
## CI/CD Pipeline
GitHub Actions Workflows in `.github/workflows/`:
### ci.yml (Main CI Pipeline)
Läuft bei Push/PR auf `main` und `develop`:
| Job | Beschreibung |
|-----|--------------|
| **lint** | ESLint + Prettier Check |
| **typecheck** | TypeScript Compiler (`tsc --noEmit`) |
| **test** | Unit & Integration Tests (Vitest) |
| **build** | Next.js Production Build |
| **e2e** | Playwright E2E Tests |
**Lokale Ausführung:**
```bash
pnpm lint # ESLint
pnpm typecheck # TypeScript Check
pnpm format:check # Prettier Check
pnpm format # Prettier Auto-Fix
pnpm test # Alle Tests
pnpm build # Production Build
```
### security.yml (Security Scanning)
- **Gitleaks**: Secret Scanning
- **pnpm audit**: Dependency Vulnerabilities
- **CodeQL**: Static Analysis (SAST)
- **Security Tests**: Unit & Integration Tests für Security-Module
## Dokumentation
- `CLAUDE.md` - Diese Datei (Projekt-Übersicht)
- `docs/INFRASTRUCTURE.md` - Server-Architektur & Deployment
- `docs/anleitungen/TODO.md` - Task-Liste & Roadmap
- `docs/anleitungen/SECURITY.md` - Sicherheitsrichtlinien
- `scripts/backup/README.md` - Backup-System Dokumentation
*Letzte Aktualisierung: 13.12.2025*