mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 19:44:12 +00:00
docs: optimize CLAUDE.md for context window efficiency (1493→401 lines)
Extract detailed subsystem documentation into docs/CLAUDE_REFERENCE.md. CLAUDE.md is loaded into every AI conversation - reducing it by 73% saves ~38KB of context window tokens per session while keeping all essential info. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8ae5841cc1
commit
1f63ae14f4
2 changed files with 692 additions and 1356 deletions
428
docs/CLAUDE_REFERENCE.md
Normal file
428
docs/CLAUDE_REFERENCE.md
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
# Payload CMS - Detaillierte Subsystem-Referenz
|
||||
|
||||
> Diese Datei enthält detaillierte Dokumentation zu den Subsystemen des Projekts.
|
||||
> Kurzübersicht und Schlüsseldateien: siehe `CLAUDE.md`.
|
||||
|
||||
## 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.porwoll.tech/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
|
||||
|
||||
**Dateien:**
|
||||
- `src/lib/email/tenant-email-service.ts` - Haupt-Service
|
||||
- `src/lib/email/payload-email-adapter.ts` - Payload-Integration
|
||||
- `src/hooks/invalidateEmailCache.ts` - Cache-Invalidierung
|
||||
|
||||
## 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
|
||||
# Anmeldung
|
||||
POST /api/newsletter/subscribe
|
||||
{"email": "...", "firstName": "...", "tenantId": 1, "source": "footer"}
|
||||
|
||||
# Bestätigung (via Link aus E-Mail)
|
||||
GET /api/newsletter/confirm?token=<uuid>
|
||||
|
||||
# Abmeldung (via Link aus E-Mail)
|
||||
GET /api/newsletter/unsubscribe?token=<uuid>
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Token-Ablauf nach 48 Stunden
|
||||
- Rate-Limiting: 5 Anmeldungen/10 Minuten pro IP
|
||||
- Erneute Anmeldung nach Abmeldung möglich
|
||||
|
||||
**Dateien:**
|
||||
- `src/lib/email/newsletter-service.ts` - Service-Logik
|
||||
- `src/lib/email/newsletter-templates.ts` - E-Mail-Templates
|
||||
- `src/hooks/sendNewsletterConfirmation.ts` - Hook
|
||||
|
||||
## BullMQ Job Queue
|
||||
|
||||
Asynchrone Job-Verarbeitung mit Redis als Backend.
|
||||
|
||||
**Queue-Worker:** Läuft als separater PM2-Prozess (`pm2 logs queue-worker`).
|
||||
|
||||
### Email Queue
|
||||
|
||||
```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
|
||||
|
||||
```bash
|
||||
# PDF aus HTML generieren
|
||||
POST /api/generate-pdf
|
||||
{"source": "html", "html": "<h1>Test</h1>", "filename": "test.pdf"}
|
||||
|
||||
# Job-Status abfragen
|
||||
GET /api/generate-pdf?jobId=abc123
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { queuePdfFromHtml, queuePdfFromUrl, getPdfJobStatus } from '@/lib/queue'
|
||||
|
||||
const job = await queuePdfFromHtml('<h1>Test</h1>', { filename: 'test.pdf' })
|
||||
const job2 = await queuePdfFromUrl('https://example.com', { format: 'A4' })
|
||||
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_RETENTION_CONCURRENCY`: Parallele Retention-Jobs (default: 1)
|
||||
- `QUEUE_DEFAULT_RETRY`: Retry-Versuche (default: 3)
|
||||
- `QUEUE_REDIS_DB`: Redis-Datenbank für Queue (default: 1)
|
||||
|
||||
**Dateien:**
|
||||
- `src/lib/queue/queue-service.ts` - Zentrale Queue-Verwaltung
|
||||
- `src/lib/queue/jobs/email-job.ts` - E-Mail-Job
|
||||
- `src/lib/queue/jobs/pdf-job.ts` - PDF-Job
|
||||
- `src/lib/queue/workers/email-worker.ts` - E-Mail-Worker
|
||||
- `src/lib/queue/workers/pdf-worker.ts` - PDF-Worker
|
||||
- `scripts/run-queue-worker.ts` - Worker-Starter
|
||||
|
||||
## Data Retention
|
||||
|
||||
Automatische Datenbereinigung für DSGVO-Compliance und Speicheroptimierung.
|
||||
|
||||
### Retention Policies
|
||||
|
||||
| Collection | Retention | Umgebungsvariable |
|
||||
|------------|-----------|-------------------|
|
||||
| email-logs | 90 Tage | `RETENTION_EMAIL_LOGS_DAYS` |
|
||||
| audit-logs | 90 Tage | `RETENTION_AUDIT_LOGS_DAYS` |
|
||||
| consent-logs | 3 Jahre | `RETENTION_CONSENT_LOGS_DAYS` |
|
||||
| media (orphans) | 30 Tage | `RETENTION_MEDIA_ORPHAN_MIN_AGE_DAYS` |
|
||||
|
||||
Scheduler: Täglich 03:00 Uhr (`RETENTION_CRON_SCHEDULE`).
|
||||
|
||||
### API-Endpoint `/api/retention`
|
||||
|
||||
```bash
|
||||
# Konfiguration abrufen
|
||||
GET /api/retention
|
||||
|
||||
# Job-Status
|
||||
GET /api/retention?jobId=abc123
|
||||
|
||||
# Manueller Job
|
||||
POST /api/retention
|
||||
{"type": "full"} # Alle Policies
|
||||
{"type": "collection", "collection": "email-logs"} # Einzelne Collection
|
||||
{"type": "media-orphans"} # Nur Media-Orphans
|
||||
```
|
||||
|
||||
**Architektur:**
|
||||
```
|
||||
Scheduler (Cron) → Retention Queue (BullMQ) → Retention Worker
|
||||
→ Email-Logs (createdAt) + Audit-Logs (createdAt) + Consent-Logs (expiresAt)
|
||||
→ Media-Orphan-Cleanup
|
||||
```
|
||||
|
||||
**Dateien:**
|
||||
- `src/lib/retention/retention-config.ts` - Zentrale Konfiguration
|
||||
- `src/lib/retention/cleanup-service.ts` - Lösch-Logik
|
||||
- `src/lib/queue/jobs/retention-job.ts` - Job-Definition
|
||||
- `src/lib/queue/workers/retention-worker.ts` - Worker
|
||||
- `src/app/(payload)/api/retention/route.ts` - API-Endpoint
|
||||
|
||||
## Redis Caching
|
||||
|
||||
```typescript
|
||||
import { redis } from '@/lib/redis'
|
||||
|
||||
await redis.set('key', JSON.stringify(data), 'EX', 60) // TTL in Sekunden
|
||||
const cached = await redis.get('key')
|
||||
await redis.keys('posts:*').then(keys => keys.length && redis.del(...keys)) // Pattern-Invalidierung
|
||||
```
|
||||
|
||||
## FormSubmissions CRM
|
||||
|
||||
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
|
||||
|
||||
## Community Management System
|
||||
|
||||
Plattformübergreifendes Community Management für YouTube, Facebook und Instagram.
|
||||
|
||||
### Architektur
|
||||
|
||||
```
|
||||
Admin UI (Inbox + Analytics)
|
||||
→ /api/community/* (sync, stats, reply, generate-reply, export, stream)
|
||||
→ UnifiedSyncService
|
||||
→ YouTube Sync + Facebook Sync + Instagram Sync
|
||||
→ CommunityInteractions (einheitliche Collection)
|
||||
```
|
||||
|
||||
### Admin UI
|
||||
|
||||
**Community Inbox** (`/admin/community/inbox`):
|
||||
- Einheitliche Ansicht aller Kommentare (YouTube + Facebook + Instagram)
|
||||
- Filter nach Plattform, Status, Priorität, Sentiment, Flags
|
||||
- AI-generierte Antwort-Vorschläge (Claude)
|
||||
- Echtzeit-Updates via SSE (`/api/community/stream`)
|
||||
- Export als CSV/JSON
|
||||
|
||||
**Community Analytics** (`/admin/community/analytics`):
|
||||
- KPI-Cards, Sentiment-Trend, Topic-Cloud, Response-Metriken, Kanal-Vergleich
|
||||
|
||||
### Meta (Facebook + Instagram) Integration
|
||||
|
||||
**OAuth-Flow:**
|
||||
1. Admin öffnet `/api/auth/meta?socialAccountId=X&accountType=both`
|
||||
2. Redirect zu Facebook OAuth (12 Scopes)
|
||||
3. Callback: Short-Lived → Long-Lived Token (60 Tage)
|
||||
4. Facebook Pages + Instagram Business Accounts werden geladen
|
||||
5. Token + Account-Daten in SocialAccounts gespeichert
|
||||
|
||||
**Scopes:**
|
||||
- Facebook: `pages_show_list`, `pages_read_engagement`, `pages_manage_posts`, `pages_read_user_content`, `pages_manage_engagement`, `pages_messaging`
|
||||
- Instagram: `instagram_basic`, `instagram_manage_comments`, `instagram_manage_messages`, `instagram_content_publish`
|
||||
|
||||
### API-Endpoints
|
||||
|
||||
| Endpoint | Methode | Beschreibung |
|
||||
|----------|---------|--------------|
|
||||
| `/api/community/sync` | POST | Manueller Sync (alle Plattformen) |
|
||||
| `/api/community/sync` | GET | Sync-Status |
|
||||
| `/api/community/sync-status` | GET | Detaillierter Status mit Account-Stats |
|
||||
| `/api/community/stats` | GET | Interaktions-Statistiken |
|
||||
| `/api/community/reply` | POST | Antwort senden |
|
||||
| `/api/community/generate-reply` | POST | AI-Antwort generieren (Claude) |
|
||||
| `/api/community/export` | GET | Daten-Export (CSV/JSON) |
|
||||
| `/api/community/stream` | GET | SSE-Stream für Echtzeit-Updates |
|
||||
| `/api/community/analytics/*` | GET | Analytics-Daten (6 Endpoints) |
|
||||
| `/api/auth/meta` | GET | Meta OAuth starten |
|
||||
| `/api/auth/meta/callback` | GET | Meta OAuth Callback |
|
||||
|
||||
### Sync-Trigger
|
||||
|
||||
| Trigger | Endpoint | Plattformen |
|
||||
|---------|----------|-------------|
|
||||
| Cron (alle 15 Min) | `/api/cron/community-sync` | Alle aktiven Accounts |
|
||||
| Manuell (Inbox-Button) | `/api/community/sync` (POST) | Alle (optional filterbar) |
|
||||
| YouTube-spezifisch | `/api/cron/youtube-sync` | Nur YouTube |
|
||||
|
||||
### CommunityRules (Automatisierung)
|
||||
|
||||
**Trigger-Typen:** `keyword`, `sentiment`, `question_detected`, `medical_detected`, `influencer` (>10k Follower), `all_new`, `contains_link`, `contains_email`
|
||||
|
||||
**Aktionen:** `set_priority`, `assign_to`, `set_flag`, `suggest_template`, `send_notification`, `flag_medical`, `escalate`, `mark_spam`, `set_deadline`
|
||||
|
||||
### Wichtige Dateien
|
||||
|
||||
```
|
||||
src/lib/integrations/meta/
|
||||
├── MetaBaseClient.ts # HTTP-Basis mit Retry + Pagination
|
||||
├── FacebookClient.ts # Facebook Graph API Client
|
||||
├── InstagramClient.ts # Instagram Graph API Client
|
||||
├── FacebookSyncService.ts # Facebook Kommentar-Sync
|
||||
├── InstagramSyncService.ts # Instagram Kommentar-Sync
|
||||
├── oauth.ts # Meta OAuth 2.0 Flow
|
||||
└── index.ts # Re-Exports
|
||||
|
||||
src/lib/jobs/
|
||||
├── UnifiedSyncService.ts # Orchestriert alle Plattform-Syncs
|
||||
├── syncAllComments.ts # YouTube-spezifischer Sync (Legacy)
|
||||
└── JobLogger.ts # Strukturiertes Logging
|
||||
|
||||
src/app/(payload)/api/
|
||||
├── auth/meta/ # OAuth Start + Callback
|
||||
├── community/ # Community-Endpoints
|
||||
└── cron/community-sync/ # Cron-Trigger
|
||||
```
|
||||
|
||||
## Timeline Collection
|
||||
|
||||
Dedizierte Collection für chronologische Darstellungen.
|
||||
|
||||
**Typen:** `history`, `milestones`, `releases`, `career`, `events`, `process`
|
||||
|
||||
**Event-Features:** Flexible Datumsformate, Kategorien, Wichtigkeitsstufen, Bilder, Links, Rich-Text
|
||||
|
||||
**Display-Optionen:** Layouts (vertikal, alternierend, horizontal, kompakt), Sortierung, Gruppierung nach Jahr
|
||||
|
||||
**Prozess-spezifische Felder (type=process):**
|
||||
- `stepNumber`, `duration`, `responsible`, `actionRequired`, `deliverables`
|
||||
|
||||
**API:** `GET /api/timelines?tenant=1[&type=history][&slug=...][&locale=en]`
|
||||
|
||||
## Workflows Collection
|
||||
|
||||
Komplexe Prozess-Darstellungen mit Phasen, Abhängigkeiten und Status-Tracking.
|
||||
|
||||
**Typen:** `project`, `business`, `approval`, `onboarding`, `support`, `development`, `marketing`, `other`
|
||||
|
||||
**Phasen-Struktur:**
|
||||
```
|
||||
Workflow → Phasen (Array)
|
||||
→ name, description, icon, color, estimatedDuration, responsible, deliverables
|
||||
→ Schritte (Array)
|
||||
→ name, description, stepType, priority, dependencies, conditions, checklist, resources, outputs
|
||||
```
|
||||
|
||||
**Display:** Layouts (vertical, horizontal, flowchart, kanban, gantt), Farbschema (phase, status, priority, brand)
|
||||
|
||||
**API:** `GET /api/workflows?tenant=1[&type=project][&complexity=medium][&slug=...][&locale=en]`
|
||||
|
||||
## HeroSliderBlock Features
|
||||
|
||||
**Slides (1-10):** Hintergrundbild (Desktop + Mobil), Headline + Subline (lokalisiert), Text-Ausrichtung, Overlay (Farbe, Deckkraft, Gradient), 2 CTA-Buttons
|
||||
|
||||
**Animationen:** fade, slide, zoom, flip, none (300-1200ms)
|
||||
|
||||
**Autoplay:** Intervall 3-10s, Pause bei Hover/Interaktion
|
||||
|
||||
**Navigation:** Pfeile (verschiedene Stile), Dots (Punkte, Striche, Nummern, Thumbnails, Fortschritt), Touch-Swipe, Tastatur
|
||||
|
||||
**Layout:** Höhe (Vollbild bis kompakt), Mobile-Höhe, Content-Breite
|
||||
|
||||
## CI/CD Pipeline Details
|
||||
|
||||
### ci.yml (Main CI Pipeline)
|
||||
Läuft bei Push/PR auf `main` und `develop`:
|
||||
- **lint:** ESLint (flat config, 0 errors)
|
||||
- **typecheck:** TypeScript Compiler (`tsc --noEmit`, 4GB heap)
|
||||
- **test:** Unit & Integration Tests (Vitest)
|
||||
- **build:** Next.js Production Build
|
||||
- **e2e:** Playwright E2E Tests
|
||||
|
||||
### security.yml
|
||||
Gitleaks (Secret Scanning), pnpm audit, CodeQL (SAST), Security Tests
|
||||
|
||||
### deploy-staging.yml
|
||||
- Trigger: Push auf `develop` oder manual dispatch
|
||||
- Ablauf: Pre-checks → SSH → Git Pull → Dependencies → Migrations → Build → PM2 Restart → Health Check
|
||||
- Secret: `STAGING_SSH_KEY`
|
||||
|
||||
```bash
|
||||
# Manuelles Staging-Deployment
|
||||
./scripts/deploy-staging.sh
|
||||
./scripts/deploy-staging.sh --skip-build
|
||||
./scripts/deploy-staging.sh --skip-migrations
|
||||
```
|
||||
|
||||
### deploy-production.yml
|
||||
- Trigger: Manual dispatch
|
||||
- Features: Pre-flight Checks, Database Backup, Health Check, Auto-Rollback
|
||||
- Secrets: `STAGING_SSH_KEY`, `PRODUCTION_SSH_KEY`
|
||||
|
||||
```bash
|
||||
gh workflow run deploy-production.yml # Via GitHub Actions
|
||||
./scripts/deploy-production.sh # Auf Server
|
||||
./scripts/deploy-production.sh --rollback # Rollback
|
||||
./scripts/deploy-production.sh --dry-run # Dry-Run
|
||||
```
|
||||
|
||||
## PgBouncer Connection Pooling
|
||||
|
||||
Läuft auf dem App-Server (127.0.0.1:6432), pooled Verbindungen zu PostgreSQL (10.10.181.101:5432).
|
||||
|
||||
**Konfiguration:** `/etc/pgbouncer/pgbouncer.ini`
|
||||
|
||||
| Parameter | Wert |
|
||||
|-----------|------|
|
||||
| pool_mode | transaction |
|
||||
| default_pool_size | 20 |
|
||||
| min_pool_size | 5 |
|
||||
| reserve_pool_size | 5 |
|
||||
| max_db_connections | 50 |
|
||||
| max_client_conn | 200 |
|
||||
|
||||
**TLS:** `server_tls_sslmode = require` (TLS 1.3)
|
||||
|
||||
```bash
|
||||
# Statistiken
|
||||
PGPASSWORD="$DB_PASSWORD" psql -h 127.0.0.1 -p 6432 -U payload -d pgbouncer -c "SHOW POOLS;"
|
||||
|
||||
# Direkte Verbindung für Migrationen (umgeht PgBouncer)
|
||||
./scripts/db-direct.sh migrate
|
||||
./scripts/db-direct.sh psql
|
||||
```
|
||||
|
||||
## Cron Jobs (Details)
|
||||
|
||||
Alle erfordern `Authorization: Bearer $CRON_SECRET`.
|
||||
|
||||
```bash
|
||||
# Community Sync manuell
|
||||
curl -X POST "https://your-domain/api/cron/community-sync" \
|
||||
-H "Authorization: Bearer $CRON_SECRET" \
|
||||
-d '{"platforms": ["youtube", "facebook"]}'
|
||||
|
||||
# Token Refresh (Dry-Run)
|
||||
curl "https://your-domain/api/cron/token-refresh?dryRun=true" \
|
||||
-H "Authorization: Bearer $CRON_SECRET"
|
||||
```
|
||||
|
||||
**Monitoring:**
|
||||
- HEAD-Requests: Status-Header (`X-Sync-Running`, `X-Last-Run`)
|
||||
- Bei laufendem Job: HTTP 423 (Locked)
|
||||
- Fehlerhafte Tokens → `yt-notifications`
|
||||
Loading…
Reference in a new issue