Skip to content

Onset — Supabase production setup (legacy import from onset-clinic)

This document was preserved from the local onset-clinic folder and may reference older naming.

Your org Last 1 Enterprises is marked managed by Vercel Marketplace. You can still create Onset in the Supabase dashboard with + New project; link the project to your Vercel app when you deploy onset-clinic so env vars can sync.

1. Create the project

  1. In Supabase -> Last 1 Enterprises -> New project.
  2. Name: Onset (or onset-prod).
  3. Region: Prefer us-east-1 (matches your other projects) unless you have a strong reason to use us-west-2.
  4. Database password: store in a 1Password/Vault entry (needed for direct Postgres access, backups, psql).
  5. Wait for provisioning to finish.

2. Apply migrations (production schema)

In the Supabase project: SQL Editor -> New query. Run in order:

  1. supabase/migrations/20250329120000_clinic_b2b.sql
  2. supabase/migrations/20250329130000_clinic_rls_and_rpc.sql

Or use Supabase CLI: supabase link then supabase db push.

Verify Table Editor shows clinics, practitioners, patient_shares and Authentication -> Policies lists RLS policies.

3. API keys (never commit secrets)

From Project Settings -> API:

Variable Use
Project URL NEXT_PUBLIC_SUPABASE_URL, iOS SupabaseURL
anon public NEXT_PUBLIC_SUPABASE_ANON_KEY, iOS SupabaseAnonKey
service_role Server-only (Edge Functions / admin scripts). Never ship in the iOS app or browser.

4. Connect the Next.js dashboard (onset-clinic)

  1. Copy Project URL and anon key into Vercel Environment Variables (or rely on Vercel Marketplace integration if it offers this project).
  2. Local: cp .env.example .env.local and paste the same values.
  3. Redeploy after changing env vars.

5. Connect the iOS app (Onset Xcode project)

  1. In Xcode -> target Onset -> Build Settings -> User-Defined (or your .xcconfig):
  2. SUPABASE_URL = https://<project-ref>.supabase.co
  3. SUPABASE_ANON_KEY = anon key (These flow into Supporting/Info.plist as $(SUPABASE_URL) / $(SUPABASE_ANON_KEY).)
  4. Build and run -> Settings -> Care team -> Share with provider -> clinic code validation calls validate_clinic_code RPC.

6. Seed your first clinic (SQL Editor, as postgres)

Run after migrations (use a real practice name and a 4+ character alphanumeric code):

insert into public.clinics (name, clinic_code)
values ('Demo Fertility Clinic', 'DEMO');

Confirm from a REST client or the app: RPC validate_clinic_code with {"p_code":"DEMO"} returns id and name.

7. Practitioners (dashboard users)

  • There is no authenticated INSERT policy on practitioners; add rows with the service role (server) or run SQL in the dashboard as an admin.
  • Typical pattern: invite staff via Supabase Auth (email magic link), then insert into practitioners linking user_id + clinic_id.

8. Database connection (IPv4 vs IPv6)

Some projects expose db.<ref>.supabase.co only over IPv6. If your network or tooling cannot reach IPv6, use the Session pooler string from Project Settings -> Database instead (IPv4). Pool hosts look like aws-0-<region>.pooler.supabase.com or aws-1-<region>.pooler.supabase.com - copy the exact host from the dashboard; do not guess the aws-0 vs aws-1 prefix.

  • User: postgres.<project_ref>
  • Port 5432 for session mode (typical for migrations / DDL)

9. Before calling it "production"

  • [ ] RLS enabled on all three tables (migrations do this).
  • [ ] No service_role in client apps or GitHub.
  • [ ] Backups / PITR per your Supabase plan.
  • [ ] Custom SMTP for Auth (optional but recommended for deliverability).
  • [ ] MCP / CI: use a Supabase personal access token only in CI secrets, not in the repo.
  • [ ] If database password, anon, or service_role keys were ever pasted into chat, email, or a ticket, rotate them in the dashboard (Database -> reset password; Settings -> API -> regenerate JWT keys).

Cursor / MCP

To create or manage projects from AI tooling, set SUPABASE_ACCESS_TOKEN (Supabase account Access Tokens) on the MCP server. The dashboard flow you're using is fine without it.