Expand description
cratefield-import-supabase: step one of moving a Supabase project onto
the harness (ADR 0026, issue #658). inspect connects read-only to the
project’s Postgres — plus, optionally, the Supabase Management API for
what Postgres cannot see — and returns a Report: every schema object,
RLS policy, auth provider, storage bucket, Edge Function and Realtime
publication, each classified as automatic, needs work or a blocker, with
a size and transfer-time estimate.
It never writes. The later steps (auth users, schema and data, storage,
cutover) read the report’s JSON; docs/import/supabase-report.md
documents it.
Step two (issue #659) is read_users: the same read-only snapshot,
but rows — the auth users as the admin import contract, plus the map
record_mapping writes so the data step can rewrite their references.
use cratefield_import_supabase::{InspectOptions, Secret, inspect};
let options = InspectOptions::new("abcdefghijklmnopqrst", Secret::new(std::env::var("SUPABASE_DB_URL").unwrap()));
let report = inspect(&options).await?;
println!("{}", report.to_markdown());Re-exports§
pub use dispositions::DispositionsError;pub use dispositions::DispositionsFile;pub use dispositions::apply as apply_dispositions;pub use dispositions::skeleton;pub use management::AuthConfig;pub use management::DEFAULT_API_BASE;pub use management::ManagementApi;pub use management::ManagementError;pub use plan::PLAN_VERSION;pub use plan::Plan;pub use plan::PlanBlocker;pub use plan::PlanDrift;pub use plan::TargetFacts;pub use plan::build_plan;pub use plan::check_drift;pub use plan::inspection_hash;pub use plan::read_target;pub use report::*;
Modules§
- dispositions
- Dispositions: the per-item decision every needs-work and blocker item needs before cutover (ADR 0026, Decision 5).
- extensions
- What the harness Postgres target can do with each extension a Supabase project may have installed.
- management
- The two Supabase Management API reads inspect makes, for what Postgres cannot see: the Edge Functions and the auth configuration.
- plan
- The migration plan: what the importer will do, tied to the inspection it was written from (ADR 0026, Decision 3; issue #728).
- policy
- What an RLS policy amounts to, and the Cratefield check to write for it.
- report
- The migration report: what inspect saw, and what each item needs.
Structs§
- Import
Identity - One OIDC link for
ImportRecord::identities: the harness slug and the source’ssub. - Import
Plan - Everything
read_usersread, inauth.users.idorder; every count is exact (the whole table, not a page of it).Debugprints counts only — never a record, an address or the metadata. - Import
Record - One user in the admin import contract.
Debugprints ids, flags and counts only — never the address, a subject or the hash; the JSON carries the address and the hash for the import to store. - Inspect
Options - What
inspectneeds. - Mapped
User - One row for the mapping table: a Supabase user, the account the import created for it, and its source metadata.
- Mapping
Counts - What
record_mappingdid. - Read
Only Session - One connection, in one read-only transaction.
- Secret
- A secret string: cleared on drop, and
Debugprints[redacted], so a stray{:?}cannot disclose it. - Skipped
User - A user not imported, and why.
- Source
Name - The part of a connection string a report may show.
- Unmapped
Provider - One Supabase OAuth provider none of whose identities were linked, with the users left to sign in by magic link.
- User
Metadata - A user’s source-side metadata (
raw_user_meta_data/raw_app_meta_data): carried to the mapping table, never to the harness, whose accounts have no metadata column yet. NoDebug: the values are the source’s own, so a stray{:?}must not print them. - Users
Options - What
read_usersneeds.
Enums§
- Inspect
Error - Why an inspection stopped. The exit code is non-zero for every one of them; a blocker is never one of them (it is part of the report).
- Mapping
Error - Why a mapping write failed.
- Skip
Reason - Why a user is not imported.
Constants§
- DEFAULT_
BATCH_ SIZE - Users read per keyset page when none is set on
UsersOptions. - DEFAULT_
TRANSFER_ MBPS - The throughput the transfer estimate assumes when none is given, in megabits per second.
- EXTERNAL_
PROVIDER - The
external_providerevery record carries: the source system, so a re-run and another source’s ids never collide.
Functions§
- connect_
mapping - Opens a writable connection to the target database — the harness
Postgres, not the Supabase source — for
record_mapping. - inspect
- Inspects the project. Read-only throughout; see
ReadOnlySession. - read_
users - Reads the source’s auth users through one read-only snapshot and plans their import.
- record_
mapping - Creates
import_supabase_usersif needed and upsertsrowsin one transaction: a new Supabase id is inserted; one already mapped to the same account has its metadata refreshed (counted unchanged); a new id may share an account with an existing row (--merge-by-emailmaps several source users to one account). The only drift is an existing id that maps to a different account —MappingError::Drift. - source_
name - Parses
urlas apostgres://orpostgresql://connection string and returns its host, port and database, and nothing else. - validate_
project_ ref - A project ref is lower-case letters and digits: it goes into a URL path.