Zum Hauptinhalt springen

Production-Release-Checkliste (develop → main)

Vor jedem Merge nach main (= Production-Deploy) abarbeiten. Punkt 1 ist der häufigste Stolperstein — Production-Migrationen laufen NICHT automatisch.

1. 🔴 Datenbank-Migrationen anwenden (KRITISCH)​

Preview/develop migriert automatisch (webapp/scripts/migrate-deploy.mjs), Production aber bewusst NICHT. Sonst bricht nach dem Deploy jeder Login mit P2022 (fehlende Spalte).

cd webapp
# Prod-Connection, Neon: UNPOOLED/direkt (Host OHNE -pooler):
$env:DATABASE_URL = "<Production DATABASE_URL_UNPOOLED>"
npx prisma migrate status # zeigt fehlende Migrationen (read-only)
npx prisma migrate deploy # spielt sie ein – kein Datenverlust
  • ☑ In der „Datasource"-Zeile steht der Prod-Host (nicht dev/preview)!
  • ☑ Bei einer Drift-Meldung: stoppen und klären, nicht blind deployen.

2. Env-Variablen im Scope Production (Vercel) prüfen​

GitHub/Auth/Stripe lesen einfache Namen (kein DEVELOP_-Präfix); für Production müssen sie im Production-Scope gesetzt sein:

  • ☑ DATABASE_URL, DATABASE_URL_UNPOOLED → Prod-DB
  • ☑ AUTH_SECRET
  • ☑ GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET → Production-OAuth-App
  • ☑ STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, NEXT_PUBLIC_STRIPE_TRIAL_PROCUCT_PRICE_ID
  • ☑ NEXT_PUBLIC_URL (Prod-Domain), BLOB_READ_WRITE_TOKEN, BLOB_PRIVATE_READ_WRITE_TOKEN, FILE_ENCRYPTION_KEY, CRON_SECRET

3. GitHub-OAuth für Production​

  • ☑ Eigene OAuth-App für Production oder Callback der Prod-Domain ergänzen.
  • ☑ Authorization callback URL = https://<prod-domain>/api/auth/callback/github.

4. Rollen / Permissions​

  • ☑ Tabelle permissions abgleichen: Weder prisma migrate deploy noch ein Deploy füllt sie, ohne diesen Schritt bleibt die Rechtematrix leer oder neue Rechte fehlen. pnpm permissions:sync mit der Prod-Connection aus Punkt 1 ausführen und die Ausgabe prüfen (siehe Berechtigungssystem). Sobald es produktive Mandanten gibt, läuft das stattdessen über Migrationen.
  • ☑ Custom-Rollen, die den Stundenplan pflegen, brauchen timetable:* — seit dem Permission-Gate (Audit-PR #33) werden sie sonst serverseitig abgewiesen (ADMIN unbetroffen).

5. Merge & Verifikation​

  • ☑ PR develop → main erstellen, CI grün abwarten.
  • ☑ Nach dem Deploy auf der Prod-Domain testen: Login (GitHub + E-Mail/Passwort), Datei Up-/Download, Stripe-Checkout, eine Vertretung anlegen.
  • ☑ Altbestand in den privaten Store umziehen, erst wenn der neue Code live ist: In webapp mit den Production-Werten von DATABASE_URL, BLOB_READ_WRITE_TOKEN, BLOB_PRIVATE_READ_WRITE_TOKEN und FILE_ENCRYPTION_KEY zuerst pnpm files:migrate-private (zählt nur), dann pnpm files:migrate-private --apply ausführen, siehe Altbestand umziehen. Bis dahin bleiben nicht öffentliche Altdateien im öffentlichen Store. Die Gegenprobe im Skript erkennt keinen falschen Schlüssel, unbedingt den Production-Schlüssel verwenden.

6. Aufgeschobene Security-Punkte (vor echtem Live-Gang bewerten)​

Noch offen aus dem Audit (siehe lokal tasks/audit-security.md):

  • ☑ Öffentliche Datei-Blobs (DSGVO-relevant) — mit #127 behoben: Nicht öffentliche Dateien liegen verschlüsselt im privaten Store. In Production gilt das für den Altbestand erst nach dem Umzug aus Punkt 5.
  • ☑ Rate-Limiting auf Login-Pfaden.
  • ☑ Stripe-Webhook-Idempotenz.
Faustregel

Reihenfolge: erst Prod-DB migrieren (Punkt 1), dann nach main mergen. Nie umgekehrt.