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
permissionsabgleichen: Wederprisma migrate deploynoch ein Deploy füllt sie, ohne diesen Schritt bleibt die Rechtematrix leer oder neue Rechte fehlen.pnpm permissions:syncmit 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→mainerstellen, 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
webappmit den Production-Werten vonDATABASE_URL,BLOB_READ_WRITE_TOKEN,BLOB_PRIVATE_READ_WRITE_TOKENundFILE_ENCRYPTION_KEYzuerstpnpm files:migrate-private(zählt nur), dannpnpm files:migrate-private --applyausfü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.