Repository navigation
Conversation
This was referenced Oct 16, 2026
ditadi
force-pushed
the
stack/database-dev-flow/03-db-migrate
branch
from
October 19, 2026 12:44
9f3a34f to
1827ebd
Compare
`appkit db introspect` reads an existing Postgres schema (default: app) from pg_catalog and writes config/database/schema.ts from it, keeping the previous file as schema.ts.bak. It also writes the migration that brings history up to the database, 0000_baseline first and NNNN_introspect after, and records it as applied. That is only true on the branch it read, so it runs only on the developer's dev or session branch, which `appkit db init` creates. The deployed app adopts 0000_baseline on start when its tables already exist. What the schema builder cannot express is skipped and reported, and what it declares differently from the database (a timestamp precision, an index) is listed. Objects it does not read (views, triggers, policies, functions, standalone sequences) are named in a warning, since a database the migrations create will not have them. It refuses when the branch's journal and the checkout's migrations differ, and it refuses a migration that drops something schema.ts left out, since the deployed app runs that migration on start. Recording takes the migration lock and checks the journal again, and a run interrupted before recording is finished by the next one. If anything fails after schema.ts is written, schema.ts, its backup, database.d.ts and the migrations are put back. Signed-off-by: ditadi <victordperd@gmail.com>
ditadi
force-pushed
the
stack/database-dev-flow/04-db-introspect
branch
from
October 19, 2026 15:02
a2522e5 to
c3e1172
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #666.
Summary
Adds
appkit db introspect, for apps whose tables already exist in Lakebase.It reads a Postgres schema (
appby default, or--schema-name) frompg_catalogand writesconfig/database/schema.tsfrom it, keeping the previous file asschema.ts.bak. It also writes the migration that brings history up to the database, and records it as applied on the branch it read:0000_baseline. The deployed app adopts it on start when its tables already exist, recording it instead of running it (feat(appkit): apply committed database migrations on deploy start #654).NNNN_introspect.Recording is only true on the branch introspect read, so it runs only on the developer's
dev-…orsession-…branch. On any other branch it refuses before connecting and points toappkit db init(#672), which creates the dev branch from the project's default branch and introspects it when there is noschema.ts.Details
schema.ts, so a missing, empty or broken file can be regenerated. If the schema has no tables introspect can write, it refuses to replace an existingschema.tswith an empty one.// appkit: skipped …comment and reported. A skipped NOT NULL column without a default is a loud warning, since inserts through the API would fail.schema.tsdeclares differently from the database (varchar without a length, timestamp precision, serial keys, partitioned tables, CHECK constraints, indexes, DEFERRABLE) is listed. The branch keeps it as it is. A database the migrations create gets whatschema.tsdeclares.schema.tsleft out and the branch still has: a table, column, default, constraint or enum type. The check matches the exact statement drizzle-kit writes for each skipped item, including the unqualified form drizzle-kit uses for thepublicschema. A drop of something the branch no longer has is written, with the breaking-change warning from feat(appkit): add appkit db migrate #666.schema.tsalso escape U+2028, U+2029 and bidi controls. Constraint names are cut at 63 bytes, as Postgres does.schema.tsis written (it does not load, drizzle-kit is missing, a rename is ambiguous, recording fails),schema.ts, its backup,database.d.tsand the migrations are put back. The backup is only rewritten when the content changes, so a rerun keeps the original.recordedlists every tag recorded as applied.Tests
runIntrospecttests cover the branch refusal, each drift case, recovery from an interrupted run, a refused drop for each kind of skipped item (also inpublic), a drop that is written, the unread warning, an empty or fully skipped schema, and rollback when recording or the types write fails.catalog.pg.test.tsreads a real schema with partitions, identity and generated columns, checks, indexes, enums, and every kind of object introspect does not read.apply.pg.test.tscovers recording: exactly the pending migrations without running them, refusal on drift, a missing tag failing before connecting, and the lock wait limit.