Skip to content

last1.id Mode 2A — Week 2 Gate B Report (W2B)

Date: 2026-08-25
Gate: B — Dry-run migration to sovereign-db + MinIO
Status: COMPLETE — STOP for Ryan Gate B approval before W2C (cutover readiness)
Supabase: unchanged (read-only pg_dump + Storage GET only)
Target: sovereign-db-last1id (192.168.1.95) / last1id_prod, MinIO on auth-last1id


Executive summary

Dry-run migration succeeded. Hosted Supabase data was dumped via Supavisor session pooler (aws-1-us-east-1.pooler.supabase.com:5432, user postgres.nztgswcpnwggymncrnyx) and restored to R940 Postgres. Exact COUNT(*) parity on all key tables. 3/3 profile photo objects copied to MinIO with matching SHA-256. GoTrue on VM 114 is healthy and reads 12 migrated auth.users via last1id_app.

Notable gotcha: Direct db.nztgswcpnwggymncrnyx.supabase.co is IPv6-only from R940; use pooler for dump. First restore attempt failed on auth table ownership until auth objects were reassigned to last1id_app (script: scripts/last1-id/gate-b-restore.sh).


Connection path (Gate B)

Path Result
Direct db.*.supabase.co:5432 Failed — IPv6 only, R940 IPv4-only
Pooler aws-1-us-east-1.pooler.supabase.com:5432 OK — session mode, user postgres.nztgswcpnwggymncrnyx
pg_dump client Must be PG 17+ (sovereign-db has 17.11; auth VM had 16.x and failed)

Database migration

Step Result
pg_dump auth + public + storage 388 KB custom dump
Restore to last1id_prod OK after ownership fix
FK identities.auth_user_id → auth.users 0 orphans
RLS policies (public) 35 live (source = target)
supabase_migrations.schema_migrations 70 rows on source (repo has 71 files; 1 dashboard-only migration likely — see Gate A)

Exact row parity (source vs sovereign)

Table Count
auth.users 12
auth.sessions 150
public.identities 18
public.credentials 220
storage.objects 3
pg_policies (public) 35

Public row total: 543 (unchanged from Gate A). All 66 auth/public/storage tables matched on COUNT(*) verification.

Auth schema highlights (source, live SQL)

Table Rows
auth.refresh_tokens 194
auth.mfa_amr_claims 150
auth.sessions 150
auth.flow_state 12
auth.identities 12
auth.users 12

Storage metadata

Table Rows
storage.buckets 1
storage.objects 3

MinIO migration (profile-photos)

Object Size SHA-256 verified
identities/21f171bb-…/provider-71883748-….jpg 378 B yes
identities/2a805b21-…/provider-e89e89c6-….jpg 3,018 B yes
identities/a3d34613-…/provider-143301fb-….jpg 1,320 B yes

MinIO object count under profile-photos/identities/: 3 (matches Supabase Storage).


GoTrue verification

Check Result
Container health Healthy (/health 200)
last1id_app → SELECT count(*) FROM auth.users 12
Kong :8000 Running

Admin API via Kong returned 403 with raw admin secret (expected: needs service-role JWT). Data-plane read via DB role confirms migrated auth data is usable.


Scripts added

Script Purpose
scripts/last1-id/gate-b-dump.sh Dump from Supabase pooler
scripts/last1-id/gate-b-restore.sh Drop/recreate schemas, restore, fix ownership

Operational order: stop GoTrue/Kong → gate-b-restore.sh → start GoTrue/Kong → verify → MinIO copy.


Gotchas for Gate C / Week 3

  1. Pooler host is region-specific — discovered aws-1-us-east-1, not aws-0-us-west-1.
  2. Restore ownership — auth schema must be owned by last1id_app or GoTrue migrations fail on startup.
  3. service_role / anon / authenticated roles — must exist before restore (RLS policies reference them).
  4. Dump file on sovereign — /tmp/last1id-gate-b/supabase-last1id.dump (not in git; delete after Gate C sign-off if desired).
  5. Supabase remains authoritative — no DNS, app, or OAuth changes in Gate B.

Ryan Gate B checklist

  • [ ] Accept row/file counts and parity table above
  • [ ] Accept pooler-based dump workflow for repeatability
  • [ ] Approve W2C (cutover readiness: GoTrue API smoke tests, BWS already wired, sovereign READ-READY for Week 3)

STOP — Awaiting Ryan Gate B approval.