Supabase setup
cd packages/server
npx supabase login
npx supabase link --project-ref <your-ref>
npx supabase db push # applies every migration in supabase/migrations/Run these commands from packages/server/ — the Supabase CLI looks for supabase/ relative to the current directory.
Required extensions
Enable these extensions in your Supabase project (Database → Extensions):
| Extension | Purpose |
|---|---|
vector | Embeddings for dedup + semantic search (commonly called pgvector) |
pg_cron | Scheduled MV refreshes, nightly judge runs, retention cron |
pgcrypto | UUIDs and HMAC |
pgsodium | Field-level encryption (PII columns) |
pg_net | Async HTTP from triggers (plugin dispatcher) |
vault | BYOK + plugin-secret storage |
age (optional) | Apache AGE graph backend — Phase 1 knowledge graph |
The db push step bootstraps all extensions in the right order via the migration sequence.
Required custom functions
The migration sequence creates the following custom Postgres functions:
| Function | Purpose |
|---|---|
mushi_rls_coverage_snapshot() | Verifies every public table has ≥1 RLS policy |
DSARs are handled via the data_subject_requests table + the api edge function (POST /v1/admin/dsar), not a stored procedure. SOC 2 evidence is generated by the soc2-evidence edge function triggered from the admin console — no soc2_evidence_snapshot() RPC exists. Both routes are documented in the Security & Compliance section.
RLS pattern
Every table ships with RLS enabled and project-scoped policies. The canonical policy pattern is:
-- Use the subquery form — Postgres caches via initPlan, not per-row
create policy "users see own project data"
on public.reports
for select
using (project_id in (
select project_id from public.project_members
where user_id = (select auth.uid())
));Do not use bare auth.uid() — the subquery form is 100x faster on large tables.
Required seed data
After db push, run the seed file to populate lookup tables:
npx supabase db seed --debugThis inserts the plugin registry, default tier definitions, and the initial mushi_runtime_config row.
Verifying the setup
-- Check all tables have RLS enabled
select mushi_rls_coverage_snapshot();
-- Check extensions
select name, default_version, installed_version
from pg_available_extensions
where name in ('vector', 'pg_cron', 'pgsodium', 'vault', 'pg_net');