cms.c2sgmbh/CLAUDE.md
Martin Porwoll a88e4f60d0 test: add E2E and integration tests with documentation
Tests:
- Update frontend.e2e.spec.ts with locale testing
- Add search.e2e.spec.ts for search functionality
- Add i18n.int.spec.ts for localization tests
- Add search.int.spec.ts for search integration
- Update playwright.config.ts

Documentation:
- Add CLAUDE.md with project instructions
- Add docs/ directory with detailed documentation
- Add scripts/ for utility scripts

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 08:19:52 +00:00

4 KiB

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)
  • Reverse Proxy: Caddy 2.10.2 mit Let's Encrypt
  • Process Manager: PM2
  • Package Manager: pnpm

Architektur

Internet → 37.24.237.181 → Caddy (443) → Payload (3000)
                                              ↓
                              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/
│       ├── Users.ts
│       ├── Media.ts
│       └── Tenants.ts
├── .env                       # Umgebungsvariablen
├── ecosystem.config.cjs       # PM2 Config
└── .next/                     # Build Output

Umgebungsvariablen (.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

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

# 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 restart payload

# Datenbank prüfen
PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db

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

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 nur 4GB RAM ohne Swap. Bei laufendem VS Code Server muss der Build mit reduziertem Memory ausgeführt werden:

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]/...
# Locales in der Datenbank prüfen
PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db -c "\dt *_locales"

URLs

Datenbank-Direktzugriff

PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db

# Nützliche Queries
SELECT * FROM tenants;
SELECT * FROM users_tenants;
\dt  -- Alle Tabellen
```All