auth/migrations.ts

Auth schema migrations.

Ordered list of {name, up} migrations for the fuz identity system tables. Consumed by run_migrations with namespace 'fuz_auth'.

Schema is not stabilized yet — append-only is NOT the rule. While fuz_app is pre-stable, migration bodies, names, and positions can change freely between versions; consumers upgrading across a schema change are expected to drop and re-bootstrap their dev/test databases (production deployments are not yet a supported use case). Once the schema is declared stable a hard append-only-after-publish rule will apply and the cliff will be called out in the release notes for that version. Until then: edit, rename, reorder, or replace migrations as needed; bias toward collapsing work into the existing v0/v1 entries rather than appending v2 patch migrations.

To add a migration in the pre-stable phase, prefer extending an existing entry's body (consumers will re-bootstrap on upgrade). If you do append a new entry to AUTH_MIGRATIONS, the runner will apply it on existing tracker rows — the same shape that will become mandatory once the schema stabilizes:

// v2: add display_name to account { name: 'account_display_name', up: async (db) => { await db.query('ALTER TABLE account ADD COLUMN display_name TEXT'); }, },

Migrations are forward-only (no down). Use IF NOT EXISTS / IF EXISTS for DDL safety. The name appears in error messages on failure.

Declarations
#

4 declarations

view source

AUTH_MIGRATION_NAMESPACE
#

AUTH_MIGRATION_NS
#

AUTH_MIGRATIONS
#

auth/migrations.ts view source

Migration[]

Auth schema migrations in order.

- v0: Full auth schema — account (with email_verified), actor, role_grant, auth_session, api_token, audit_log (with seq), bootstrap_lock, invite, app_settings, plus all indexes and seeds. - v1: role_grant_offer table for consentful grants; adds scope_id / scope_kind / source_offer_id / revoked_reason to role_grant and swaps the (actor_id, role) partial unique index for a scope-aware variant using the index-side 'GLOBAL' token + all-zeros sentinel UUID. The (scope_kind, scope_id) pair is enforced paired-null by role_grant_scope_kind_paired / role_grant_offer_scope_kind_paired CHECK constraints — both null for global, both non-null for scoped. The role_grant_offer table carries a superseded_at terminal state; its partial unique index is scoped by (to_account, role, scope_kind, scope, from_actor) so multiple grantors may coexist. scope_kind is informative-only in v1 (registry-membership validation against create_scope_kind_schema); v2 may add INSERT-time (role, scope_kind) enforcement.

RESERVED_MIGRATION_NAMESPACES
#

auth/migrations.ts view source

readonly string[]

Migration namespaces reserved by fuz_app. Consumers passing migration_namespaces to create_app_backend must choose a name not in this list — the runtime check rejects matches with a thrown error. Typed as ReadonlyArray<string> (not a literal tuple) so .includes() accepts any consumer-supplied namespace string without a cast.

Depends on
#

Imported by
#