Phase-1-Vorbereitung für den Rebreak-Cutover (apps/rebreak Nuxt → backend
standalone Nitro). Alle Änderungen sind lokal verifiziert (build = 9.66 MB
gzipped 3.08 MB, node .output/server/index.mjs startet ohne ERR_MODULE_NOT_FOUND
auf :3000). Kein Push, kein Server-Eingriff in dieser Session.
Inhalt:
- backend/nitro.config.ts: 8 zusätzliche runtimeConfig-Keys (cartesia*, eleven*,
supabaseUrl/AnonKey/ServiceKey, public.supabase.{url,key}). Schließt den
Auth-500-Cascade vom 2026-05-06 (server/utils/auth.ts:32 liest
config.public.supabase ?? config.supabase — beide Pfade jetzt deklariert).
- .npmrc (NEU, root-level): node-linker=hoisted für Prisma 7 transitive
@prisma/client-runtime-utils (siehe feedback_backend_runtime_config.md).
- backend/start-staging.sh: Pfad korrigiert von /srv/rebreak-monorepo/...
→ /srv/rebreak/backend/.output-staging/server/index.mjs. infisical run
wrapper (kein NUXT_*-Mapping mehr — runtimeConfig liest process.env.X
direkt). IMAP-Services entfernt (sind Mo's Scope, separat in ecosystem).
- scripts/deploy.sh (NEU): adaptiert von /srv/rebreak/scripts/deploy.sh
für backend/-Layout. APP_DIR=backend, pnpm --filter rebreak-backend build,
.output → .output-staging atomic-move bleibt erhalten, pm2 restart
--update-env zieht neue Infisical-Secrets.
- scripts/deploy-webhook/server.mjs (NEU): 1:1-Kopie vom Server, damit
ecosystem.config.js auf die Repo-Version zeigen kann.
- ecosystem.config.js (NEU, root-level): rebreak-staging zeigt auf
backend/start-staging.sh, rebreak-webhook zeigt auf scripts/deploy-webhook.
rebreak-prod + dns-* sind kommentiert (folgen in späterer Phase).
- ops/CUTOVER_PLAN.md: Plan-Doku vom 2026-05-06 (yesterday's work).
- .gitignore: .claude/ und xgit ergänzt (lokale Agent-State, nicht versioniert).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 KiB
Rebreak Cutover-Plan: apps/rebreak/ (Nuxt) → backend/ (Standalone Nitro)
Verantwortlich: Backyard-Scope (Hetzner-Pipeline + Cutover-Architektur)
Erstellt: 2026-05-06
Status: PLAN — nicht ausgeführt. Alle destruktiven Schritte sind ⚠️-markiert und bedürfen explizitem User-Approval.
Server: ssh rebreak-server (49.13.55.22, rebreak-prod-01, CX23, 4 GB RAM)
Repo: git@github.com:RaynisDev/rebreak.git
1. Status quo (Stand 2026-05-06, post-rollback)
1.1 Server /srv/rebreak/ (live, Backyard's Layout)
/srv/rebreak/
├── apps/
│ ├── rebreak/ ← Nuxt-App (LIVE)
│ │ ├── nuxt.config.ts ← runtimeConfig (vollständig)
│ │ ├── start-staging.sh ← Infisical login + jq-eval + NUXT_*-Mapping
│ │ ├── server/api/... ← API-Routes
│ │ ├── .output-staging/ ← gebauter Output (pm2 fährt das)
│ │ ├── imap-proxy/ ← Mo's Scope
│ │ └── imap-idle/ ← Mo's Scope
│ └── rebreak-native/ ← React-Native-App
├── scripts/
│ ├── deploy.sh ← cd apps/rebreak + pnpm --filter @trucko/rebreak build
│ └── deploy-webhook/server.mjs ← GitHub HMAC validator → spawnt deploy.sh
├── ecosystem.config.js ← pm2 zeigt auf apps/rebreak/start-staging.sh
└── ops/nginx/ ← Source-tracking only (nicht live)
- Git-HEAD:
6eca0b5(rolled back, Backyard's working state) - Branch:
main - Remote-main:
6eca0b5(force-pushed back to safe state) - pm2:
rebreak-stagingonline,rebreak-imap-stagingonline,rebreak-idle-stagingonline,rebreak-webhookonline - Smoke-Tests:
https://staging.rebreak.org/→ 200,/api/auth/me→ 401 (correct).
1.2 Mac ~/mono/rebreak-monorepo/ (Cutover-Target)
~/mono/rebreak-monorepo/
├── backend/ ← Standalone Nitro (NEU)
│ ├── nitro.config.ts ← runtimeConfig UNVOLLSTÄNDIG (siehe §3)
│ ├── start-staging.sh ← infisical run wrapper, zeigt auf /srv/rebreak-monorepo/backend/.output/server/index.mjs
│ ├── package.json ← name: rebreak-backend
│ ├── prisma/ ← Prisma 7
│ ├── server/api/...
│ └── tsconfig.json
├── apps/rebreak-native/
├── ops/nginx/ ← gleiche Source-Tracking-Configs wie auf Server
├── pnpm-workspace.yaml ← packages: apps/* + backend
├── package.json ← name: rebreak-monorepo
└── xgit
- Git-HEAD:
5dfbe88(mitcutover-llm-toggle-prep-Arbeit, llmProvider-Toggle-Code) - Branch:
main(Mac), preserved ascutover-llm-toggle-prepauf Remote - Kein
.npmrc— siehe §3 Risiko Prisma 7 transitive deps
1.3 Was kaputt war (Incident 2026-05-06)
User force-pushte aus dem neuen Mac-Repo (backend/-Layout) zu RaynisDev/rebreak.git →
Server-Webhook triggerte deploy.sh → cd /srv/rebreak/apps/rebreak schlug fehl
(Pfad existiert nicht im neuen Layout) bzw. anderer build-pfad lief → schließlich
crashte Auth-Middleware mit HTTP 500: Cannot read properties of undefined (reading 'url'),
weil backend/nitro.config.ts.runtimeConfig keine supabase-Section hat und die
@nuxtjs/supabase-Module-Config (die das im alten Setup auto-injected) im Standalone-Nitro
nicht mehr existiert. Cascade: alle authentifizierten Endpoints kaputt.
Rollback durchgeführt vor dieser Session: RaynisDev/rebreak.git main = 6eca0b5,
Server-HEAD = 6eca0b5, pm2 läuft wieder, HTTP 200 + 401.
2. Pipeline-Diagramm
2.1 Pipeline AKTUELL (Backyard-Layout, läuft)
Mac (trucko-monorepo) GitHub Hetzner-Server (49.13.55.22)
──────────────────── ─────── ─────────────────────────────
./xgit "msg" ─push──▶ RaynisDev/rebreak.git ─hook─▶ rebreak-webhook (pm2, :9000)
│ HMAC-validate
▼
scripts/deploy.sh
│ cd /srv/rebreak
│ git fetch && reset --hard origin/main
│ pnpm install --frozen-lockfile
│ cd apps/rebreak
│ pnpm --filter @trucko/rebreak build
│ cp -r .output .output-staging-new
│ rm -rf .output-staging
│ mv .output-staging-new .output-staging
▼
pm2 restart rebreak-staging
│ → bash apps/rebreak/start-staging.sh
│ → infisical login (universal-auth)
│ → infisical secrets --env=staging --output=json
│ → eval/export VAR=val + NUXT_*-Mapping
│ → pm2 start imap-staging + idle-staging
│ → exec node apps/rebreak/.output-staging/server/index.mjs
▼
nginx: staging.rebreak.org → 127.0.0.1:3016
2.2 Pipeline ZIEL (nach Cutover, neues Layout)
Mac (rebreak-monorepo) GitHub Hetzner-Server
──────────────────── ─────── ──────────────
./xgit "msg" ─push──▶ RaynisDev/rebreak.git ─hook─▶ rebreak-webhook
▼
scripts/deploy.sh ← MUSS GEÄNDERT WERDEN
│ cd /srv/rebreak
│ git fetch && reset --hard origin/main
│ pnpm install --frozen-lockfile
│ cd backend ← NEU
│ pnpm --filter rebreak-backend build ← NEU
│ cp -r .output .output-staging-new ← NEU (relativ zu backend/)
│ rm -rf .output-staging
│ mv .output-staging-new .output-staging
▼
pm2 restart rebreak-staging
│ → bash backend/start-staging.sh ← NEU
│ → infisical login + run --env=staging
│ → exec node backend/.output-staging/server/index.mjs
▼
nginx: staging.rebreak.org → 127.0.0.1:3016
Wichtigste Pfad-Änderungen:
| Bereich | Vorher (live) | Nachher (Cutover) |
|---|---|---|
| App-Dir | /srv/rebreak/apps/rebreak/ |
/srv/rebreak/backend/ |
| Build-Filter | pnpm --filter @trucko/rebreak build |
pnpm --filter rebreak-backend build |
| Build-Output | apps/rebreak/.output-staging/server/index.mjs |
backend/.output-staging/server/index.mjs |
| Start-Script | apps/rebreak/start-staging.sh |
backend/start-staging.sh |
| ecosystem.config.js | zeigt auf apps/rebreak | zeigt auf backend |
| start-staging.sh-Pattern | jq+eval+NUXT_*-Mapping | infisical run -- node …/.output/server/index.mjs (kein Mapping nötig — Nitro liest process.env.X direkt via runtimeConfig-Defaults) |
Achtung: backend/start-staging.sh aktuell zeigt auf /srv/rebreak-monorepo/backend/... — falscher Pfad,
muss /srv/rebreak/backend/... sein (siehe §4 Schritt 6).
3. Fehlende runtimeConfig-Keys
Quelle 1: /srv/rebreak/apps/rebreak/nuxt.config.ts (live, vollständig)
Quelle 2: grep config.X in ~/mono/rebreak-monorepo/backend/server/
Ziel: backend/nitro.config.ts.runtimeConfig
3.1 Keys die im AKTUELLEN backend/nitro.config.ts schon existieren (16 total)
✅ databaseUrl, adminSecret, openrouterApiKey, deepgramApiKey, googleApiKey, googleAiApiKey, azureTtsKey, azureTtsRegion, openaiApiKey, stripeSecretKey, stripeWebhookSecret, resendApiKey, encryptionKey, lyraBotUserId, rebreakBotUserId, groqApiKey, cronSecret + public.{stripePublishableKey, appUrl, apiBase}
3.2 Keys die FEHLEN (Cutover-Blocker)
| Key | Quelle (Mac backend code) | Wofür | Default |
|---|---|---|---|
cartesiaApiKey |
server/api/coach/speak-cartesia.post.ts:22 |
Cartesia TTS API | process.env.CARTESIA_API_KEY ?? "" |
cartesiaVoiceId |
server/api/coach/speak-cartesia.post.ts:24 |
Cartesia voice override | process.env.CARTESIA_VOICE_ID ?? "" |
elevenlabsApiKey |
server/api/coach/speak-elevenlabs.post.ts:26,34 |
ElevenLabs TTS API | process.env.ELEVENLABS_API_KEY ?? "" |
elevenlabsVoiceId |
server/api/coach/speak-elevenlabs.post.ts:28 |
ElevenLabs voice ID | process.env.ELEVENLABS_VOICE_ID ?? "" |
Diese 4 Keys sind in der live
nuxt.config.tsebenfalls nicht deklariert — die TTS-Routes für Cartesia/ElevenLabs sind NEU in derbackend/-Welt (existieren als untracked files:backend/server/api/coach/speak-cartesia.post.ts
speak-elevenlabs.post.ts). Cutover-Risiko: gering (alte Routes existierten gar nicht), aber für Vollständigkeit mussnitro.config.tsdiese Keys deklarieren, sonstconfig.cartesiaApiKey === undefinedzur Laufzeit.
3.3 Supabase-Keys (Hauptbruchstelle des Incidents)
⚠️ Im aktuellen backend/nitro.config.ts fehlen supabase.url / supabase.key / supabase.serviceKey komplett.
Im alten Nuxt-Layout setzt @nuxtjs/supabase automatisch
config.public.supabase = { url, key } aus dem supabase: { ... }-Block.
Im standalone-Nitro gibt es kein Modul → muss explizit deklariert werden.
Backend-Code-Aufrufer (siehe server/utils/auth.ts:30 etc.) lesen Supabase
typischerweise via @supabase/supabase-js-Client, der direkt process.env.SUPABASE_URL /
SUPABASE_SERVICE_ROLE_KEY liest. Trotzdem: für Konsistenz mit Frontend/native
und falls irgendein File config.public.supabase.url liest, müssen wir
public.supabase.{url, key} und top-level supabaseServiceKey ergänzen.
→ siehe backend/nitro.config.ts.cutover-draft für vollständige Liste.
3.4 Verifikation des Cutover-Drafts
Nach Cutover:
ssh rebreak-server "tr '\\0' '\\n' < /proc/$(ss -tlnp | grep :3016 | grep -oE 'pid=[0-9]+' | cut -d= -f2)/environ | grep -E 'API_KEY|SUPABASE|JWT|SECRET' | sort"
Liste muss alle erwarteten Werte enthalten. Wenn process.env.X leer ist, ist
Infisical-Wrapper kaputt — siehe feedback_infisical_secrets.md Verify-Trick.
4. Cutover-Sequence (sequentiell abarbeiten, jeden Step bestätigen lassen)
Annahme: Mac-Repo ist auf einem Pre-Cutover-Branch (z.B.
cutover-llm-toggle-prep),mainlokal =5dfbe88. Servermain=6eca0b5. Webhook ist online.
Phase A — Vorbereitung (nicht-destruktiv, lokal auf Mac)
Step 1. Aktiviere backend/nitro.config.ts.cutover-draft →
nach Review der Datei: mv backend/nitro.config.ts.cutover-draft backend/nitro.config.ts.
Step 2. Aktiviere .npmrc.cutover-draft →
mv .npmrc.cutover-draft .npmrc (Repo-root-level, sorgt für node-linker=hoisted).
Step 3. Korrigiere Pfad in backend/start-staging.sh Zeile 31:
- VORHER:
/srv/rebreak-monorepo/backend/.output/server/index.mjs - NACHHER:
/srv/rebreak/backend/.output-staging/server/index.mjs(analog zur prod-pattern: gebauten output nach.output-stagingmovt deploy.sh).
Step 4. Lokaler Build-Test: cd backend && pnpm install && pnpm build. Muss .output/server/index.mjs produzieren.
Step 5. Smoke-Test lokal: node backend/.output/server/index.mjs mit allen ENV-Vars manuell gesetzt → Health-Check (Port 3016).
Phase B — Server-Vorbereitung (read-only, kein Eingriff in laufendes System)
Step 6. SSH-Vergleich: ssh rebreak-server "ls /srv/rebreak/". Verifiziere dass backend/-Pfad NICHT existiert (sonst stale Files vom letzten Force-Push-Versuch).
Step 7. ⚠️ Falls stale backend/ existiert: ssh rebreak-server "ls -la /srv/rebreak/backend/ 2>&1" Output an User eskalieren. NICHT selbst löschen.
Step 8. Infisical-Secrets Audit: User soll bestätigen dass alle in §3.2 + §3.3 genannten Keys (CARTESIA_API_KEY, ELEVENLABS_API_KEY, SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY etc.) im Infisical-staging-Env existieren. NICHT selbst Infisical-CLI ausführen (Token-Scope-Risiko).
Phase C — Pipeline-Anpassung (auf Mac, dann xgit)
Step 9. Edit scripts/deploy.sh (Mac-Repo erstellen, Server hat noch alte Version):
APP_DIR="${REPO_ROOT}/apps/rebreak"→APP_DIR="${REPO_ROOT}/backend"pnpm --filter @trucko/rebreak build→pnpm --filter rebreak-backend build
Step 10. Edit ecosystem.config.js (falls im neuen Repo gemirrort wird — derzeit ist es nur auf Server):
script: \${APP_DIR}/start-staging.sh`` (APP_DIR jetzt = backend)cwd: APP_DIRanalog- Webhook-Eintrag
script: \${REPO_ROOT}/scripts/deploy-webhook/server.mjs`` bleibt (existiert weiter unter scripts/).
Klärung an User: Liegt
scripts/deploy.shundecosystem.config.jsim neuen Mac-Repo? Falls nein, müssen sie aus/srv/rebreak/rüberkopiert + angepasst werden. Wenn der Webhook auf dem Server diese Files NICHT aus dem Repo zieht (sondern lokal vorhält), dann werden Step 9+10 zu manuellen Server-Edits — siehe Step 14 ⚠️.
Phase D — Deploy (DESTRUKTIV)
Step 11. ⚠️ Sichere Backyard-State auf Server: ssh rebreak-server "cd /srv/rebreak && git tag -a backyard-pre-cutover -m 'Pre-cutover safe-state 6eca0b5' 6eca0b5" — User-OK einholen (read-only-tag, aber zur Sicherheit).
Step 12. ⚠️ Force-push neuen Layout-State: aus ~/mono/rebreak-monorepo mit ./xgit "cutover: backend/-Layout aktiviert".
- Webhook-Triggert deploy.sh AUTOMATISCH.
- Risiko: alte deploy.sh ist auf
apps/rebreak/-Pfad fixiert, wird alsocd: apps/rebreak: No such filewerfen → build crash → kein restart, alter.output-stagingläuft weiter. - Mitigation: Der CRASH ist gewollt — er verhindert dass kaputter Code gestartet wird. Server bleibt auf laufenden
rebreak-staging(alter index.mjs) live.
Step 13. ⚠️ Manueller Server-Edit für scripts/deploy.sh UND ecosystem.config.js:
- NICHT von dieser Agent-Session ausgeführt — User macht das selbst.
- Alternativen je nach User-Wahl: (a) ssh + sed-Edit der Server-Files (b) deploy.sh wird Teil des Repos und der webhook-deploy-flow zieht es aus dem Repo (cleaner, aber selbst-referentielles Bootstrap-Problem: alter deploy.sh muss erst die neue deploy.sh ans richtige
scripts/-Pfad kopieren). - Empfehlung: (a) für ersten Cutover, danach (b) als follow-up commit.
Step 14. ⚠️ Trigger Re-Deploy nach Server-deploy.sh-Edit: ssh rebreak-server "bash /srv/rebreak/scripts/deploy.sh" ODER neuer xgit-trivial-commit (z.B. README touch). User-Wahl.
Step 15. ⚠️ Manueller pm2-restart falls deploy.sh letzten restart noch nicht getriggert hat:
ssh rebreak-server "pm2 restart rebreak-staging --update-env". Das --update-env ist wichtig damit
neue Infisical-secrets gezogen werden.
Phase E — Verifikation (read-only)
Step 16. ssh rebreak-server "pm2 logs rebreak-staging --nostream --lines 50" — keine 500er, kein crash-loop.
Step 17. Endpoint-Tests (siehe §6 Test-Checklist).
Step 18. Wenn 30 Minuten stable: cleanup ssh rebreak-server "rm -rf /srv/rebreak/apps/rebreak/.output-staging /srv/rebreak/apps/rebreak/.output". An User eskalieren — rm -rf ist destruktiv.
5. Rollback-Plan (Cutover scheitert, <5 min)
5.1 Schneller Rollback (Webhook re-triggert alter HEAD)
# Aus Mac-Repo:
git checkout main
git reset --hard 6eca0b5 # Backyard's safe state
git push --force origin main # ⚠️ destructiv, User-OK
# Dann auf Server:
ssh rebreak-server "cd /srv/rebreak && git reset --hard 6eca0b5" # ⚠️
ssh rebreak-server "bash /srv/rebreak/scripts/deploy.sh" # alter deploy.sh, alter Pfad
ssh rebreak-server "pm2 restart rebreak-staging --update-env"
5.2 Falls Server scripts/deploy.sh schon im Cutover modifiziert wurde
User muss manuell die alte Version aus git show 6eca0b5:scripts/deploy.sh > /srv/rebreak/scripts/deploy.sh schreiben (read-only-Mac, dann scp), bevor Re-Deploy klappt.
5.3 Falls .output-staging bereits gelöscht wurde
ssh rebreak-server "cd /srv/rebreak/apps/rebreak && pnpm --filter @trucko/rebreak build && cp -r .output .output-staging"
Vorher User-OK einholen (Build dauert 90-180s, zwischenzeitlich keine Auth möglich).
5.4 Smoke-Test nach Rollback
curl -s -o /dev/null -w '%{http_code}\n' https://staging.rebreak.org/
curl -s -o /dev/null -w '%{http_code}\n' https://staging.rebreak.org/api/auth/me
# Erwartung: 200 + 401
6. Test-Checklist nach Cutover
Pflicht (alle müssen pass):
GET https://staging.rebreak.org/→ 200GET https://staging.rebreak.org/api/auth/me→ 401 (unauthenticated, NICHT 500)GET https://staging.rebreak.org/api/auth/memit gültigem JWT → 200 + user-dataPOST https://staging.rebreak.org/api/coach/sos-sessionmit JWT → 200 + sessionIdGET https://staging.rebreak.org/api/coach/sos-stream?session=<id>→ SSE stream openendPOST /api/coach/speak-googlemit JWT → audio/mpeg blobPOST /api/coach/speak-deepgrammit JWT → audio blobPOST /api/coach/speak-geminimit JWT → audio blobPOST /api/coach/speak-cartesiamit JWT → audio blob (NEU)POST /api/coach/speak-elevenlabsmit JWT → audio blob (NEU)POST /api/coach/transcribemit audio + JWT → textGET /api/community/postsmit JWT → posts-arrayGET /api/dns/profilemit JWT → profile-config (achtet aufconfig.public.appUrl.includes("staging"))GET /api/lyra/welcome-backmit JWT → messagePOST /api/stripe/checkoutmit JWT → session-url
Best-effort (admin/cron):
GET /api/admin/stats?secret=<adminSecret>→ 200POST /api/cron/lyra-post?secret=<cronSecret>→ 200/204
Process-Health:
pm2 logs rebreak-staging --nostream --lines 100— keine 500er, keine crash-restartspm2 jlist | jq '.[] | select(.name=="rebreak-staging") | .pm2_env.restart_time'→ 0 increments über 5 mintr '\0' '\n' < /proc/<node-pid>/environ | grep -E 'API_KEY|SUPABASE'→ alle keys present
iOS/Android-App-Test (User-Side):
- App-Login → User-Profile lädt
- SOS-Session öffnen → Lyra streamt + spricht (TtsProvider beide testen)
- Community-Tab → posts laden
- DNS-Profile-Sync läuft
7. Risiken + Open Questions
Risiken
- R1 (high):
scripts/deploy.shundecosystem.config.jssind auf dem Server, NICHT im Repo. Cutover-Bootstrap ist selbstreferentiell — entweder manueller Server-Edit (Step 13) ODER Repo-Migration der Files. Diese Sequenz hat ein narrow window in dem ein altes deploy.sh gegen neue Repo-Struktur baut → fail. - R2 (medium):
node-linker=hoistedin.npmrcmuss BEFORE firstpnpm installaktiv sein, sonst landet@prisma/client-runtime-utilsin einem nestednode_modules/.pnpm/...und ESM-Loader findet's nicht. Step 2 muss vor Step 4 passieren. Strikte Order. - R3 (medium):
start-staging.shim neuen Backend nutztinfisical run -- node ...— beim alten gab esevalvon secrets-JSON. Falls irgendeine ENV-Var-Mapping-Magie (NUXT_*-Prefix) gebraucht wird, muss sie nachgezogen werden. Audit nötig: existiert ein Code-Pfad derprocess.env.NUXT_Xdirekt liest und nicht viauseRuntimeConfig? - R4 (low): PWA-Manifest + i18n-locales aus
nuxt.config.tshaben kein Äquivalent in standalone Nitro. Falls App-Frontend (rebreak-native) auf SSR-i18n-Endpoints angewiesen ist → kaputt. Native-App-Test im Detail. - R5 (low):
nitro.config.externals.inline: [/^(?!@supabase\/supabase-js)/]ist eine Anti-pattern-Regex (matched fast alles). Möglicherweise produziert sie unerwartet riesige.output-bundles. Code-Review im Cutover-PR sinnvoll.
Open Questions an User
- Sollen
scripts/deploy.sh+ecosystem.config.jsTeil des Cutover-Commits werden (im Repo unterscripts/undecosystem.config.jsRoot)? Das vermeidet manuelle Server-Edits und ist Backyard-konform. Bootstrap-Frage: einmaliger manuellergit pull && cp scripts/deploy.sh /srv/rebreak/scripts/first-time, danach automatisch. backend/start-staging.shPfad: soll auf/srv/rebreak/backend/.output-staging/server/index.mjszeigen (analog Backyard's apps/rebreak-Pattern, mit deploy.sh-.output → .output-stagingmove) ODER direkt/srv/rebreak/backend/.output/server/index.mjs(ohne staging-suffix-Move)? Erste Variante = Konsistenz mit Backyard. Zweite = simpler Cutover.- Webhook-Build-Filter: soll der Filter
pnpm --filter rebreak-backend buildden Frontend-Native-App-Build IGNORIEREN (bisher: nur Backend baut)? Die rebreak-native-App buildet via Capacitor/Metro, nicht via pnpm — also ist--filter rebreak-backendkorrekt restriktiv. Bestätigen. - Gibt es eine Test-Staging-Umgebung wo wir den Cutover proben können bevor wir die echte staging.rebreak.org nehmen? Andernfalls ist DiGA-User-Test-Window (TestFlight) während Cutover potentiell down.
- Cartesia/ElevenLabs-Secrets in Infisical: existieren
CARTESIA_API_KEYundELEVENLABS_API_KEYschon im staging-Env? Falls nein, sind die neuen TTS-Routes nach Cutover broken (404-degradation, nicht 500 —if (!key) return error).
8. Operations-Cheatsheet (post-Cutover)
# Logs live
ssh rebreak-server "pm2 logs rebreak-staging --lines 100"
# Manueller Re-Deploy (nur bei broken webhook)
ssh rebreak-server "bash /srv/rebreak/scripts/deploy.sh"
# pm2-status
ssh rebreak-server "pm2 list"
# Verify .output-staging is fresh
ssh rebreak-server "stat -c '%y' /srv/rebreak/backend/.output-staging/server/index.mjs"
# Verify config-key present in built bundle
ssh rebreak-server "grep -l 'cartesiaApiKey' /srv/rebreak/backend/.output-staging/server/chunks/*.mjs"
# Check ENV-Vars in running node-process
ssh rebreak-server "tr '\\0' '\\n' < /proc/\$(ss -tlnp | grep :3016 | grep -oE 'pid=[0-9]+' | cut -d= -f2)/environ | grep -E 'CARTESIA|ELEVENLABS|SUPABASE' | sort"
# nginx reload (NUR wenn nginx-conf changed; wir machen das nicht in diesem Cutover)
ssh rebreak-server "nginx -t && systemctl reload nginx"
KEIN-GO-Liste (gilt während Cutover und danach):
- ❌
pm2 delete rebreak-staging(nur restart) - ❌
git reset --harddirekt auf Server (deploy.sh macht das offiziell) - ❌
rm -rfauf/srv/rebreak/...ohne explizites User-OK - ❌ DNS-Änderungen
- ❌ Infisical-Token-Rotation
- ❌
pnpm installparallel zum Webhook-Deploy (OOM auf 4 GB)