13 Commits

Author SHA1 Message Date
chahinebrini
97206b7865 Support Gitea webhooks in deploy listener
Some checks failed
Deploy Staging / Build backend (Nitro) (push) Has been cancelled
Deploy Staging / Deploy zu Hetzner (push) Has been cancelled
ci/woodpecker/push/woodpecker Pipeline was canceled
2026-06-18 08:46:20 +02:00
chahinebrini
37f3173539 chore: add scripts/dev.sh for local app dev against server 2026-06-16 22:05:53 +02:00
chahinebrini
8697fee2e8 fix(deploy): warte auf Backend-Port 3016 vor idle-Daemon-Restart
Deploy-Race: rebreak-idle-staging wurde direkt nach pm2-restart von
rebreak-staging gestartet, bevor der Nitro-Server auf Port 3016
lauschte. Der Daemon startete sofort Initial-Scans fuer alle Accounts
-- jeder triggerScan()-Call scheiterte mit "fetch failed" (ECONNREFUSED).
Kein Crash, aber Error-Log-Burst (N Fehler pro Mail-Account) und
verpasster Initial-Sweep.

Fix: curl-Preflight in Step 5b wartet bis Port 3016 antwortet (max
60s, 12x alle 5s, --retry-connrefused). Bei Timeout: WARN im Log,
kein Deploy-Abbruch (best-effort fuer optionalen Service).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 15:47:24 +02:00
chahinebrini
7ad8625d8e feat(marketing): Windows-PC-Schutz Download-Seite + Installer
- /download/windows: eigene, korrekt geframte Windows-Seite (PC-DNS-Schutz,
  nicht iPhone-Supervision)
- Installer in public/downloads/RebreakMagic-Setup.exe (3,7 MB, aus CI-Artefakt)
- deploy-marketing.sh: --info=progress2 -> --progress (macOS-rsync-kompatibel)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:40:25 +02:00
chahinebrini
fb2d90b947 fix(calls): no duplicate incoming-call notifications
- backend: skip Expo alert push to iOS devices that already received VoIP push
  (CallKit + banner = double ring)
- native: receiveIncoming no longer triggers InCallManager.startRingtone —
  CallKit/ConnectionService play their own ring. Dedup if same callId
  arrives twice (Realtime + VoIP-Push race).
2026-06-04 18:28:00 +02:00
chahinebrini
f8181d63b9 fix(deploy): pm2 stop staging services + 2.5GB heap vor build (OOM-fix) 2026-06-04 09:35:43 +02:00
chahinebrini
372aaa43dd fix(ci): pipeline race-condition + health-check retry + maestro secrets
Hauptproblem: Webhook-Deploy (deploy.sh) und GH-Actions-Deploy
(deploy-from-artifact.sh) liefen gleichzeitig → Race auf .output-staging
und doppelter pm2-restart.

Fixes:
- deploy-from-artifact.sh: setzt .deploy-ga.lock (noclobber, mit PID)
  während Deploy läuft; stale locks werden erkannt und überschrieben
- deploy.sh: prüft .deploy-ga.lock bei Start — wenn GH-Actions aktiv,
  sauberes exit 0 statt Kollision
- Health-Check: Retry-Loop (12× × 5s = max 60s) statt einmaligem sleep 5;
  Infisical-Login + Nitro-Start braucht auf gestresstem Server bis 30s
- maestro-cloud.yml: ungültiges `if: secrets.X != ''` entfernt (secrets
  in if-conditions sind in GH-Actions immer leer); stattdessen expliziter
  secrets-check als erster Step mit klarer Fehlermeldung
- pnpm --prefer-offline in deploy-from-artifact.sh: nutzt Store-Cache
- .gitignore: .deploy-ga.lock ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 09:32:25 +02:00
chahinebrini
de701677b2 feat(mail): IDLE-daemon for real-time Legend mail-protection
Standalone ESM-daemon that:
- Connects via ImapFlow IDLE to all active Legend mailboxes
- Triggers /api/mail/scan-internal on new-mail events (real-time)
- Auto-renew IDLE every 25min (RFC 3501 limit), exponential-backoff reconnect
- DB-refresh every 5min for new/removed connections

Plus deploy-pipeline:
- GH-Actions artifact-upload + scp to /srv/rebreak/backend/imap-idle/
- npm install --production on server (imapflow + pg)
- pm2 startOrReload via ecosystem.config.js
- start-idle-staging.sh wrapper for Infisical secret-injection

Replaces 30min-cron polling for Legend tier -- Casino-mails now blocked
within seconds, fulfilling Legend tier marketing promise.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 20:48:44 +02:00
chahinebrini
8d95e192a6 chore(admin): restore executable bit on deploy scripts 2026-05-08 22:30:17 +02:00
chahinebrini
f7c9c79365 feat(admin): Admin App initial commit + Deploy-Infrastructure
apps/admin/:
- Nuxt 4.1.3 + @nuxt/ui 4 + @nuxtjs/supabase, port 3017 staging
- 7 pages: index (59 LOC dashboard), login (72 LOC), auth/confirm, plus stubs
  für domains/users/stats/moderation (14-17 LOC each, content für separate
  Phase 2 Session)
- composables/useAdminAuth.ts: Supabase login + verifyAdminRole hook
- middleware/admin-auth.ts: route guard (Phase 3 backend-check ready)
- layouts/default.vue, app.vue, README.md
- nuxt.config.ts: SSR=true, port 3017, dark-mode preference, Supabase
  pkce-flow, runtimeConfig.adminSecret für Phase 3 backend-binding

Deploy-Infrastructure:
- .github/workflows/deploy-admin-staging.yml: build admin auf push to main mit
  path-filter apps/admin/**, scp tar zu Server, atomic-mv + pm2 restart
- scripts/deploy-admin-from-artifact.sh: Server-side deploy (extract, atomic mv,
  pm2 reload). Kein prisma-migrate (admin hat kein eigenes DB-Schema).
- apps/admin/start-admin-staging.sh: pm2 start-script mit Infisical-wrapper,
  port 3017, mappt Infisical SUPABASE_URL/KEY auf NUXT_PUBLIC_*
- ecosystem.config.js: rebreak-admin-staging Eintrag (port 3017,
  max_memory_restart 400M)
- ops/nginx/admin-staging.rebreak.org.conf: HTTP→HTTPS redirect, SSL paths,
  proxy auf 127.0.0.1:3017, noindex header

Pending User-Actions für go-live:
1. DNS-A-Record admin.staging.rebreak.org → 49.13.55.22
2. SSL-cert via certbot (oder bestehender wildcard *.staging.rebreak.org)
3. nginx-config auf Server aktivieren (sudo cp + ln + reload)
4. pm2 initial start: pm2 start ecosystem.config.js --only rebreak-admin-staging
5. Infisical-secret ADMIN_SECRET (server-only, Phase 3 binding)

GH-Actions: keine neuen Secrets (nutzt bestehende HETZNER_SSH_KEY/HOST/USER)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 22:30:17 +02:00
chahinebrini
87438ede8e feat(deploy): GitHub-Actions Build+Deploy-Pipeline für rebreak-staging
CX23 (4GB RAM) OOM'd am 2026-05-06 während webhook-getriggertem `pnpm build`
(Heap-Limit 1.5GB überschritten). Build raus aus Server, GitHub-Runner (7GB RAM)
übernimmt — Server deployed nur noch Artifact via scp + atomic-mv + pm2 restart.

- .github/workflows/deploy-staging.yml: 2-Job (build + deploy via SSH-Artifact-Push)
- scripts/deploy-from-artifact.sh: Server-Script mit Migration-Detection + atomic-mv
- ops/GITHUB_ACTIONS_PIPELINE.md: Architektur-Doku + Cheatsheet

Coexistence: alter rebreak-webhook bleibt als Failsafe, wird nach 5+ erfolgreichen
GA-Runs deaktiviert. Erster Run: Webhook temporär gestoppt für sauberen Test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:18:49 +02:00
chahinebrini
b38bf176b9 feat(deploy): Migration-Detection in webhook-deploy.sh
Step 2.5 zwischen pnpm install und build:
- git diff vs .last-deployed-sha auf prisma/migrations + schema.prisma
- bei Änderungen: pnpm prisma migrate deploy via infisical run wrapper
  (idempotent, conservative — abort bei Fail vor pm2-restart)
- DATABASE_URL Fallback auf NUXT_DATABASE_URL analog start-staging.sh

Step 8: persistiert HEAD-SHA in .last-deployed-sha
.gitignore: .last-deployed-sha (server-only artifact)

Edge cases:
- First-deploy: .last-deployed-sha fehlt → run_migration=true (sicher dank
  Idempotenz)
- Infisical-Login-Fail: abort vor pm2-restart
- Migration-Fail: exit 1, alter Code läuft auf alter DB sauber

Old-trucko-Pattern (deploy.sh:58-65) macht migrate deploy unconditional;
rebreak-Variante macht es conditional → spart Infisical+DB-Roundtrip wenn
keine Migration-Files berührt wurden.
2026-05-07 19:09:12 +02:00
chahinebrini
d1b71e76b2 chore(cutover): prepare backend/-Layout for Hetzner-Pipeline-Cutover
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>
2026-05-07 00:35:50 +02:00