Supabase backend
--db supabase scaffolds the idiomatic SQL variant from _template/supabase-app. It is deliberately NOT a Convex clone: Row Level Security is the API surface, logic lives in SQL (triggers, RPCs), storage is Supabase Storage, server code is Edge Functions, and the data flow is request/response — not realtime.
Setup
- 1. Create a Supabase project (free tier works)
- 2. Open its SQL editor and run the entire apps/<slug>/supabase/schema.sql — tables, RLS policies, triggers, and RPCs in one file
- 3. cp apps/<slug>/.env.example apps/<slug>/.env.local and fill in VITE_SUPABASE_URL + VITE_SUPABASE_ANON_KEY (project settings → API)
- 4. cd apps/<slug> && pnpm dev
RLS as the API
The client talks to PostgREST directly with the anon key; every table's policies decide what each authenticated user can see and change (scoped to auth.uid()). There is no hand-written REST layer — adding a policy IS adding an endpoint. Cross-row logic belongs in SQL triggers and RPCs inside schema.sql.
useSupaQuery: request/response
The variant's data idiom lives in src/lib/useQuery.ts. Fetch on mount, call refetch after your own mutations — deliberately no realtime subscription (add a Supabase realtime channel to a specific page only when a product genuinely needs it).
const { data, error, refetch, loading } = useSupaQuery(
() => supabase.from("records").select("*").order("created_at"),
[],
);
// after a mutation:
await supabase.from("records").insert({ title });
await refetch();
loading is true while data is undefined and there is no error; render Skeleton then, EmptyState when the array is empty.
Edge Functions
Server-side code that must hold secrets ships as Edge Functions in supabase/functions/: agent-api (api-keys), ai-chat (ai), mcp (mcp), stripe-checkout + stripe-webhook (billing). Deploy the ones your features need:
supabase functions deploy ai-chat
supabase secrets set ANTHROPIC_API_KEY=sk-ant-...
supabase functions deploy mcp --no-verify-jwt
supabase secrets set APP_URL=<your deployed frontend URL>
.env files
- .env.example — the template listing the required keys
- .env.local — dev keys (gitignored)
- .env.production — the same keys for the deployed build; pnpm deploy refuses to run without it