2ce68cb098
- Move db/schema.sql to supabase/migrations/ as the first supabase CLI migration (manual `db push` only, no automated runner); re-add the gebos_ingest role + grants there since init.sql never re-runs - Add gebos-postgres-passwords oneshot on db-host: syncs role passwords from sops (LoadCredential, journal-safe), makes supabase_admin SUPERUSER and hands the auth schema to supabase_auth_admin to match the upstream supabase/postgres image; add pg_hba rule for 10.0.0.0/8 - Vendor the official docker-compose (studio/kong/auth/rest/meta only, external Postgres, loopback Studio with no Kong dashboard route) plus kong.yml (trimmed) and kong-entrypoint.sh (verbatim); tested: compose config, Kong config parse, migration applied on TimescaleDB pg17 - Document decisions as ADRs 0001-0004 (migrations, passwords, vendored stack, JWT API keys incl. verify/mint procedure) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
2.3 KiB
Markdown
52 lines
2.3 KiB
Markdown
# ADR-0001: Database schema changes are manual Supabase CLI migrations
|
|
|
|
Date: 2026-07-08
|
|
Status: Accepted
|
|
|
|
## Context
|
|
|
|
Schema v1 (`db/schema.sql`, ~600 lines) was committed but wired to nothing.
|
|
The only SQL that ran automatically was `nix/supabase/init.sql` via
|
|
`services.postgresql.initialScript` — which executes **only at first initdb**,
|
|
so on the already-initialized db-host cluster neither it nor any schema change
|
|
would ever apply again. A delivery mechanism was needed.
|
|
|
|
Options considered:
|
|
|
|
1. **Automated runner** — a systemd oneshot on db-host applying migrations on
|
|
every deploy (dbmate/atlas or plain psql with a tracking table).
|
|
2. **Manual Supabase CLI migrations** — plain-SQL files in
|
|
`supabase/migrations/`, applied by a human with `supabase db push`.
|
|
3. **Extending initialScript** — rejected outright: never re-runs on an
|
|
existing cluster.
|
|
|
|
## Decision
|
|
|
|
Option 2. Schema changes are rare, deliberate, admin-level operations; a
|
|
human applies them on purpose, and no automation exists to break or to apply
|
|
a half-reviewed migration as a side effect of a deploy.
|
|
|
|
* Migrations live in `supabase/migrations/<timestamp>_<name>.sql`; schema v1
|
|
moved there as the first one. `supabase/config.toml` is the minimal CLI
|
|
project marker.
|
|
* Applied via SSH tunnel to db-host as the `postgres` superuser
|
|
(see `supabase/README.md` for the exact commands). The CLI records applied
|
|
files in `supabase_migrations.schema_migrations`, so pushes are incremental
|
|
and re-running is safe. Individual migrations need **not** be idempotent.
|
|
* Layering rule: `nix/supabase/init.sql` holds only cluster bootstrap
|
|
(Supabase schemas, admin/API roles, extensions needing
|
|
`shared_preload_libraries`); everything else — including the `gebos_ingest`
|
|
role and its grants, which are coupled to application tables and must reach
|
|
existing clusters — lives in migrations. Passwords live in neither
|
|
(see ADR-0002).
|
|
|
|
## Consequences
|
|
|
|
* Deploys (`deploy-rs`) never touch the schema; a deploy and a migration are
|
|
two separate, independently reversible acts.
|
|
* A human must remember to push after merging a migration. Accepted for a
|
|
pilot with one operator.
|
|
* The local `nix run .#dev` Postgres has no TimescaleDB yet, so the v1
|
|
migration's `create_hypertable` fails there until the dev stack gains the
|
|
extension.
|