P9: squash migration trees, harden SQLite schema upkeep - #173
Merged
Conversation
|
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.



P9 — сжатие миграций + ведение SQLite-схемы (финал серии remediation)
Строго последний план серии 2026-07-02. Оба дерева goose-миграций (0001..0058, ~106 файлов) схлопнуты в один
0001_init.sqlна диалект; baseline-механизм снесён;migrateguardобезврежен; добавлены линт парности и генератор rebuild-скриптов. 7 коммитов.Что сделано
DestructiveMigrationsопустошён. Он ссылался на исчезающую миграцию 0014 — после squash это вечно блокировало бы миграции на свежих непустых БД (checkOne видел бы v14 как «pending» навсегда). ПроводкаCheckAllсохранена под будущие деструктивные миграции.0001_init.sql= дампsqlite_masterсвежей БД, смигрированной полным деревом (временныйtools/squashtool, в git не попал). Baseline-fast-path (applyBaselineIfFresh) +db/migrations/sqlite/baseline/+ 2 baseline-теста + stress-тест удалены. Diff old/new дампа — пустой.0001_init.sql=pg_dump --schema-onlyс БД, смигрированной полным деревом (одноразовый postgres:18-alpine).sqlc generate— нулевой дифф (главный гейт эквивалентности PG-схемы). Пере-миграция новым деревом → бит-идентичный дамп.TestSchemaSyncPostgresMatchesSQLitePASS (squashed PG ↔ squashed SQLite: таблицы/колонки/типы/CHECK/FK/индексы сходятся), sqlc CLEAN, контракт-тесты обоих бэкендов PASS, 46 таблиц в обоих деревьях.migration_parity_lint_test.go): номера 2..58 запрещены (goose молча пропустил бы их на до-squash БД → новые миграции ≥ 0059); один номер = одно изменение в обоих деревьях; dialect-only через маркер. + 5 юнит-тестов правил.cmd/sqlite-rebuild: crash-safe рецепт пересборки таблицы (BEGIN до DROP, COMMIT после RENAME, PRAGMA вне транзакций) — golden + functional тесты.db/migrations/README.md+ правила нумерации; комментарии с исчезнувшими номерами миграций почищены;backup.go— комментарий про инверсию SchemaVersion-сравнения для до-squash архивов.Отклонения от плана (обоснованные)
TestMigrateGoosePostgresожидал>= 7версий — план адаптировал только SQLite-аналог (Task 3), но не PG-аналог. Поправил (ровно 1), как SQLite.bodyотstrings.Index(script, "PRAGMA"), но слово «PRAGMA» есть в шапке-комментарии раньше реального statement → syntax error. Заякорил наPRAGMA foreign_keys = OFF.fmt.Sscanf→strconv.Atoi) + 2×gosec G304 (CLI-чтение файла оператором →//nolint:gosecс обоснованием) в новых файлах плана.Замечания
Проверки (локально, все выполнены с поднятым Postgres)
go build/vet ./... ./cmd/...,gofmt(мои файлы),golangci-lint(storage+cmd) — 0sqlc generate— CLEANTestSchemaSyncPostgresMatchesSQLite+ контракт-тесты обоих бэкендов — PASSgo test ./...— PASSСм.
docs/plans/2026-07-02-remediation/plan-9-migration-squash.md(workspace). Полный CI (schema_sync + PG-контракты через service-контейнер) — на ране.