diff --git a/BUG_REPORT_CUSTOM_VIEWS.md b/BUG_REPORT_CUSTOM_VIEWS.md new file mode 100644 index 0000000..fdd2ad4 --- /dev/null +++ b/BUG_REPORT_CUSTOM_VIEWS.md @@ -0,0 +1,126 @@ +# Bug Report: Custom Admin Views cause TypeError with path-to-regexp + +## Summary +Custom admin views registered via `admin.components.views` cause a `TypeError: Missing parameter name at 5` error from path-to-regexp when used together with `@payloadcms/plugin-multi-tenant`. + +## Environment +- **Payload Version:** 3.68.4 +- **Next.js Version:** 15.5.9 +- **React Version:** 19.2.3 +- **Node.js Version:** 22.x +- **Database:** PostgreSQL 17.6 +- **Plugin:** @payloadcms/plugin-multi-tenant 3.68.4 + +## Steps to Reproduce + +1. Create a Payload 3.x project with the multi-tenant plugin +2. Add a custom view to the admin config: + +```typescript +// payload.config.ts +export default buildConfig({ + admin: { + user: Users.slug, + components: { + views: { + MyCustomView: { + Component: '@/components/admin/MyCustomView#MyCustomView', + path: '/my-custom-view', + }, + }, + }, + }, + plugins: [ + multiTenantPlugin({ + tenantsSlug: 'tenants', + collections: { /* ... */ }, + }), + // other plugins... + ], +}) +``` + +3. Create a simple client component: + +```tsx +// src/components/admin/MyCustomView.tsx +'use client' + +import React from 'react' + +export const MyCustomView: React.FC = () => { + return ( +
+

Custom View

+
+ ) +} + +export default MyCustomView +``` + +4. Build and run the project +5. Navigate to `/admin/my-custom-view` + +## Expected Behavior +The custom view should render correctly. + +## Actual Behavior +A server-side error occurs with the following message in production: + +``` +Uncaught Error: An error occurred in the Server Components render. +The specific message is omitted in production builds to avoid leaking sensitive details. +``` + +When running in development or checking server logs, the actual error is: + +``` +⨯ TypeError: Missing parameter name at 5 + at (.next/server/chunks/XXXX.js:5:9989) + at (.next/server/chunks/XXXX.js:5:10666) + at g (.next/server/chunks/XXXX.js:5:11896) + at e (.next/server/chunks/824.js:96:517138) + at (.next/server/app/(payload)/admin/[[...segments]]/page.js:1:31665) + at Array.find () + at (.next/server/app/(payload)/admin/[[...segments]]/page.js:1:31644) + at ax (.next/server/app/(payload)/admin/[[...segments]]/page.js:1:34637) { + digest: '3964718924' +} +``` + +## Additional Context + +### What works: +- Admin panel without custom views +- Components in `afterNavLinks` (e.g., TenantBreadcrumb) +- Components in `beforeNavLinks` (e.g., DashboardNavLink) + +### What fails: +- ANY custom view registered via `admin.components.views`, even the simplest component without any dependencies + +### Investigation findings: +- The error originates from `path-to-regexp` (version 6.3.0) +- The error occurs during route matching in `handleEndpoints.js` +- The error message "Missing parameter name at 5" suggests an invalid route pattern like `/:` is being generated somewhere +- This happens regardless of the view path used (tested with `/dashboard`, `/tenant-dashboard`, `/test-dashboard`) +- The issue appears to be triggered by the combination of custom views and the multi-tenant plugin + +### Workaround +Disable custom views and use only `afterNavLinks`/`beforeNavLinks` components: + +```typescript +admin: { + components: { + afterNavLinks: ['@/components/admin/TenantBreadcrumb#TenantBreadcrumb'], + // views disabled due to bug + }, +}, +``` + +## Related Plugins +- `@payloadcms/plugin-multi-tenant` (may be related to the conflict) +- `@payloadcms/plugin-redirects` +- `@payloadcms/plugin-seo` +- `@payloadcms/plugin-form-builder` +- `@payloadcms/plugin-nested-docs` diff --git a/CLAUDE.md b/CLAUDE.md index 538fc7f..c028b2f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,31 +11,55 @@ Multi-Tenant CMS für 4 Websites unter einer Payload CMS 3.x Instanz: ## Tech Stack -- **CMS:** Payload CMS 3.x -- **Framework:** Next.js 15.4.7 +- **CMS:** Payload CMS 3.68.4 +- **Framework:** Next.js 15.5.9 +- **React:** 19.2.3 - **Sprache:** TypeScript -- **Datenbank:** PostgreSQL 17 (separater Server) +- **Runtime:** Node.js 22.x +- **Datenbank:** PostgreSQL 17.6 (separater Server) - **Connection Pool:** PgBouncer 1.24.1 (Transaction-Mode) -- **Reverse Proxy:** Caddy 2.10.2 mit Let's Encrypt +- **Reverse Proxy:** Caddy 2.9.x mit Let's Encrypt (Dev) / Nginx (Prod) - **Process Manager:** PM2 - **Package Manager:** pnpm -- **Cache:** Redis (optional, mit In-Memory-Fallback) +- **Cache:** Redis 7.x (optional, mit In-Memory-Fallback) - **Job Queue:** BullMQ (Redis-basiert) +- **Analytics:** Umami 3.x +- **AI Tools:** Claude Code, Codex CLI, Gemini CLI ## Architektur +### Development (VLAN 181 - porwoll.tech) + ``` -Internet → 37.24.237.181 → Caddy (443) → Payload (3000) - ↓ - PgBouncer (6432) - ↓ - PostgreSQL (10.10.181.101:5432) +Internet → Cloudflare → 37.24.237.181 → Caddy (sv-caddy) → Services + ↓ + ┌───────────────────────────┴───────────────────────────┐ + │ │ + sv-payload:3000 sv-frontend:3000-3008 + (Payload CMS) (9 Frontend-Projekte) + │ + PgBouncer (6432) + │ + PostgreSQL (sv-postgres:5432) ``` -| Server | IP | Funktion | -| --------------------- | ------------- | ---------- | -| sv-payload (LXC 700) | 10.10.181.100 | App Server | -| sv-postgres (LXC 701) | 10.10.181.101 | Datenbank | +| LXC | Hostname | IP | Service | Status | +|-----|----------|-----|---------|--------| +| 699 | sv-caddy | 10.10.181.99 | Caddy Reverse Proxy | ✅ Running | +| 700 | sv-payload | 10.10.181.100 | Payload CMS + Redis | ✅ Running | +| 701 | sv-postgres | 10.10.181.101 | PostgreSQL 17 + Redis Commander | ✅ Running | +| 702 | sv-dev-payload | 10.10.181.102 | Payload Experimental | ⏸️ Stopped | +| 703 | sv-analytics | 10.10.181.103 | Umami Analytics | ✅ Running | +| 704 | sv-frontend | 10.10.181.104 | Multi-Frontend Dev (9 Projekte) | ✅ Running | + +### Production (Hetzner 3) + +| Service | URL | Port | +|---------|-----|------| +| Payload CMS | https://cms.c2sgmbh.de | 3001 | +| Umami Analytics | https://analytics.c2sgmbh.de | 3000 | +| PostgreSQL 17 | localhost | 5432 | +| Redis Cache | localhost | 6379 | ## Wichtige Pfade @@ -758,6 +782,8 @@ Vollwertiger Hero-Slider mit: | Bookings | bookings | Fotografie-Buchungen (porwoll.de) | | Certifications | certifications | Zertifizierungen (C2S) | | Projects | projects | Game-Development-Projekte (gunshin.de) | +| Videos | videos | Video-Bibliothek mit YouTube/Vimeo/Uploads | +| VideoCategories | video-categories | Kategorien für Videos | ## Timeline Collection @@ -985,11 +1011,21 @@ Automatisches Deployment auf Staging-Server bei Push auf `develop`: ## Dokumentation -- `CLAUDE.md` - Diese Datei (Projekt-Übersicht) -- `docs/INFRASTRUCTURE.md` - Server-Architektur & Deployment +### Hauptdokumentation +- `CLAUDE.md` - Diese Datei (Projekt-Übersicht für AI-Assistenten) +- `docs/INFRASTRUCTURE.md` - Infrastruktur-Übersicht (Dev + Prod) +- `docs/DEPLOYMENT.md` - Deployment-Prozess & Checklisten +- `docs/PROJECT_STATUS.md` - Aktueller Projektstatus & Roadmap - `docs/STAGING-DEPLOYMENT.md` - Staging Deployment Workflow -- `docs/anleitungen/TODO.md` - Task-Liste & Roadmap + +### Anleitungen +- `docs/anleitungen/TODO.md` - Task-Liste & Changelog - `docs/anleitungen/SECURITY.md` - Sicherheitsrichtlinien +- `docs/anleitungen/FRONTEND.md` - Frontend-Entwicklung (sv-frontend) +- `docs/anleitungen/API_ANLEITUNG.md` - API-Dokumentation +- `docs/anleitungen/framework-monitoring.md` - Framework-Updates beobachten + +### Scripts & Backup - `scripts/backup/README.md` - Backup-System Dokumentation -*Letzte Aktualisierung: 14.12.2025* +*Letzte Aktualisierung: 18.12.2025* diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md new file mode 100644 index 0000000..03d8dbd --- /dev/null +++ b/docs/DEPLOYMENT.md @@ -0,0 +1,525 @@ +# Deployment Guide - Payload CMS Multi-Tenant + +*Letzte Aktualisierung: 18. Dezember 2025* + +## Übersicht + +Dieses Dokument beschreibt den Deployment-Prozess für das Payload CMS Multi-Tenant-System. + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ DEVELOPMENT │ │ STAGING │ │ PRODUCTION │ +│ │ │ │ │ │ +│ sv-frontend │────▶│ sv-payload │────▶│ Hetzner 3 │ +│ Local Dev │ │ pl.porwoll.tech │ │ cms.c2sgmbh.de │ +│ │ │ │ │ │ +│ develop branch │ │ develop branch │ │ main branch │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ +``` + +--- + +## Umgebungen + +| Umgebung | Server | URL | Branch | Zweck | +|----------|--------|-----|--------|-------| +| **Development** | sv-payload (LXC 700) | https://pl.porwoll.tech | `develop` | Entwicklung & Testing | +| **Production** | Hetzner 3 | https://cms.c2sgmbh.de | `main` | Live-System | + +--- + +## Staging Deployment (Development → pl.porwoll.tech) + +### Automatisch via GitHub Actions + +Bei jedem Push auf `develop` wird automatisch deployed: + +```yaml +# .github/workflows/deploy-staging.yml +on: + push: + branches: [develop] +``` + +**Ablauf:** +1. Pre-deployment Checks (Lint, Tests) +2. SSH-Verbindung zu sv-payload +3. `git pull origin develop` +4. `pnpm install` +5. `pnpm payload migrate` +6. `pnpm build` +7. `pm2 restart payload` +8. Health Check + +### Manuell auf sv-payload + +```bash +# SSH zum Server +ssh payload@10.10.181.100 + +# Ins Projektverzeichnis +cd /home/payload/payload-cms + +# Änderungen holen +git pull origin develop + +# Dependencies aktualisieren +pnpm install + +# Migrationen ausführen (falls vorhanden) +pnpm payload migrate + +# Build erstellen +pnpm build + +# PM2 neustarten +pm2 restart payload + +# Logs prüfen +pm2 logs payload --lines 20 +``` + +### Mit Deploy-Script + +```bash +# Auf sv-payload +./scripts/deploy-staging.sh + +# Optionen: +./scripts/deploy-staging.sh --skip-build # Nur Code-Update +./scripts/deploy-staging.sh --skip-migrations # Ohne Migrationen +``` + +--- + +## Production Deployment (main → cms.c2sgmbh.de) + +### Schritt 1: Merge zu main + +```bash +# Auf dem Development-Server oder lokal +git checkout main +git pull origin main +git merge develop +git push origin main +``` + +### Schritt 2: Deploy auf Hetzner 3 + +```bash +# SSH zum Production-Server +ssh payload@162.55.85.18 + +# Deploy-Script ausführen +~/deploy.sh +``` + +### Deploy-Script (~/deploy.sh) + +```bash +#!/bin/bash +set -e + +cd ~/payload-cms + +echo "📥 Pulling latest changes..." +git pull origin main + +echo "📦 Installing dependencies..." +pnpm install + +echo "🔄 Running migrations..." +pnpm payload migrate + +echo "🏗️ Building..." +pnpm build + +echo "🔄 Restarting PM2..." +pm2 restart payload + +echo "✅ Deployment complete!" +pm2 status +``` + +### Manuelles Deployment + +```bash +ssh payload@162.55.85.18 +cd ~/payload-cms +git pull origin main +pnpm install +pnpm payload migrate +pnpm build +pm2 restart payload +``` + +--- + +## Rollback + +### Auf vorherigen Commit zurücksetzen + +```bash +# Letzten funktionierenden Commit finden +git log --oneline -10 + +# Zurücksetzen (VORSICHT: Ändert History nicht) +git checkout +pnpm install +pnpm build +pm2 restart payload + +# Oder: Hard Reset (VORSICHT: Ändert History) +git reset --hard +git push --force origin main # Nur im Notfall! +``` + +### Datenbank-Rollback + +```bash +# Backup wiederherstellen (nur bei Datenverlust) +gunzip -c ~/backups/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz | \ + psql -h localhost -U payload -d payload_db +``` + +--- + +## Migrationen + +### Migration erstellen + +```bash +# Auf Development-Server +pnpm payload migrate:create + +# Generiert: src/migrations/YYYYMMDD_HHMMSS_.ts +``` + +### Migration ausführen + +```bash +# Normale Ausführung +pnpm payload migrate + +# Bei PgBouncer-Problemen: Direkte Verbindung +./scripts/db-direct.sh migrate +``` + +### Migration-Status prüfen + +```bash +pnpm payload migrate:status +``` + +--- + +## Build-Konfiguration + +### Memory-Limits + +Der Server hat 8GB RAM. Build-Einstellungen: + +```json +// package.json +{ + "scripts": { + "build": "cross-env NODE_OPTIONS='--no-deprecation --max-old-space-size=2048' next build" + } +} +``` + +### Bei Memory-Problemen + +```bash +# PM2 stoppen um Speicher freizugeben +pm2 stop payload + +# Build mit reduziertem Memory +NODE_OPTIONS="--no-deprecation --max-old-space-size=1024" pnpm build + +# PM2 wieder starten +pm2 start payload +``` + +--- + +## PM2 Konfiguration + +### ecosystem.config.cjs + +```javascript +module.exports = { + apps: [ + { + name: 'payload', + script: 'node_modules/.bin/next', + args: 'start', + cwd: '/home/payload/payload-cms', + instances: 1, + max_memory_restart: '2G', + env: { + NODE_ENV: 'production', + PORT: 3000 + } + }, + { + name: 'queue-worker', + script: './scripts/run-queue-worker.ts', + interpreter: 'node', + interpreter_args: '--import tsx', + cwd: '/home/payload/payload-cms', + instances: 1, + max_memory_restart: '500M' + } + ] +} +``` + +### PM2 Befehle + +```bash +pm2 status # Status aller Prozesse +pm2 logs payload # Logs anzeigen +pm2 logs queue-worker # Queue-Worker Logs +pm2 restart payload # Neustart +pm2 restart all # Alle neustarten +pm2 save # Autostart-Konfiguration speichern +pm2 startup # Systemd-Integration +``` + +--- + +## Health Checks + +### Nach Deployment prüfen + +```bash +# 1. PM2 Status +pm2 status + +# 2. Logs auf Fehler prüfen +pm2 logs payload --lines 50 + +# 3. API erreichbar? +curl -I https://cms.c2sgmbh.de/api/users + +# 4. Admin Panel erreichbar? +curl -I https://cms.c2sgmbh.de/admin + +# 5. Redis verbunden? +redis-cli ping +``` + +### Automatischer Health Check + +```bash +#!/bin/bash +# health-check.sh + +API_URL="https://cms.c2sgmbh.de/api" +ADMIN_URL="https://cms.c2sgmbh.de/admin" + +# API Check +if curl -sf "$API_URL/users" > /dev/null; then + echo "✅ API OK" +else + echo "❌ API FAILED" + exit 1 +fi + +# Admin Check +if curl -sf "$ADMIN_URL" > /dev/null; then + echo "✅ Admin OK" +else + echo "❌ Admin FAILED" + exit 1 +fi + +echo "✅ All checks passed" +``` + +--- + +## Umgebungsvariablen + +### Production (.env) + +```env +# Datenbank +DATABASE_URI=postgresql://payload:***@localhost:5432/payload_db +PAYLOAD_SECRET=*** + +# URLs +PAYLOAD_PUBLIC_SERVER_URL=https://cms.c2sgmbh.de +NEXT_PUBLIC_SERVER_URL=https://cms.c2sgmbh.de + +# Environment +NODE_ENV=production +PORT=3001 + +# Redis +REDIS_URL=redis://localhost:6379 + +# Security +CSRF_SECRET=*** +TRUST_PROXY=true +``` + +### Staging (.env) + +```env +# Datenbank (via PgBouncer) +DATABASE_URI=postgresql://payload:***@127.0.0.1:6432/payload_db +PAYLOAD_SECRET=*** + +# URLs +PAYLOAD_PUBLIC_SERVER_URL=https://pl.porwoll.tech +NEXT_PUBLIC_SERVER_URL=https://pl.porwoll.tech + +# Environment +NODE_ENV=production +PORT=3000 + +# Redis +REDIS_URL=redis://localhost:6379 + +# Security +CSRF_SECRET=*** +TRUST_PROXY=true +``` + +--- + +## CI/CD Pipeline + +### GitHub Actions Workflows + +| Workflow | Trigger | Aktion | +|----------|---------|--------| +| `ci.yml` | Push/PR auf main, develop | Lint, Test, Build | +| `security.yml` | Push/PR, Schedule | Security Scanning | +| `deploy-staging.yml` | Push auf develop | Auto-Deploy zu Staging | + +### Secrets (GitHub) + +| Secret | Beschreibung | +|--------|--------------| +| `STAGING_SSH_KEY` | SSH Private Key für sv-payload | + +### Manuelles Deployment triggern + +```bash +# Via GitHub CLI +gh workflow run deploy-staging.yml + +# Mit skip_tests Option +gh workflow run deploy-staging.yml -f skip_tests=true +``` + +--- + +## Backup vor Deployment + +### Automatisches Backup + +Backups laufen täglich um 03:00 Uhr. Vor großen Deployments manuell: + +```bash +# Auf Production +~/backup.sh + +# Auf Staging +/home/payload/backups/postgres/backup-db.sh --verbose +``` + +### Backup-Speicherorte + +| Server | Lokal | Offsite | +|--------|-------|---------| +| Production | ~/backups/ | - | +| Staging | /home/payload/backups/postgres/ | s3://c2s/backups/postgres/ | + +--- + +## Troubleshooting + +### Build schlägt fehl + +```bash +# Cache löschen +rm -rf .next +pnpm build + +# Mit mehr Speicher +NODE_OPTIONS="--max-old-space-size=4096" pnpm build +``` + +### PM2 startet nicht + +```bash +# Logs prüfen +pm2 logs payload --lines 100 + +# Prozess komplett entfernen und neu starten +pm2 delete payload +pm2 start ecosystem.config.cjs +``` + +### Datenbank-Verbindung fehlgeschlagen + +```bash +# PgBouncer Status (Staging) +sudo systemctl status pgbouncer + +# PostgreSQL Status (Production) +sudo systemctl status postgresql + +# Verbindung testen +psql -h localhost -U payload -d payload_db -c "SELECT 1" +``` + +### Migration fehlgeschlagen + +```bash +# Status prüfen +pnpm payload migrate:status + +# Bei PgBouncer-Problemen +./scripts/db-direct.sh migrate + +# Einzelne Migration manuell +pnpm payload migrate --name 20251216_073000_add_video_collections +``` + +--- + +## Checkliste + +### Vor dem Deployment + +- [ ] Alle Tests grün (`pnpm test`) +- [ ] Build erfolgreich (`pnpm build`) +- [ ] Migrationen getestet auf Staging +- [ ] Backup erstellt (bei Datenbank-Änderungen) +- [ ] CLAUDE.md/Docs aktualisiert (bei neuen Features) + +### Nach dem Deployment + +- [ ] `pm2 status` - Prozesse online +- [ ] Admin Panel erreichbar +- [ ] API funktioniert +- [ ] Logs auf Fehler geprüft +- [ ] Neue Features manuell getestet + +--- + +## Kontakte + +| Rolle | Kontakt | +|-------|---------| +| Server Admin | Martin Porwoll | +| Repository | https://github.com/complexcaresolutions/cms.c2sgmbh | + +--- + +*Dokumentation: Complex Care Solutions GmbH | 18.12.2025* diff --git a/docs/INFRASTRUCTURE.md b/docs/INFRASTRUCTURE.md index 1db94ec..ddcff69 100644 --- a/docs/INFRASTRUCTURE.md +++ b/docs/INFRASTRUCTURE.md @@ -1,85 +1,174 @@ -# Payload CMS Multi-Tenant Infrastructure +# Infrastruktur Dokumentation -> Letzte Aktualisierung: 09.12.2025 +*Letzte Aktualisierung: 18. Dezember 2025* -## Übersicht - -Diese Dokumentation beschreibt die Infrastruktur eines Payload CMS 3.x Multi-Tenant-Systems für den Betrieb mehrerer Websites unter einer zentralen CMS-Instanz. - -## Gesamtarchitektur +## Gesamtübersicht ``` ┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ GESAMTARCHITEKTUR │ +│ INFRASTRUKTUR ÜBERSICHT │ │ │ -│ ┌───────────────────────────────────────────────────────────────────────────────┐ │ -│ │ LOKALE ENTWICKLUNGSUMGEBUNG │ │ -│ │ (Proxmox VE Cluster) │ │ -│ │ LAN: 10.10.181.0/24 │ │ -│ │ │ │ -│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ -│ │ │ sv-payload │ │ sv-postgres │ │sv-dev-payload│ │sv-analytics │ │ │ -│ │ │ LXC 700 │ │ LXC 701 │ │ LXC 702 │ │ LXC 703 │ │ │ -│ │ │ Payload CMS │ │ PostgreSQL │ │ Next.js │ │ Umami │ │ │ -│ │ │10.10.181.100│ │10.10.181.101│ │10.10.181.102│ │10.10.181.103│ │ │ -│ │ │ + Redis │ │ │ │ │ │ │ │ │ -│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ -│ └───────────────────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌───────────────────┴───────────────────┐ │ -│ │ LOKALER INTERNETZUGANG │ │ -│ │ 850 Mbps ↓ / 50 Mbps ↑ │ │ -│ │ │ │ -│ │ Feste IP-Adressen: │ │ -│ │ 37.24.237.178 - Router │ │ -│ │ 37.24.237.179 - complexcaresolutions │ │ -│ │ 37.24.237.180 - Nginx Proxy Manager │ │ -│ │ 37.24.237.181 - pl.c2sgmbh.de │ │ -│ │ 37.24.237.182 - frei │ │ -│ └───────────────────┬───────────────────┘ │ -│ │ │ -│ INTERNET │ -│ │ │ -│ ┌──────────────────────────────────┼──────────────────────────────────┐ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │ -│ │ HETZNER 1 │ │ HETZNER 2 │ │ HETZNER 3 │ │ -│ │ CCS GmbH │ │ Martin Porwoll │ │ Backend/Analytics │ │ -│ │ │ │ │ │ │ │ -│ │ 78.46.87.137 │ │ 94.130.141.114 │ │ 162.55.85.18 │ │ -│ │ Debian 12.12 │ │ Ubuntu 24.04 │ │ Debian 13 │ │ -│ │ Plesk │ │ Plesk │ │ Native │ │ -│ │ │ │ │ │ │ │ -│ │ Next.js Frontends │ │ Next.js Frontends │ │ ✅ Payload CMS │ │ -│ │ • complexcare... │ │ • porwoll.de │ │ ✅ Umami │ │ -│ │ • gunshin.de │ │ • caroline-... │ │ ✅ PostgreSQL 17 │ │ -│ └─────────────────────┘ └─────────────────────┘ │ ✅ Redis Cache │ │ -│ │ ✅ Claude Code │ │ -│ └─────────────────────┘ │ +│ INTERNET │ +│ │ │ +│ │ Vodafone Business │ +│ │ 5 öffentliche IPs │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────────────────────┐ │ +│ │ UBIQUITI DREAM MACHINE PRO SE │ │ +│ │ │ │ +│ │ 37.24.237.178 │ Internetzugang │ │ +│ │ 37.24.237.179 │ cloud.complexcaresolutions.de → 10.10.179.100 │ │ +│ │ 37.24.237.180 │ zh3.de (Nginx PM) → 10.10.180.100 │ │ +│ │ 37.24.237.181 │ porwoll.tech (Caddy) → 10.10.181.99 │ │ +│ │ 37.24.237.182 │ FREI (Reserve) │ │ +│ │ │ │ +│ └──────────────────────────────────┬──────────────────────────────────────────┘ │ +│ │ +│ CLOUDFLARE (Proxy) │ +│ ├── zh3.de + Subdomains → 37.24.237.180 │ +│ ├── porwoll.tech + *.porwoll.tech → 37.24.237.181 │ +│ └── porwoll.org (intern DNS only) │ +│ │ +│ HETZNER (Extern) │ +│ ├── 78.46.87.137 (Hetzner 1 - zweitmeinu.ng) │ +│ ├── 94.130.141.114 (Hetzner 2 - Porwoll) │ +│ └── 162.55.85.18 (Hetzner 3 - Payload Prod) │ │ │ └─────────────────────────────────────────────────────────────────────────────────────┘ ``` --- -## Server-Details +## Öffentliche IP-Adressen -### HETZNER 3 - Backend & Analytics (Produktion) +| IP | Verwendung | Ziel (intern) | +|----|------------|---------------| +| 37.24.237.178 | Internetzugang (Default) | - | +| 37.24.237.179 | cloud.complexcaresolutions.de | 10.10.179.100 (Nextcloud) | +| 37.24.237.180 | zh3.de (via Cloudflare) | 10.10.180.100 (Nginx PM) | +| 37.24.237.181 | porwoll.tech (Cloudflare) | 10.10.181.99 (Caddy) | +| 37.24.237.182 | FREI (Reserve) | - | -| Eigenschaft | Wert | -|-------------|------| -| **Hostname** | sv-hz03-backend | -| **IP-Adresse** | 162.55.85.18 | -| **Betriebssystem** | Debian 13 "Trixie" | -| **CPU** | AMD Ryzen 5 3600 (6 Cores / 12 Threads) | -| **RAM** | 64 GB DDR4 ECC | -| **Storage** | 2x 512 GB NVMe SSD (Software RAID 1) | -| **Netzwerk** | 1 Gbit/s (garantiert) | -| **Traffic** | Unbegrenzt | -| **Kosten** | ~€52/Monat | +--- -#### Services auf Hetzner 3 +## VLANs + +| VLAN | Name | Subnetz | Zweck | +|------|------|---------|-------| +| 40 | c2s-prd | 10.10.40.0/24 | Produktion | +| 90 | c2s-mgt | 10.10.90.0/24 | Management (Proxmox) | +| 179 | c2s-179 | 10.10.179.0/24 | Cloud Services | +| 180 | c2s-180 | 10.10.180.0/24 | Web Services (zh3.de) | +| 181 | c2s-181 | 10.10.181.0/24 | Development (porwoll.tech) | + +--- + +## VLAN 181 - Development (porwoll.tech) + +| ID | Hostname | IP | Service | Status | +|----|----------|-----|---------|--------| +| 699 | sv-caddy | 10.10.181.99 | Caddy Reverse Proxy | ✅ Running | +| 700 | sv-payload | 10.10.181.100 | Payload CMS Dev | ✅ Running | +| 701 | sv-postgres | 10.10.181.101 | PostgreSQL 17 + Redis Commander | ✅ Running | +| 702 | sv-dev-payload | 10.10.181.102 | Payload Test | ⏸️ Stopped | +| 703 | sv-analytics | 10.10.181.103 | Umami Analytics | ✅ Running | +| 704 | sv-frontend | 10.10.181.104 | Frontend Dev (9 Projekte) | ✅ Running | + +--- + +## sv-frontend (LXC 704) - Frontend Development + +**SSH:** `ssh frontend@10.10.181.104` + +### Software Stack +- Node.js 22.x +- pnpm +- Next.js 16.0.10 +- Claude Code 2.0.72 +- Codex CLI 0.73.0 +- Gemini CLI 0.21.2 + +### Projekte & Ports + +| Port | Service | Repository | URL | +|------|---------|------------|-----| +| 3000 | frontend-porwoll | frontend.porwoll.de | porwoll-dev.porwoll.tech | +| 3001 | frontend-blogwoman | frontend.blogwoman.de | blogwoman-dev.porwoll.tech | +| 3002 | frontend-caroline-com | frontend.caroline-porwoll.com | caroline-com-dev.porwoll.tech | +| 3003 | frontend-caroline-de | frontend.caroline-porwoll.de | caroline-de-dev.porwoll.tech | +| 3004 | frontend-ccs | frontend.complexcaresolutions.de | ccs-dev.porwoll.tech | +| 3005 | frontend-gunshin | frontend.gunshin.de | gunshin-dev.porwoll.tech | +| 3006 | frontend-sensual | frontend.sensualmoment.de | sensual-dev.porwoll.tech | +| 3007 | frontend-zweitmeinu | frontend.zweitmeinu.ng | zweitmeinu-dev.porwoll.tech | +| 3008 | frontend-zytoskandal | frontend.zytoskandal.de | zytoskandal-dev.porwoll.tech | + +### Service-Verwaltung + +```bash +# Service starten +systemctl start frontend-porwoll + +# Service stoppen +systemctl stop frontend-porwoll + +# Alle Status +systemctl status frontend-* +``` + +--- + +## sv-caddy (LXC 699) - Reverse Proxy + +- **IP:** 10.10.181.99 +- **Software:** Caddy 2.9.x + Cloudflare DNS Plugin +- **SSL:** Wildcard *.porwoll.tech via Let's Encrypt DNS-Challenge +- **Config:** `/etc/caddy/Caddyfile` + +### Routing + +| URL | Backend | +|-----|---------| +| pl.porwoll.tech | 10.10.181.100:3000 | +| redis.porwoll.tech | 10.10.181.101:8081 | +| umami.porwoll.tech | 10.10.181.103:3000 | +| *-dev.porwoll.tech | 10.10.181.104:300x | + +--- + +## GitHub Organisation: complexcaresolutions + +| Repository | Beschreibung | Visibility | +|------------|--------------|------------| +| cms.c2sgmbh | Payload CMS Backend | Internal | +| frontend.porwoll.de | porwoll.de Frontend | Internal | +| frontend.blogwoman.de | blogwoman.de Frontend | Internal | +| frontend.caroline-porwoll.com | caroline-porwoll.com Frontend | Internal | +| frontend.caroline-porwoll.de | caroline-porwoll.de Frontend | Internal | +| frontend.complexcaresolutions.de | CCS Website Frontend | Internal | +| frontend.gunshin.de | gunshin.de Frontend | Internal | +| frontend.sensualmoment.de | sensualmoment.de Frontend | Internal | +| frontend.zweitmeinu.ng | zweitmeinu.ng Frontend | Internal | +| frontend.zytoskandal.de | zytoskandal.de Frontend | Internal | + +--- + +## Hetzner 3 - Payload Production + +- **IP:** 162.55.85.18 +- **Domain:** cms.c2sgmbh.de +- **User:** payload +- **SSH:** `ssh payload@162.55.85.18` + +### Software +- Payload CMS 3.68.4 +- Next.js 15.5.9 +- React 19.2.3 +- PostgreSQL 17 +- Redis +- Umami Analytics + +### Services | Service | User | Port | URL | Status | |---------|------|------|-----|--------| @@ -88,501 +177,66 @@ Diese Dokumentation beschreibt die Infrastruktur eines Payload CMS 3.x Multi-Ten | Umami Analytics | umami | 3000 | https://analytics.c2sgmbh.de | ✅ Läuft | | Redis Cache | redis | 6379 | localhost | ✅ Läuft | | Nginx | root | 80/443 | Reverse Proxy | ✅ Läuft | -| Claude Code | claude | - | CLI Tool | ✅ Installiert | - -#### System-User - -| User | Zweck | Home-Verzeichnis | -|------|-------|------------------| -| root | System-Administration | /root | -| payload | Payload CMS | /home/payload | -| umami | Umami Analytics | /home/umami | -| claude | Claude Code / Server-Admin | /home/claude | - ---- - -### HETZNER 1 - Complex Care Solutions GmbH - -| Eigenschaft | Wert | -|-------------|------| -| **Eigentümer** | Complex Care Solutions GmbH | -| **IP-Adresse** | 78.46.87.137 | -| **Betriebssystem** | Debian 12.12 | -| **Control Panel** | Plesk Web Pro Edition 18.0.73 | -| **CPU** | AMD Ryzen 7 Pro 8700GE | -| **RAM** | 64 GB | -| **Storage** | 2x 512 GB NVMe SSD (Software RAID 1) | - -#### Domains auf Hetzner 1 - -| Domain | Zweck | -|--------|-------| -| **complexcaresolutions.de** | Hauptdomain | -| **gunshin.de** | Portfolio/Holding | -| c2sgmbh.de | Kurzform → Redirect | -| zweitmeinung-*.de | Fachgebiete → Redirect | - ---- - -### HETZNER 2 - Martin Porwoll (privat) - -| Eigenschaft | Wert | -|-------------|------| -| **Eigentümer** | Martin Porwoll (privat) | -| **IP-Adresse** | 94.130.141.114 | -| **Betriebssystem** | Ubuntu 24.04 LTS | -| **Control Panel** | Plesk Web Pro Edition 18.0.73 | -| **CPU** | Intel Xeon E3-1275v6 | -| **RAM** | 64 GB | -| **Storage** | 2x 512 GB NVMe SSD (Software RAID 1) | - -#### Domains auf Hetzner 2 - -| Domain | Zweck | -|--------|-------| -| **porwoll.de** | Hauptdomain | -| **caroline-porwoll.de** | Dr. Caroline Porwoll | - ---- - -### Lokale Infrastruktur (Proxmox) - Entwicklung - -| Server | IP | Port | Funktion | OS | -|--------|-----|------|----------|-----| -| sv-payload | 10.10.181.100 | 3000 | Payload CMS (Dev) + Redis | Debian 13 | -| sv-postgres | 10.10.181.101 | 5432 | PostgreSQL (Dev) | Debian 13 | -| sv-dev-payload | 10.10.181.102 | 3001 | Next.js Frontend | Debian 13 | -| sv-analytics | 10.10.181.103 | 3000 | Umami (Dev) | Debian 13 | - -#### Feste IP-Adressen (Lokal → Internet) - -| IP | Verwendung | -|----|------------| -| 37.24.237.178 | Router / Gateway | -| 37.24.237.179 | complexcaresolutions.cloud | -| 37.24.237.180 | Nginx Proxy Manager | -| 37.24.237.181 | pl.c2sgmbh.de (Payload Dev) | -| 37.24.237.182 | **Frei** | - ---- - -## Credentials - -### Produktion (sv-hz03-backend) - -#### PostgreSQL - -| Datenbank | User | Passwort | -|-----------|------|----------| -| payload_db | payload | Suchen55 | -| umami_db | umami | Suchen55 | - -#### Redis +### Deploy ```bash -redis-cli -h localhost -p 6379 -# Kein Passwort (nur localhost) -``` - -#### Environment Variables - Payload (.env) - -```env -DATABASE_URI=postgresql://payload:Suchen55@localhost:5432/payload_db -PAYLOAD_SECRET=hxPARlMkmv+ZdCOAMw+N4o2x4mNbERB237iDQTYXALY= -PAYLOAD_PUBLIC_SERVER_URL=https://cms.c2sgmbh.de -NEXT_PUBLIC_SERVER_URL=https://cms.c2sgmbh.de -NODE_ENV=production -PORT=3001 -REDIS_HOST=localhost -REDIS_PORT=6379 -``` - -### Entwicklung (pl.c2sgmbh.de) - -#### PostgreSQL (sv-postgres) - -| Datenbank | User | Passwort | -|-----------|------|----------| -| payload_db | payload | Finden55 | - -#### Environment Variables (.env) - -```env -DATABASE_URI=postgresql://payload:Finden55@10.10.181.101:5432/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 -REDIS_HOST=localhost -REDIS_PORT=6379 +~/deploy.sh ``` --- -## Multi-Tenant Konzept - -Das System verwendet `@payloadcms/plugin-multi-tenant` für die Mandantenfähigkeit. - -### Tenants (Mandanten) - -Jeder Tenant repräsentiert eine separate Website: - -| Tenant | Slug | Domains | -|--------|------|---------| -| porwoll.de | porwoll | porwoll.de, www.porwoll.de | -| Complex Care Solutions GmbH | c2s | complexcaresolutions.de | -| Gunshin | gunshin | gunshin.de | - -### Datenisolation - -- Jeder Content (Media, Pages, Posts etc.) gehört zu genau einem Tenant -- User werden Tenants zugewiesen und sehen nur deren Inhalte -- Die Domain-Erkennung erfolgt automatisch durch das Plugin - -### Datenbank-Tabellen +## Development Workflow ``` -tenants - Mandanten-Stammdaten -tenants_domains - Domain-Zuordnungen -users_tenants - User-Mandanten-Beziehung (N:M) +DEVELOPMENT STAGING PRODUCTION +sv-frontend → sv-payload → Hetzner 03 +porwoll.tech pl.porwoll.tech cms.c2sgmbh.de + develop branch main branch ``` ---- - -## Redis Caching - -### Architektur - -``` -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ REDIS CACHING STRATEGIE │ -│ │ -│ Request → Payload CMS → Redis Cache? │ -│ │ │ -│ ┌────┴────┐ │ -│ HIT MISS │ -│ │ │ │ -│ ▼ ▼ │ -│ Return PostgreSQL → Cache in Redis → Return │ -│ │ -│ Cache-Typen: │ -│ • API Response Cache (GET /api/pages, /api/posts) │ -│ • Automatische Invalidierung bei Content-Änderungen │ -│ │ -│ Konfiguration: │ -│ • Max Memory: 2GB (Prod) / 512MB (Dev) │ -│ • Eviction: allkeys-lru │ -│ • TTL: 5 Minuten (Standard) │ -│ │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Redis Befehle - -```bash -# Status prüfen -redis-cli ping - -# Statistiken -redis-cli info stats - -# Cache-Keys anzeigen -redis-cli keys "*" - -# Cache leeren -redis-cli flushdb - -# Live-Monitoring -redis-cli monitor -``` - -### Background Jobs (geplant) - -**Evaluation (09.12.2025): BullMQ vs Agenda.js** - -| Kriterium | BullMQ | Agenda.js | -|-----------|--------|-----------| -| Database | Redis ✅ | MongoDB ❌ | -| TypeScript | Native ✅ | Begrenzt ⚠️ | -| Priority Jobs | Ja ✅ | Nein ❌ | -| Rate Limiting | Ja ✅ | Nein ❌ | -| UI Dashboard | @bull-board ✅ | Keine ❌ | - -**Entscheidung: BullMQ** (Redis bereits vorhanden, TypeScript-native, @bull-board UI) - -**Geplante Konfiguration:** -```bash -# Environment Variables (wenn implementiert) -QUEUE_REDIS_URL=redis://localhost:6379/1 # Separate DB für Jobs -QUEUE_CONCURRENCY=5 # Parallele Worker -QUEUE_DEFAULT_RETRY=3 # Wiederholungsversuche -``` - -**PM2 Worker-Konfiguration (geplant):** -```javascript -// ecosystem.config.cjs - Erweiterung -{ - name: 'queue-worker', - script: './scripts/run-queue-worker.ts', - instances: 1, - max_memory_restart: '500M' -} -``` - ---- - -## Deployment Workflow - -``` -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ DEPLOYMENT WORKFLOW │ -│ │ -│ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ │ -│ │ ENTWICKLUNG (DEV) │ │ PRODUKTION (PROD) │ │ -│ │ pl.c2sgmbh.de │ │ cms.c2sgmbh.de │ │ -│ │ 37.24.237.181 │ │ 162.55.85.18 │ │ -│ └──────────────────────────────────┘ └──────────────────────────────────┘ │ -│ │ -│ Step 1: CODE ENTWICKELN │ -│ ┌────────────────────────────────────────────────────────────────────────┐ │ -│ │ cd /home/payload/payload-cms │ │ -│ │ pnpm dev # Lokal testen │ │ -│ │ pnpm build # Build-Test │ │ -│ │ pm2 restart payload # Auf Dev-Server deployen │ │ -│ └────────────────────────────────────────────────────────────────────────┘ │ -│ ↓ │ -│ │ -│ Step 2: ZU GITHUB PUSHEN │ -│ ┌────────────────────────────────────────────────────────────────────────┐ │ -│ │ git add . # Alle Änderungen stagen │ │ -│ │ git commit -m "feat: XYZ" # Commit erstellen │ │ -│ │ git push origin main # Zu GitHub pushen │ │ -│ └────────────────────────────────────────────────────────────────────────┘ │ -│ ↓ │ -│ │ -│ ┌────────────────────────────────────────────────────┐ │ -│ │ GITHUB REPOSITORY (PRIVAT) │ │ -│ │ https://github.com/c2s-admin/cms.c2sgmbh │ │ -│ └────────────────────────────────────────────────────┘ │ -│ ↓ │ -│ │ -│ Step 3: AUF PRODUKTION DEPLOYEN │ -│ ┌────────────────────────────────────────────────────────────────────────┐ │ -│ │ ssh payload@162.55.85.18 │ │ -│ │ ~/deploy.sh # Automatisches Deployment │ │ -│ │ │ │ -│ │ Das deploy.sh Script macht: │ │ -│ │ ├─ git pull origin main # Code von GitHub holen │ │ -│ │ ├─ pnpm install # Dependencies aktualisieren │ │ -│ │ ├─ pnpm build # Produktions-Build │ │ -│ │ └─ pm2 restart payload # Service neustarten │ │ -│ └────────────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -``` - -### Git-Setup auf Servern - -| Server | User | Remote | Auth-Methode | Status | -|--------|------|--------|--------------|--------| -| pl.c2sgmbh.de (Dev) | payload | HTTPS | GitHub CLI (`gh auth`) | ✅ Konfiguriert | -| cms.c2sgmbh.de (Prod) | payload | SSH | SSH-Key | ✅ Eingerichtet | - -### Deployment-Befehle - -**Entwicklungsserver → GitHub:** - -```bash -cd /home/payload/payload-cms -git status -pnpm build -pm2 restart payload -git add . -git commit -m "feat: Beschreibung der Änderung" -git push origin main -``` - -**GitHub → Produktionsserver:** - -```bash -# Option A: SSH + Deploy-Script (empfohlen) -ssh payload@162.55.85.18 '~/deploy.sh' - -# Option B: Manuelles SSH-Login -ssh payload@162.55.85.18 -cd ~/payload-cms -git pull origin main -pnpm install -pnpm build -pm2 restart payload -``` - ---- - -## Backup - -### Backup-Script (~/backup.sh) - -```bash -#!/bin/bash -set -e - -BACKUP_DIR=~/backups -DATE=$(date +%Y-%m-%d_%H-%M-%S) -RETENTION_DAYS=7 - -mkdir -p $BACKUP_DIR - -# PostgreSQL Backup -PGPASSWORD=Suchen55 pg_dump -h localhost -U payload payload_db > $BACKUP_DIR/payload_db_$DATE.sql -gzip $BACKUP_DIR/payload_db_$DATE.sql - -# Alte Backups löschen -find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete -``` - -### Cronjob (täglich 3:00 Uhr) - -``` -0 3 * * * /home/payload/backup.sh >> /home/payload/backups/backup.log 2>&1 -``` - ---- - -## Service-Management - -### PM2 Befehle - -```bash -pm2 status # Status -pm2 logs payload # Logs -pm2 restart payload # Neustart -pm2 save # Autostart speichern -``` - -### Systemd Services - -```bash -# PostgreSQL -systemctl status postgresql -systemctl restart postgresql - -# Nginx -systemctl status nginx -systemctl restart nginx -nginx -t # Config testen - -# Redis -systemctl status redis-server -systemctl restart redis-server -``` +**AI Tools:** Claude Code, Codex CLI, Gemini CLI, VS Code Remote-SSH --- ## URLs Übersicht -| Service | Entwicklung | Produktion | -|---------|-------------|------------| -| Payload Admin | https://pl.c2sgmbh.de/admin | https://cms.c2sgmbh.de/admin | -| Payload API | https://pl.c2sgmbh.de/api | https://cms.c2sgmbh.de/api | -| Umami | - | https://analytics.c2sgmbh.de | +### Development (porwoll.tech) + +| Service | URL | +|---------|-----| +| Portal | https://porwoll.tech | +| Payload CMS | https://pl.porwoll.tech | +| Redis Commander | https://redis.porwoll.tech | +| Umami Analytics | https://umami.porwoll.tech | +| Frontend porwoll.de | https://porwoll-dev.porwoll.tech | +| (8 weitere) | https://*-dev.porwoll.tech | + +### Production (Hetzner) + +| Service | URL | +|---------|-----| +| Payload Admin | https://cms.c2sgmbh.de/admin | +| Payload API | https://cms.c2sgmbh.de/api | +| Umami Analytics | https://analytics.c2sgmbh.de | --- -## SSH Schnellzugriff +## Quick Reference ```bash -# Produktion (Hetzner 3) -ssh root@162.55.85.18 # Root -ssh payload@162.55.85.18 # Payload User -ssh umami@162.55.85.18 # Umami User -ssh claude@162.55.85.18 # Claude Code +# Frontend-Server +ssh frontend@10.10.181.104 -# Hetzner Server -ssh root@78.46.87.137 # Hetzner 1 (CCS) -ssh root@94.130.141.114 # Hetzner 2 (Porwoll) +# Hetzner 3 Production +ssh payload@162.55.85.18 -# Entwicklung (Proxmox) -ssh payload@10.10.181.100 # sv-payload -ssh root@10.10.181.101 # sv-postgres +# Caddy neu laden +ssh root@10.10.181.99 "systemctl reload caddy" + +# Frontend Service starten +systemctl start frontend-porwoll ``` --- -## Netzwerk & Firewall - -### UFW Regeln auf sv-payload (Dev) - -```bash -22/tcp ALLOW 10.10.181.0/24 # SSH aus VLAN -80/tcp ALLOW Anywhere # HTTP (ACME) -443/tcp ALLOW Anywhere # HTTPS -``` - -### UFW Regeln auf sv-postgres (Dev) - -```bash -22/tcp ALLOW 10.10.181.0/24 # SSH aus VLAN -5432/tcp ALLOW 10.10.181.100 # PostgreSQL nur von Payload -``` - -### UFW Regeln auf sv-hz03-backend (Prod) - -```bash -22/tcp ALLOW Anywhere # SSH -80/tcp ALLOW Anywhere # HTTP -443/tcp ALLOW Anywhere # HTTPS -``` - ---- - -## SSL Zertifikate - -| Domain | Anbieter | Status | -|--------|----------|--------| -| pl.c2sgmbh.de | Let's Encrypt (Caddy) | Auto-Renewal | -| cms.c2sgmbh.de | Let's Encrypt (Certbot) | Auto-Renewal | -| analytics.c2sgmbh.de | Let's Encrypt (Certbot) | Auto-Renewal | - ---- - -## Tech Stack - -| Komponente | Technologie | Version | -|------------|-------------|---------| -| CMS | Payload CMS | 3.x | -| Framework | Next.js | 15.4.7 | -| Runtime | Node.js | 22.x | -| Datenbank | PostgreSQL | 17 | -| Cache | Redis | 7.x | -| Analytics | Umami | 3.x | -| Process Manager | PM2 | Latest | -| Package Manager | pnpm | Latest | -| Reverse Proxy (Dev) | Caddy | 2.10.2 | -| Reverse Proxy (Prod) | Nginx | Latest | -| SSL | Let's Encrypt | - | - ---- - -## DSGVO-Konformität - -Die Architektur wurde bewusst ohne Cloudflare designed: - -- Keine US-Dienste im Datenpfad für Admin-Zugriffe -- Direkte öffentliche IP statt Proxy -- Keine Auftragsverarbeiter-Verträge für CDN nötig -- Redakteur-IPs und Sessions bleiben in DE - ---- - -## Checkliste nach Deployment - -- [ ] `pm2 status` - Alle Prozesse online? -- [ ] `redis-cli ping` - Redis antwortet? -- [ ] Admin Panel erreichbar? -- [ ] `pm2 logs payload --lines 10` - Keine Fehler? - ---- - -*Stand: 09. Dezember 2025* +*Dokumentation: Martin Porwoll | Complex Care Solutions GmbH | 18.12.2025* diff --git a/docs/PROJECT_STATUS.md b/docs/PROJECT_STATUS.md new file mode 100644 index 0000000..bc0a1d2 --- /dev/null +++ b/docs/PROJECT_STATUS.md @@ -0,0 +1,206 @@ +# Projekt Status - Dezember 2025 + +**Stand:** 18. Dezember 2025 + +## Zusammenfassung + +Die komplette Entwicklungsinfrastruktur ist eingerichtet und funktionsfähig: +- Payload CMS Multi-Tenant (Dev + Prod) +- Multi-Frontend Development Environment +- AI-gestützte Entwicklungstools +- Reverse Proxy Stack (Caddy + Nginx) +- Analytics (Umami) + +--- + +## ✅ Abgeschlossen + +### Infrastruktur VLAN 181 (Development) + +| LXC | Hostname | IP | Service | Status | +|-----|----------|-----|---------|--------| +| 699 | sv-caddy | 10.10.181.99 | Caddy Reverse Proxy | ✅ Running | +| 700 | sv-payload | 10.10.181.100 | Payload CMS + Redis | ✅ Running | +| 701 | sv-postgres | 10.10.181.101 | PostgreSQL 17 + Redis Cmd | ✅ Running | +| 702 | sv-dev-payload | 10.10.181.102 | Payload Experimental | ⏸️ Stopped | +| 703 | sv-analytics | 10.10.181.103 | Umami Analytics | ✅ Running | +| 704 | sv-frontend | 10.10.181.104 | Multi-Project Next.js | ✅ Running | + +### Hetzner 3 (Production) + +- [x] Debian 13 Installation +- [x] PostgreSQL 17 mit payload_db und umami_db +- [x] Redis Cache +- [x] Payload CMS Production (cms.c2sgmbh.de) +- [x] Umami Analytics Production (analytics.c2sgmbh.de) +- [x] Nginx Reverse Proxy mit Let's Encrypt +- [x] PM2 Process Management +- [x] Claude Code CLI +- [x] Backup-Scripts (täglich) +- [x] CVE-2025-55182 Hotfix + +### Caddy Reverse Proxy (sv-caddy) + +- [x] Caddy 2.9.x mit Cloudflare DNS Plugin +- [x] Wildcard SSL für *.porwoll.tech +- [x] Cloudflare DNS-Challenge +- [x] Routing für alle Services +- [x] Security Headers + +### Payload CMS + +- [x] Multi-Tenant Plugin +- [x] Redis Caching +- [x] Package-Versionen synchronisiert: + - Next.js 15.5.9 + - React 19.2.3 + - Payload 3.68.4 +- [x] GitHub Repository (complexcaresolutions/cms.c2sgmbh) + +### sv-frontend (Multi-Project) + +- [x] Node.js 22.x + pnpm +- [x] AI-Tools installiert: + - Claude Code 2.0.72 + - Codex CLI 0.73.0 + - Gemini CLI 0.21.2 +- [x] 9 Frontend-Projekte initialisiert +- [x] Systemd Services (Ports 3000-3008) +- [x] SSH-Zugriff mit Key +- [x] VS Code Remote-SSH kompatibel + +### GitHub Repositories + +Organisation: **complexcaresolutions** (Internal) + +- [x] cms.c2sgmbh (Payload CMS) +- [x] frontend.porwoll.de +- [x] frontend.blogwoman.de +- [x] frontend.caroline-porwoll.com +- [x] frontend.caroline-porwoll.de +- [x] frontend.complexcaresolutions.de +- [x] frontend.gunshin.de +- [x] frontend.sensualmoment.de +- [x] frontend.zweitmeinu.ng +- [x] frontend.zytoskandal.de + +--- + +## ⚠️ Kritische Aufgaben + +| Priorität | Aufgabe | Status | +|-----------|---------|--------| +| 🔴 | Umami Dev Admin-Passwort ändern | Offen | +| 🔴 | auth.zh3.de - 502 Bad Gateway beheben | Offen | +| 🟡 | pve04/pve05/Backup: Enterprise Repo | Offen | + +--- + +## 🔜 Nächste Schritte + +### Kurzfristig (diese Woche) + +1. [ ] Porwoll.de Frontend-Entwicklung starten +2. [ ] VS Code Remote-SSH testen +3. [ ] Claude Code auf sv-frontend authentifizieren + +### Mittelfristig (Januar 2025) + +4. [ ] Frontend-Staging auf Hetzner 3 einrichten +5. [ ] GitHub Actions für Deployment +6. [ ] Content Collections in Payload erweitern +7. [ ] Design-System (Tailwind + Shadcn/UI) + +### Langfristig (Q1 2025) + +8. [ ] Alle 9 Frontends entwickeln +9. [ ] Migration von Plesk-Domains zu neuer Infra +10. [ ] CI/CD Pipeline komplett +11. [ ] Monitoring & Alerting + +--- + +## 📊 Service-URLs + +### Development (porwoll.tech) + +| Service | URL | Status | +|---------|-----|--------| +| Portal | https://porwoll.tech | ✅ | +| Payload CMS | https://pl.porwoll.tech | ✅ | +| Redis Commander | https://redis.porwoll.tech | ✅ | +| Umami Analytics | https://umami.porwoll.tech | ✅ | +| Frontend porwoll.de | https://porwoll-dev.porwoll.tech | ✅ | +| (8 weitere) | https://*-dev.porwoll.tech | ⏸️ On-Demand | + +### Production (Hetzner) + +| Service | URL | Status | +|---------|-----|--------| +| Payload CMS | https://cms.c2sgmbh.de | ✅ | +| Umami Analytics | https://analytics.c2sgmbh.de | ✅ | + +--- + +## 🔧 Quick Commands + +### sv-frontend + +```bash +# SSH Zugang +ssh frontend@10.10.181.104 + +# Service starten/stoppen +systemctl start frontend-porwoll +systemctl stop frontend-porwoll + +# AI-Tools +claude # Claude Code +codex # Codex CLI +gemini # Gemini CLI +``` + +### Hetzner 3 + +```bash +# SSH Zugang +ssh payload@162.55.85.18 + +# Deploy +~/deploy.sh + +# Logs +pm2 logs payload +``` + +--- + +## 📝 Änderungsprotokoll + +### 18.12.2025 +- sv-frontend (LXC 704) komplett eingerichtet +- 9 GitHub Repositories erstellt +- Alle Next.js Projekte initialisiert +- Systemd Services für alle Frontends +- Caddy Routing für *-dev.porwoll.tech +- AI-Tools (Claude Code, Codex, Gemini) installiert +- Infrastruktur-Dokumentation aktualisiert + +### 12.12.2025 +- sv-caddy mit Cloudflare DNS-Challenge +- Wildcard SSL für porwoll.tech +- Redis Commander auf sv-postgres +- pgAdmin4 entfernt (MIME-Type Probleme) + +### 11.12.2025 +- Hetzner 3 Production Setup +- Payload CMS Migration +- Umami Analytics Production +- Redis Caching (Dev + Prod) +- Package-Versionen synchronisiert + +### 26.11.2025 +- Initial Payload CMS Setup +- Multi-Tenant Plugin +- PostgreSQL auf sv-postgres +- Erste Tenants angelegt diff --git a/docs/anleitungen/Analytics.md b/docs/anleitungen/Analytics.md new file mode 100644 index 0000000..fc6b9aa --- /dev/null +++ b/docs/anleitungen/Analytics.md @@ -0,0 +1,981 @@ +# ANALYTICS-LÖSUNG: Implementierungsübersicht für Payload CMS + +*Letzte Aktualisierung: 18. Dezember 2025* + +## Kontext + +Du entwickelst das Multi-Tenant Payload CMS Backend und Next.js Frontend für 4 Websites. Diese Dokumentation beschreibt die Analytics-Lösung, die in das Frontend integriert werden muss. + +**Wichtig:** Frontends verwenden die **Production-API** (cms.c2sgmbh.de) und **Production-Analytics** (analytics.c2sgmbh.de). + +--- + +## Architektur-Übersicht + +``` +┌─────────────────────────────────────────────────────────────────────────────────────┐ +│ ANALYTICS ARCHITEKTUR │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────────────────┐ │ +│ │ OHNE CONSENT (immer aktiv) │ │ +│ │ │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ UMAMI ANALYTICS │ │ │ +│ │ │ │ │ │ +│ │ │ Server: sv-analytics (10.10.181.103:3000) │ │ │ +│ │ │ Dashboard: http://10.10.181.103:3000 │ │ │ +│ │ │ Script: /custom.js (Anti-Adblock) │ │ │ +│ │ │ Endpoint: /api/send │ │ │ +│ │ │ │ │ │ +│ │ │ Features: │ │ │ +│ │ │ • Cookieless Tracking (DSGVO-konform ohne Einwilligung) │ │ │ +│ │ │ • Pageviews, Sessions, Referrer, UTM-Parameter │ │ │ +│ │ │ • Custom Events (Newsletter, Formulare, CTAs, Downloads) │ │ │ +│ │ │ • 100% Erfassung aller Besucher │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────┘ │ │ +│ └─────────────────────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────────────────┐ │ +│ │ MIT CONSENT (Kategorie: "marketing") │ │ +│ │ │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ GOOGLE ADS CONVERSION │ │ │ +│ │ │ │ │ │ +│ │ │ Client-Side (bei Consent): │ │ │ +│ │ │ • Google Ads Tag (gtag.js) │ │ │ +│ │ │ • Conversion Tracking │ │ │ +│ │ │ • Remarketing Audiences │ │ │ +│ │ │ │ │ │ +│ │ │ Server-Side (immer, anonymisiert): │ │ │ +│ │ │ • Google Ads Conversion API │ │ │ +│ │ │ • Enhanced Conversions (gehashte E-Mail) │ │ │ +│ │ │ • GCLID-basierte Attribution │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ +│ │ │ GOOGLE CONSENT MODE v2 │ │ │ +│ │ │ │ │ │ +│ │ │ Integration mit bestehendem Orestbida Consent-Banner │ │ │ +│ │ │ Kategorie "marketing" steuert: │ │ │ +│ │ │ • ad_storage │ │ │ +│ │ │ • ad_user_data │ │ │ +│ │ │ • ad_personalization │ │ │ +│ │ └─────────────────────────────────────────────────────────────────────┘ │ │ +│ └─────────────────────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Infrastruktur + +### Umami Server + +| Umgebung | Server | URL | Dashboard | +|----------|--------|-----|-----------| +| **Production** | Hetzner 3 | https://analytics.c2sgmbh.de | https://analytics.c2sgmbh.de | +| **Development** | sv-analytics (LXC 703) | https://umami.porwoll.tech | https://umami.porwoll.tech | + +| Eigenschaft | Production | Development | +|-------------|------------|-------------| +| **Tracking Script** | https://analytics.c2sgmbh.de/script.js | https://umami.porwoll.tech/script.js | +| **API Endpoint** | https://analytics.c2sgmbh.de/api/send | https://umami.porwoll.tech/api/send | +| **Datenbank** | umami_db auf Hetzner 3 | umami_db auf sv-postgres | + +### Website-IDs (Multi-Tenant) + +Die Website-IDs werden in Umami für jeden Tenant erstellt: + +```typescript +// src/config/analytics.ts + +export const UMAMI_WEBSITE_IDS: Record = { + 'porwoll.de': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', + 'complexcaresolutions.de': 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy', + 'gunshin.de': 'zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz', + 'zweitmeinu.ng': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', +} + +// Production URL für Frontends +export const UMAMI_HOST = process.env.NEXT_PUBLIC_UMAMI_HOST || 'https://analytics.c2sgmbh.de' +``` + +--- + +## Frontend-Integration + +### 1. Umami Script Komponente + +```typescript +// src/components/analytics/UmamiScript.tsx + +'use client' + +import Script from 'next/script' + +interface UmamiScriptProps { + websiteId: string + host?: string +} + +export function UmamiScript({ + websiteId, + host = 'https://analytics.c2sgmbh.de' // Production default +}: UmamiScriptProps) { + if (!websiteId) return null + + return ( +