diff --git a/CLAUDE.md b/CLAUDE.md index c9255e3..390aba3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,10 +38,25 @@ Internet → 37.24.237.181 → Caddy (443) → Payload (3000) /home/payload/payload-cms/ # Projektroot ├── src/ │ ├── payload.config.ts # Haupt-Konfiguration -│ └── collections/ -│ ├── Users.ts -│ ├── Media.ts -│ └── Tenants.ts +│ ├── collections/ # Alle Collections +│ │ ├── Users.ts +│ │ ├── Media.ts +│ │ ├── Tenants.ts +│ │ ├── Posts.ts +│ │ ├── Categories.ts +│ │ ├── Portfolios.ts +│ │ ├── PortfolioCategories.ts +│ │ ├── EmailLogs.ts +│ │ └── ... +│ ├── lib/ +│ │ ├── email/ # E-Mail-System +│ │ │ ├── tenant-email-service.ts +│ │ │ └── payload-email-adapter.ts +│ │ ├── search.ts # Volltextsuche +│ │ └── redis.ts # Redis Cache Client +│ └── hooks/ # Collection Hooks +│ ├── sendFormNotification.ts +│ └── invalidateEmailCache.ts ├── .env # Umgebungsvariablen ├── ecosystem.config.cjs # PM2 Config └── .next/ # Build Output @@ -56,6 +71,18 @@ 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 ``` ## Multi-Tenant Plugin @@ -145,15 +172,102 @@ PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db -c "\dt *_loc - **Admin Panel:** https://pl.c2sgmbh.de/admin - **API:** https://pl.c2sgmbh.de/api +- **E-Mail API:** https://pl.c2sgmbh.de/api/send-email (POST, Auth erforderlich) + +## 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": "

Inhalt

", + "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 + +## 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)) +``` ## Datenbank-Direktzugriff -````bash +```bash PGPASSWORD=Finden55 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; \dt -- Alle Tabellen -```All -```` +``` + +## 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 | +| NewsletterSubscribers | newsletter-subscribers | Newsletter mit Double Opt-In | +| SocialLinks | social-links | Social Media Links | +| Forms | forms | Formular-Builder | +| FormSubmissions | form-submissions | Formular-Einsendungen | +| EmailLogs | email-logs | E-Mail-Protokollierung | +| CookieConfigurations | cookie-configurations | Cookie-Banner Konfiguration | +| CookieInventory | cookie-inventory | Cookie-Inventar | +| ConsentLogs | consent-logs | Consent-Protokollierung | + +## Globals + +| Global | Slug | Beschreibung | +|--------|------|--------------| +| SiteSettings | site-settings | Allgemeine Website-Einstellungen | +| Navigation | navigation | Navigationsmenü | +| SEOSettings | seo-settings | SEO-Einstellungen | +| PrivacyPolicySettings | privacy-policy-settings | Datenschutz-Einstellungen | + +*Letzte Aktualisierung: 07.12.2025* diff --git a/docs/anleitungen/TODO.md b/docs/anleitungen/TODO.md index ba14fe4..a8ce7c5 100644 --- a/docs/anleitungen/TODO.md +++ b/docs/anleitungen/TODO.md @@ -86,10 +86,18 @@ - DNS-Einträge prüfen - Caddy-Konfiguration für alle Domains -- [ ] **[!] E-Mail-Adapter einrichten** - - SMTP-Konfiguration - - Newsletter Double Opt-In E-Mails - - Kontaktformular-Benachrichtigungen +- [x] **E-Mail-System** (Erledigt: 06.12.2025) + - [x] Multi-Tenant Email Adapter für Payload CMS + - [x] Tenant-spezifische SMTP-Konfiguration in Tenants Collection + - [x] EmailLogs Collection für Protokollierung aller E-Mails + - [x] REST-Endpoint `/api/send-email` mit: + - [x] Authentifizierung & Tenant-Zugriffskontrolle + - [x] Rate-Limiting (10 E-Mails/Minute pro User) + - [x] Form-Submission Notifications + - [x] Cache-Invalidierung bei Config-Änderungen + - [x] SMTP-Passwort-Schutz (nie in API-Responses) + - [ ] SMTP-Credentials in `.env` konfigurieren (TODO) + - [ ] Newsletter Double Opt-In E-Mails (TODO) - [ ] **[!] Frontend-Komponenten entwickeln** - React/Next.js Komponenten für alle Blocks @@ -162,10 +170,11 @@ - [ ] Google Ads API Credentials in Backend .env - Dokumentation: `docs/anleitungen/ANALYTICS_IMPLEMENTATION_GUIDE.md` -- [ ] **Caching-Strategie** - - Redis-Cache für API - - CDN-Integration (Cloudflare) - - Invalidierung bei Updates +- [x] **Redis Caching** (Erledigt: 05.12.2025) + - [x] Redis-Cache für API-Responses + - [x] TTL-basierte Invalidierung + - [x] Pattern-basierte Cache-Invalidierung + - [ ] CDN-Integration (Cloudflare) (TODO) - [~] **Backup-System** - [x] Manuelle Datenbank-Backups (pg_dump) @@ -195,9 +204,18 @@ - [ ] Leistungs-Übersicht - [ ] Karriere-Seite mit Stellenangeboten -### gunshin.de -- [ ] Portfolio-Collection -- [ ] Projekt-Galerie +### gunshin.de / Fotografin-Portfolio +- [x] Portfolio-Categories Collection (Erledigt: 06.12.2025) + - [x] Name, Slug, Beschreibung (lokalisiert) + - [x] Cover-Bild, Reihenfolge, Aktiv-Status +- [x] Portfolios Collection (Erledigt: 06.12.2025) + - [x] Titel, Beschreibung, Excerpt (lokalisiert) + - [x] Kategorie-Beziehung + - [x] Cover-Bild + Galerie-Bilder mit Captions + - [x] Projekt-Details (Kunde, Ort, Datum, Ausrüstung) + - [x] Status (draft/published/archived) + - [x] isFeatured, SEO-Felder +- [ ] Projekt-Galerie Frontend - [ ] Referenzen-Slider ### zweitmein.ng @@ -281,4 +299,4 @@ --- -*Letzte Aktualisierung: 05.12.2025 (Git & GitHub Setup, isSuperAdmin Feld, Techstack-Dokumentation)* +*Letzte Aktualisierung: 07.12.2025 (E-Mail-System, Portfolio-Collections, Redis Caching)*