Files
bsk/docs/supabase-shared-config.md
T
tiennm99 699686253c docs: record phase-5/7 + key-rotation decisions
- Phase 5 imaging: keep, pin numbers — 200 KB/image, 1h signed-URL TTL,
  7-day retention window (PLAN.md §4 Phase 5)
- Phase 7 reminders: keep QStash (free tier 1000 msgs/day covers
  clinic-scale); document signature + Zod + DB-invariant validation
  plan in threat-model R8
- sb_secret_* / sb_publishable_* rotation: event-driven only for the
  current educational scope (solo author, no real users); switch to
  quarterly when any real user exists
- threat-model Unresolved: drop the three items above; CI grep for
  sb_secret_ in NEXT_PUBLIC_* lines remains the only open question
2026-05-25 16:16:38 +07:00

4.1 KiB

Supabase Shared-Project Config

The BSK Supabase project is shared with several other personal side projects. Settings outside the per-app bsk.* schema are project-wide — changing them affects every app on the same project. This doc records what is currently configured and who owns it, so future changes don't blindside neighboring apps.

Update this file whenever a project-wide setting changes.

Project metadata

Field Value
Project ref (fill in: e.g. abcdefghijklmnopqrst)
Region (fill in: e.g. ap-southeast-1)
Plan Free (Hobby)
Primary owner tiennm99
Apps sharing this project bsk, (future: blog, links, …)

Per-app schemas

Schema App Repo Status
bsk BSK clinic rewrite this repo active
public (reserved — do not use)

Rule: no app may write to public. Every table, view, function, type, policy must be schema-qualified.

Project-wide settings (change with caution)

These are single-value-for-the-whole-project settings. Any change is announced in this doc + a commit message before the change lands.

Auth providers

  • Email/password: enabled
  • Magic link: (record decision)
  • OAuth: (none yet — record provider, client id source when added)
  • Anonymous sign-ins: disabled

JWT

  • Signing algorithm: HS256 (Supabase default)
  • Expiry: 3600s (Supabase default)
  • Custom claims: (none)

Email templates

  • Confirmation, recovery, magic link, invite: Supabase defaults.
  • Sender address: Supabase default (noreply@mail.app.supabase.io).
  • BSK-specific templates: not yet customized. If customized, every app receives the same look.

SMTP

  • Provider: Supabase built-in (rate-limited).
  • Custom SMTP: not configured.

Password rules

  • Minimum length: 8 (Supabase default)
  • HIBP check: (record decision)

API keys (new format)

  • sb_publishable_* — browser, replaces anon key.
  • sb_secret_* — server, replaces service role key.
  • Legacy supabase_key_* retires 2026-12-31. Not in use.
  • Rotation policy: event-driven (no scheduled cadence — single-author personal project). Triggers: suspected leak, key appearing in logs/screenshots/repo history, repo handoff or new contributor, suspected sibling-app compromise. Re-evaluate the moment any real (non-author) user exists.
  • Storage location: Vercel project env vars, Production-scoped. Never in repo.

Exposed schemas

PostgREST schema list (Supabase → Settings → API → Exposed schemas): bsk, (others as added).

Storage buckets

Bucket Owner app Public? RLS notes
bsk-checkup-media bsk no per-checkup RLS on object metadata
bsk-public-assets bsk no signed URLs only

Bucket names must be prefixed with the owner app slug.

Realtime channels

Channel names live in a single project-wide namespace. Prefix every channel with the owner app slug:

  • bsk:queue:{shift_id}
  • queue:{shift_id} ✗ (would collide with any sibling using the same name)

Change-coordination protocol

  1. Update this file with the proposed change + which apps it affects.
  2. Open a draft PR for visibility (even if no sibling app shares this repo).
  3. After applying the change in the Supabase dashboard, commit the doc update referencing the dashboard change.
  4. For destructive changes (auth provider removal, JWT rotation, schema drop): pause sibling apps' deploys first.

Forbidden operations

  • supabase db reset against this project — wipes every app's data.
  • supabase db remote commit from any one app without verifying it includes only that app's schema.
  • KEYS *, FLUSHDB, FLUSHALL against the shared Upstash DB (separate concern; see lib/upstash.ts).
  • Manual edits to auth.* or storage.* tables outside the dashboard.

Backup & restore

Free-tier PITR is project-wide; a restore wipes every app's data to a point in time. Per-app rollback is not supported by Supabase. Mitigations:

  • Daily pg_dump --schema=bsk cron (see docs/runbooks/restore-from-bad-migration.md).
  • Preflight check on migrations (see scripts/preflight-supabase.ts).
  • Never run destructive DDL without a recent dump.