Shipflash logoDocs

Supabase

Supabase owns auth, Postgres, generated types, migrations, RLS, grants, RPC functions, seeds, retention work, and service-role boundaries.

On this page

Supabase source map

Client boundaries

Request-scoped user clients, service-role clients, and stateless service clients are separate entrypoints.

  • src/lib/supabase/server.ts
  • src/lib/supabase/static.ts
  • src/lib/supabase/proxy.ts

Database contract

Migrations define schema, constraints, RLS, grants, RPC functions, and operational jobs. Generated types keep application code aligned.

  • supabase/migrations/20260426000000_init.sql
  • src/lib/supabase/types.ts

Operational tables

Rate limits, webhook events, notification outbox, audit log, and retention workflows are production safety primitives.

  • src/lib/security/rate-limit/check.ts
  • src/lib/security/webhooks/processing.ts
  • src/features/compliance/server/retention/service.ts

Service-role boundary

Source: src/lib/supabase/server.ts

Service-role access is server-only and does not persist auth sessions.

ts
export const getServiceSupabase = async () => {
  let forwardedFor: string | null = null;
  try {
    const headerStore = await headers();
    forwardedFor = headerStore.get("x-forwarded-for");
  } catch {
    forwardedFor = null;
  }
  const url = getSupabaseUrl();
  const key = getSupabaseServiceRoleKey();
  return createClient<Database>(url, key, {
    auth: { persistSession: false, autoRefreshToken: false },
    global: {
      headers: {
        ...(forwardedFor ? { "X-Forwarded-For": forwardedFor } : {}),
      },
    },
  });
};

Supabase production rules

  • Enable RLS decisions before exposing a table to user-scoped code.
  • Use service-role clients only in trusted server paths.
  • Regenerate generated types after schema changes.
  • Run migration contract checks after touching supabase/migrations.
  • Keep one-off data repair separate from durable schema migrations.