Skip to content

Deployment & Promotion ​

Env-var names are stale (2026-08-08)

VITE_SUPABASE_* is the retired Vite SPA's naming. The mobile app reads EXPO_PUBLIC_SUPABASE_* and apps/web reads server-side SUPABASE_URL / SUPABASE_PUBLISHABLE_KEY (see apps/web/.env.example; getSetuCardServerEnv() throws if either is unset — there is deliberately no production-fallback default). deploy-prod.yml also has no web path yet — its components are [both, migrations, functions], so shipping apps/web needs that path added first. The promotion discipline on this page is unchanged and still binding.

Deploy is decoupled from release. Promotion is manual and deliberate — nothing self-syncs to Prod.

What gets promoted ​

Every one of these changes must be applied to both Supabase projects (Dev first, then Prod):

  • Migrations · Edge Functions · secrets · storage buckets · cron schedules.

Full procedure + parity-verification SQL + CLI connectivity gotchas: supabase/docs/PROMOTION_RUNBOOK.md.

Frontend deploy ​

  • DEV: auto on green CI from develop → Cloudflare Pages DEV.
  • UAT / PROD: manual workflow_dispatch from uat / main (after verify-ci).
  • Each build injects its own VITE_SUPABASE_*.

Design sync — a required step of develop → uat (ADR-0015) ​

Promotion to UAT is where accumulated design drift is reconciled. It is attached to this gate deliberately: a "periodic" audit has no owner and no forcing function, whereas this promotion is manual and already happens.

  1. Open the design drift ledger.
  2. For every 🔴 open row: push the change into the Claude Design MCP project (via DesignSync) and mark it 🟢 synced — or mark it 🟡 deferred with a written reason on the row.
  3. A row is never silently dropped. correction and none rows need no action (⚪).

Skipping this does not break the deploy — it breaks the next screen designed from the design project, which will be drawn against stale foundations. That failure has already occurred once here (the quarantined QR setu prototype-handoff/), so treat it as a real step, not paperwork.

Edge Function deploy ​

bash
npm run functions:deploy -- --project-ref <ref> [--only fn-a,fn-b] [--dry-run]
  • Explicit --project-ref always required (never relies on supabase link state).
  • Skips _shared/utils (no index.ts).
  • Deploy to Dev, verify, then Prod.

Rollback (DR runbooks now; PITR deferred) ​

SurfaceRollback
FrontendCloudflare Pages instant rollback to a previous deployment.
Backend (schema)Compensating expand-contract migration (not an in-place revert).
Edge Functiongit revert + redeploy.
Data safety netSupabase managed daily backups (interim). PITR + RPO/RTO + restore drills = deferred decision.

Feature flags / kill-switches ​

Decouple deploy from release: land code dark behind a flag, flip it on when ready, flip it off to mitigate. (Target capability per CLAUDE.md.)

Post-deploy verification ​

  • Verify end-to-end in-app, not just via tests — part of the Definition of Done.
  • Deploy-smoke runs against the real URL (mind Cloudflare Bot Fight Mode 403s).