diff --git a/CLAUDE.md b/CLAUDE.md index a33b1c5..8c28286 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ Multi-Tenant CMS für 3 aktive Websites unter einer Payload CMS 3.x Instanz: | sv-postgres | 10.10.181.101 | PostgreSQL 17 | | sv-frontend | 10.10.181.104 | Multi-Frontend Dev (9 Projekte) | -**Production (Hetzner 3):** `cms.c2sgmbh.de:3001` (Payload), `analytics.c2sgmbh.de:3000` (Umami) +**Production (Hetzner 3):** `Internet → Nginx (ModSecurity WAF) → localhost:3001` (Payload), `analytics.c2sgmbh.de:3000` (Umami) → Details: `docs/INFRASTRUCTURE.md` @@ -172,6 +172,7 @@ Beispiel: `src/migrations/20260109_020000_add_blogwoman_collections.ts` - **Tenant SMTP Save (Stand 17.02.2026):** Bei conditional `email.smtp` keine Feld-`required` auf `host/user`; stattdessen Group-`validate` verwenden. Tenant-Audit-Hook darf Admin-Save nicht mit `await` blockieren. - **TRUST_PROXY=true:** PFLICHT hinter Reverse-Proxy, sonst funktionieren Rate-Limiting und IP-Allowlists nicht - **CSRF_SECRET:** PFLICHT in Production (oder PAYLOAD_SECRET) - Server startet nicht ohne +- **ModSecurity WAF (Production):** Nginx auf Hetzner 3 hat OWASP CRS 3.3.7 in Blocking-Mode. `/admin` und `/api/` sind per Exclusion-Rules freigeschaltet (IDs 1000160/1000170). Bei neuen API-Pfaden außerhalb von `/api/` muss ggf. eine neue Exclusion-Rule in `/etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf` ergänzt werden. **Diagnose:** `curl localhost:3001/...` (JSON=Payload) vs `curl https://cms.c2sgmbh.de/...` (HTML=ModSecurity-Block) ## Build-Konfiguration