Skip to content

Onset Environments — R940

Live Onset stack runs on Proxmox R940 (pve-r940):

Role Host Public URL
API / Auth / PostgREST onset-db https://onset-api.theonset.app
Clinic portal onset-app (onset-clinic-app) https://clinic.theonset.app
Marketing / web Cloudflare Pages https://theonset.app

Hosted Supabase projects and Railway clinic services are retired. Do not link, push, or document those providers for Onset.


Topology

  iOS Debug / Staging TF ──┐
  iOS Release / App Store ─┼──► onset-api.theonset.app  (onset-db on R940)
  onset-web              ──┘
  clinic.theonset.app ────────► onset-app on R940
Surface Config Backend
iOS Debug / Onset Staging Staging.xcconfig onset-api.theonset.app
iOS Release / App Store Production.xcconfig onset-api.theonset.app
Clinic portal onset-app container same API
Git main production

Info.plist keys: OnsetAPIURL / OnsetAPIAnonKey (from xcconfig ONSET_API_URL / ONSET_API_ANON_KEY). OnsetAPIConfig still accepts legacy SupabaseURL / SupabaseAnonKey for one release if a stale Mac build setting remains.


1. Database migrations (onset-db)

SQL lives in supabase/migrations/ (folder name is historical). Apply on onset-db:

# From a machine with SSH to onset-db:
scp supabase/migrations/<file>.sql onset-db:/tmp/<file>.sql
ssh onset-db 'sudo docker exec -i supabase-db psql -U postgres -d postgres -v ON_ERROR_STOP=1 < /tmp/<file>.sql'

Or use the helper:

./scripts/onset-db-apply.sh supabase/migrations/<file>.sql

Gate 5 dose/silent columns were applied 2026-09-29 via 20260929010000_shared_adherence_doses_and_silent.sql.

Several core tables (shared_adherence, practitioner_patients, etc.) predate migration tracking and have no CREATE TABLE in this folder. Prefer additive migrations against the live onset-db schema.


2. iOS build configuration

Action Scheme Build config xcconfig
Xcode Run Onset Debug Staging
Internal TestFlight Onset Staging Release-Staging Staging
App Store / prod TestFlight Onset Release Production

Both point at onset-api.theonset.app. Bundle ID is com.last1enterprises.Onset.

Keys: OnsetAPIURL / OnsetAPIAnonKey expand from ONSET_API_URL / ONSET_API_ANON_KEY in xcconfig (API base + anon JWT for R940). RevenueCat: REVENUECAT_PUBLIC_API_KEY.

Render from BWS (prefer new names; fall back to deprecated):

Prefer Deprecated (keep until clinic/admin cutover)
ONSET_DB_PROD_API_ANON_KEY ONSET_DB_PROD_SUPABASE_ANON_KEY
ONSET_DB_PROD_API_URL ONSET_DB_PROD_SUPABASE_URL
ONSET_DB_PROD_API_SERVICE_ROLE_KEY ONSET_DB_PROD_SUPABASE_SERVICE_ROLE_KEY
ONSET_DB_PROD_API_POOLER_URL ONSET_DB_PROD_SUPABASE_POOLER_URL
ONSET_API_URL ONSET_SUPABASE_URL
ONSET_API_SERVICE_ROLE_KEY ONSET_SUPABASE_SERVICE_ROLE_KEY

Clinic portal dual-reads NEXT_PUBLIC_ONSET_API_* / ONSET_API_SERVICE_ROLE_KEY with legacy NEXT_PUBLIC_SUPABASE_* / SUPABASE_SERVICE_ROLE_KEY. BWS now has matching ONSET_APP_PROD_NEXT_PUBLIC_ONSET_API_* and ONSET_APP_PROD_ONSET_API_SERVICE_ROLE_KEY copies; old *_SUPABASE_* keys stay until clinic/admin deploys drop them.

last1-admin dual-reads ONSET_API_* with legacy ONSET_SUPABASE_*. BWS: prefer LAST1ADMIN_APP_PROD_ONSET_API_*; keep LAST1ADMIN_APP_PROD_ONSET_SUPABASE_* until Railway env is updated.

Clinic smoke test

  1. Install Onset (Debug or TestFlight).
  2. More → Care team → Share with Provider (clinic org code) or My Practitioner (connection code).
  3. Confirm patient on clinic.theonset.app.
  4. Sync Now / daily use → shared_adherence updates (dose % + silent flags after Gate 5).

Connection codes are created in the live clinic portal.


3. onset-web

Cloudflare Pages. Preview (develop) and production (main) should use https://onset-api.theonset.app (and matching anon/service keys from R940 vault). Do not configure hosted Supabase project URLs.

Preview: https://develop.onset-web.pages.dev


4. Clinic portal (onset-app)

Runs as Docker service onset-clinic-app on onset-app (R940). Public site: https://clinic.theonset.app

Env vars are R940 API credentials (NEXT_PUBLIC_* pointing at onset-api.theonset.app). Stripe webhooks target clinic.theonset.app.


5. Git workflow

feature/* ──► develop (optional verify) ──► main ──► production
Repo Production
onset-ios Release → App Store; API = onset-api.theonset.app
onset-web Cloudflare Pages → theonset.app
clinic.theonset.app Deploy to onset-app → clinic.theonset.app

Migrations: land in supabase/migrations/, apply on onset-db, verify in app + clinic.

Staging verification checklist

  • [ ] iOS against onset-api: sign-in, Today, practitioner sync
  • [ ] Clinic portal: login, patient list, protocol push
  • [ ] New SQL migration applied on onset-db
  • [ ] No hosted Supabase or Railway clinic URLs in commits

6. LastVet (separate stack)

LastVet production API is https://api.last.vet. Onset iOS OAuth bases in xcconfig already use that host. LastVet Railway staging is outside Onset Clinic scope; do not wire Onset Clinic through Railway.

See docs/provider-network/ENVIRONMENTS.md for the veteran integration matrix (live store: onset-db / onset-api.theonset.app).