Repository navigation
fix: make pre-migration backups schema-aware - #77
Merged
Merged
Conversation
The mandatory backup taken before applying a pending migration (e.g. 012_ownership.sql) previously requested every BACKUP_TABLES entry via --table, so pg_dump would fail on tables the target schema had not yet created. db:backup now reads the target's schema_migrations and resolves the dump set to BACKUP_TABLES intersected with the tables the applied migrations actually created. Resolution fails closed on schema inconsistencies: an expected table missing from the DB, or an allowlisted table present without a recorded migration, aborts the backup instead of producing a silently partial artifact. The dump remains allowlist-only — unknown tables can never be requested, an empty resolved set is refused, and the archive TOC assertions in the recovery drill are unchanged. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Three fail-closed hardenings to schema-aware backup resolution:
- an applied migration filename unknown to this checkout now aborts the
backup ("target database schema is ahead of this repository checkout")
instead of being tolerated — an older tool cannot know whether its
allowlist is still complete
- the applied ledger must be a contiguous prefix of the repo migration
list; gaps or skipped migrations abort before any table resolution
- the live schema query restricts to BASE TABLE relations, so a view can
never satisfy a required backup table
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This branch was successfully 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.
Summary
Fixes a production-migration sequencing hazard discovered after PR #76:
db:backuprequested everyBACKUP_TABLESentry viapg_dump --table=, so the mandatory fresh backup required before applying012_ownership.sqlwould fail on a database where 012 is committed but not yet applied.db:backupnow reads the target'sschema_migrationsand resolves the dump set toBACKUP_TABLES ∩ tables the applied migrations created(resolveBackupTables()inscripts/backup-scope.mjs). A target at 011 backs up the 10 pre-012 tables and simply excludes the not-yet-created ownership tables; a target at 012 backs up all 14.The allowlist-only model is unchanged — unknown tables can never be requested, and resolution fails closed on a broken schema:
Also reports schema metadata: applied count/latest, repo migration count, behind-main flag, and which allowlisted tables were excluded. No credentials or URLs printed.
Scope
Operator-safety only. No migration, schema, ingestion, API, UI, privacy-page, or permission changes. Production DB untouched.
Security / privacy impact
Strengthens backup integrity: a broken or inconsistent schema now aborts rather than yielding a partial backup. Allowlist-only dump model preserved; TOC assertions in the recovery drill unchanged.
Database / deployment impact
npm run db:backup+db:migratesequence for 012.Verification
npm test— 538 tests, 0 failures (newtest/backup-schema.test.mjs: pre-012, post-012, broken-post-012 fail-closed, unknown-table exclusion, missing-core-table fail-closed, unrecorded-table fail-closed)npm run typechecknpm run buildnpm audit --audit-level=moderate— 0 vulnerabilitiesnpm run db:drill— PASS on Postgres 17 (post-012 target still dumps all 14; TOC allowlist proof unchanged)Contributor agreement
Generated with Devin