diff --git a/CLAUDE.md b/CLAUDE.md index 7447a4f..a049b22 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -245,6 +245,10 @@ pnpm build pnpm payload migrate:create pnpm payload migrate +# Schema-Sync (wichtig nach Collection-Änderungen!) +./scripts/sync-schema.sh --dry-run # Zeigt Änderungen +./scripts/sync-schema.sh # Führt Sync aus + # ImportMap nach Plugin-Änderungen pnpm payload generate:importmap @@ -277,6 +281,12 @@ scripts/backup/setup-backup.sh # Backup-System einricht 3. `pm2 restart payload` 4. Testen unter https://pl.porwoll.tech/admin +### Bei Collection/Global-Änderungen (zusätzlich) + +1. `pnpm payload migrate:create` - Migration erstellen +2. `git add src/migrations/` - Migration committen +3. Auf PROD nach Deployment: `./scripts/sync-schema.sh` wird automatisch ausgeführt + ## Bekannte Besonderheiten - **ES Modules:** package.json hat `"type": "module"`, daher PM2 Config als `.cjs` @@ -1009,12 +1019,44 @@ Automatisches Deployment auf Staging-Server bei Push auf `develop`: **GitHub Secret erforderlich:** - `STAGING_SSH_KEY` - SSH Private Key für `payload@37.24.237.181` +### deploy-production.yml (Production Deployment) +Manuelles Deployment auf Production-Server (Hetzner 3) bei workflow_dispatch: + +| Feature | Beschreibung | +|---------|--------------| +| Pre-flight Checks | Überprüft Branch-Status und Migrationen | +| Pre-deployment Tests | Optional, Lint + Unit Tests | +| Database Backup | Automatisches Backup vor Deployment | +| Health Check | Verifiziert erfolgreiche Deployment | +| Auto-Rollback | Bei fehlgeschlagenem Health Check | + +**Manuelles Production-Deployment:** +```bash +# Via GitHub Actions (empfohlen) +gh workflow run deploy-production.yml + +# Auf dem Production-Server (Hetzner 3) +ssh payload@162.55.85.18 +./scripts/deploy-production.sh + +# Mit Optionen +./scripts/deploy-production.sh -y # Ohne Bestätigung +./scripts/deploy-production.sh --skip-backup # Ohne Backup +./scripts/deploy-production.sh --rollback # Rollback zur vorherigen Version +./scripts/deploy-production.sh --dry-run # Zeigt was passieren würde +``` + +**GitHub Secrets erforderlich:** +- `STAGING_SSH_KEY` - SSH Private Key für sv-payload +- `PRODUCTION_SSH_KEY` - SSH Private Key für Hetzner 3 + ## Dokumentation ### 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/DEPLOYMENT_STRATEGY.md` - Vollständige Deployment-Strategie (Dev → Prod) - `docs/PROJECT_STATUS.md` - Aktueller Projektstatus & Roadmap - `docs/STAGING-DEPLOYMENT.md` - Staging Deployment Workflow diff --git a/docs/DEPLOYMENT_STRATEGY.md b/docs/DEPLOYMENT_STRATEGY.md index a051a72..13dcd77 100644 --- a/docs/DEPLOYMENT_STRATEGY.md +++ b/docs/DEPLOYMENT_STRATEGY.md @@ -174,6 +174,49 @@ Diese Strategie gewährleistet fehlerfreie Deployments von der Development-Umgeb --- +## Schema-Synchronisation + +### Problem: Schema-Drift + +Wenn neue Collections oder Globals auf DEV hinzugefügt werden, muss die PROD-Datenbank +entsprechend aktualisiert werden. Besonders die `payload_locked_documents_rels` Tabelle +benötigt für jede Collection eine eigene `*_id` Spalte. + +### Automatische Synchronisation (im Deploy-Script) + +Das Deploy-Script führt automatisch `drizzle-kit push` aus: + +```bash +# Im deploy-production.sh: +pnpm payload migrate # Payload-Migrationen +pnpm exec drizzle-kit push --force # Schema-Sync +``` + +### Manuelle Schema-Synchronisation + +```bash +# Auf dem Server: +cd ~/payload-cms + +# Dry-Run (zeigt was sich ändern würde) +./scripts/sync-schema.sh --dry-run + +# Schema synchronisieren +./scripts/sync-schema.sh + +# Oder mit --force für CI/Automation +./scripts/sync-schema.sh --force +``` + +### Best Practices + +1. **Nach Collection-Änderungen:** `pnpm payload migrate:create` auf DEV ausführen +2. **Migrations committen:** `git add src/migrations/` +3. **Schema-Datei prüfen:** `src/payload-generated-schema.ts` sollte aktuell sein +4. **Vor Deployment testen:** `./scripts/sync-schema.sh --dry-run` auf PROD + +--- + ## Rollback-Strategie ### Automatischer Rollback (GitHub Actions) diff --git a/drizzle.production.config.ts b/drizzle.production.config.ts new file mode 100644 index 0000000..f4f0ef7 --- /dev/null +++ b/drizzle.production.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'drizzle-kit' + +/** + * Drizzle config for production schema sync. + * Used by deploy script to push schema changes directly to database. + * + * Usage: + * DATABASE_URI="postgresql://..." pnpm exec drizzle-kit push --config=drizzle.production.config.ts + */ +export default defineConfig({ + schema: './src/payload-generated-schema.ts', + out: './drizzle', + dialect: 'postgresql', + dbCredentials: { + url: process.env.DATABASE_URI || '', + }, + // Safe mode - will prompt for destructive changes + strict: true, + verbose: true, +}) diff --git a/scripts/deploy-production.sh b/scripts/deploy-production.sh index f22e676..610cf6e 100755 --- a/scripts/deploy-production.sh +++ b/scripts/deploy-production.sh @@ -250,10 +250,14 @@ log "Installing dependencies..." pnpm install --frozen-lockfile success "Dependencies installed" -# Step 5: Run migrations +# Step 5: Run migrations and schema sync if [ "$SKIP_MIGRATIONS" = false ]; then log "Running database migrations..." pnpm payload migrate || warn "No migrations to run or migration failed" + + log "Syncing database schema with drizzle-kit..." + # Use drizzle-kit push to ensure schema is in sync (handles payload_locked_documents_rels etc.) + pnpm exec drizzle-kit push --config=drizzle.production.config.ts --force 2>/dev/null || warn "drizzle-kit push skipped or failed" else warn "Skipping migrations (--skip-migrations)" fi diff --git a/scripts/sync-schema.sh b/scripts/sync-schema.sh new file mode 100755 index 0000000..d5c1d18 --- /dev/null +++ b/scripts/sync-schema.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# ============================================================================= +# Schema Sync Script +# ============================================================================= +# Synchronizes the database schema with the Payload-generated schema. +# Use this after adding new Collections/Globals to ensure the database +# has all required tables and columns. +# +# Usage: +# ./scripts/sync-schema.sh # Interactive mode +# ./scripts/sync-schema.sh --force # Non-interactive (for CI/automation) +# ./scripts/sync-schema.sh --dry-run # Show what would change +# ============================================================================= + +set -e + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Parse arguments +FORCE=false +DRY_RUN=false + +for arg in "$@"; do + case $arg in + --force|-f) + FORCE=true + shift + ;; + --dry-run|-n) + DRY_RUN=true + shift + ;; + -h|--help) + head -15 "$0" | tail -12 + exit 0 + ;; + esac +done + +# Determine environment +if [ -f "/home/payload/payload-cms/.env" ]; then + source /home/payload/payload-cms/.env 2>/dev/null || true +fi + +PROJECT_DIR="${PROJECT_DIR:-/home/payload/payload-cms}" +cd "$PROJECT_DIR" + +echo -e "${BLUE}==============================================" +echo -e " Database Schema Sync" +echo -e "==============================================${NC}" +echo "" + +# Check if schema file exists +if [ ! -f "src/payload-generated-schema.ts" ]; then + echo -e "${YELLOW}Generating schema file...${NC}" + pnpm payload generate:db-schema 2>/dev/null || true +fi + +if [ ! -f "src/payload-generated-schema.ts" ]; then + echo -e "${RED}Error: Could not find or generate schema file${NC}" + exit 1 +fi + +# Dry run mode +if [ "$DRY_RUN" = true ]; then + echo -e "${YELLOW}[DRY RUN] Showing what would change:${NC}" + echo "" + pnpm exec drizzle-kit push --config=drizzle.production.config.ts --dry-run 2>&1 || true + exit 0 +fi + +# Interactive confirmation +if [ "$FORCE" != true ]; then + echo -e "${YELLOW}This will sync the database schema with the code.${NC}" + echo "Database: $DATABASE_URI" + echo "" + read -p "Continue? (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 + fi +fi + +# Run schema sync +echo "" +echo -e "${BLUE}Running drizzle-kit push...${NC}" +pnpm exec drizzle-kit push --config=drizzle.production.config.ts --force + +echo "" +echo -e "${GREEN}Schema sync complete!${NC}" +echo "" +echo "Next steps:" +echo " 1. Restart Payload: pm2 restart payload" +echo " 2. Test the admin panel"