Skip to content

Supabase ​

THE PRODUCTION PROJECT CHANGED ON 2026-08-16 — CHECK THE REF, NOT THE NAME

Every ygmqxyrbnemhwkiyoboc on this page is the retired project, now named qr-setu-legacy-bkp. Production is ikkwqowfnbhdasfejojg (qr-setu-prod), on a separate Supabase account. ⚠ Both projects have held the name qr-setu-prod, so the NAME is ambiguous and only the REF identifies a project — anything written before 2026-08-16 that says "qr-setu-prod" means the other one. Following a stale instruction here points an OAuth redirect, a migration or a build at the wrong live project.

Stale in three places (2026-08-08); the Supabase reasoning still holds

  1. "React SPA" is legacy/ — the surfaces are apps/mobile (Expo/RN) and apps/web (RR8 SSR).
  2. VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY → EXPO_PUBLIC_SUPABASE_* (mobile) and server-side SUPABASE_URL / SUPABASE_PUBLISHABLE_KEY (apps/web).
  3. The public_page_ops_* family is retired by the transactional outbox; its tables were dropped from Dev on 2026-08-08 and the four Edge Functions are orphaned.

⚠ Two current facts worth more than anything below. qr-setu-dev's public schema holds 0 tables as of 2026-08-08 — the v2 baseline is authored, not applied. And the logged-in supabase CLI on the dev machine cannot see the qr-setu-* projects at all (projects list returns another org's; link 403s silently), so the documented functions:deploy path does not work there — use the Supabase MCP tools and call list_migrations immediately after the first apply_migration (QRS-267).

The single backend: PostgreSQL + RLS + Auth + Edge Functions + Storage. Two projects.

Projects ​

ProjectRefRole
PRODqr-setu-prodygmqxyrbnemhwkiyobocIsolated, real user data. The original/already-connected project.
DEV + UATqr-setu-devdyhjofjjuazhyqcvlrkxBootstrapped from a schema-only baseline; zero data rows.

Both provisioned 2026-07-10. Verified 58/58 tables and 118/118 RLS policies identical at baseline.

What we use ​

CapabilityHow QRSETU uses it
PostgreSQL + RLS58 tables, 118 policies. RLS on every user-facing table.
AuthJWT sessions; role from profiles.role (default 'user').
Edge FunctionsDeno/TS, @supabase/supabase-js pinned 2.30.0. Writes/secrets/HTTP.
Storageprofile-pictures bucket (Prod only so far).
pg_cronDrives the public_page_ops_* Type B functions (Prod only so far).

Client rules [ENFORCED] ​

  • One canonical typed singleton: src/lib/supabaseClient.ts (createClient(VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)).
  • @/lib/customSupabaseClient (~50 importers) and src/shared/lib/supabaseClient.js re-export it.
  • No createClient anywhere else. No hardcoded production-fallback URL.

CLI & config ​

  • supabase/config.toml — per-function verify_jwt (Type A true, Type B public_page_ops_* false).
  • npm run functions:deploy -- --project-ref <ref> — explicit ref, never supabase link state.
  • Local stack via Docker Desktop; EF tests via Deno (npm run test:ef).

[TRANSITIONAL] — not yet replicated to Dev ​

  • pg_cron job — hardcodes Prod's Edge Function URL; needs a project-URL-aware rewrite first.
  • profile-pictures bucket — environment-specific data, not portable schema.

Gotcha: the deno.land/x/postgres pooler is incompatible in this setup — see the Edge Function standards memo / EDGE_FUNCTION_GUIDELINES.md.

See Database & RLS · Backend · Migrations.