From e7b46e92d20970ac3626e726a26c8d81e0597477 Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 14 Sep 2026 02:21:44 +0000 Subject: [PATCH] feat(db): allow migration_repair snapshot and event kinds 00028 check constraints would reject a real PG apply. Add goose 00032 with Up/Down so repair snapshots can persist. Co-authored-by: Cursor --- ...-14-document-revision-migration-repair.sql | 58 +++++++++++++++++++ internal/db/migrate_test.go | 33 +++++++++++ 2 files changed, 91 insertions(+) create mode 100644 deploy/postgres/goose/00032_2026-09-14-document-revision-migration-repair.sql diff --git a/deploy/postgres/goose/00032_2026-09-14-document-revision-migration-repair.sql b/deploy/postgres/goose/00032_2026-09-14-document-revision-migration-repair.sql new file mode 100644 index 00000000..c8ebfb07 --- /dev/null +++ b/deploy/postgres/goose/00032_2026-09-14-document-revision-migration-repair.sql @@ -0,0 +1,58 @@ +-- +goose Up +-- Allow explicit migration_repair snapshots/events for legacy canonicalization repair. +-- 00028 rejected this source/change kind, so a real PG apply would fail closed. + +ALTER TABLE document_snapshots + DROP CONSTRAINT IF EXISTS chk_snapshot_source_kind; +ALTER TABLE document_snapshots + ADD CONSTRAINT chk_snapshot_source_kind + CHECK (source_kind IN ( + 'template', + 'human', + 'agent', + 'agent_squad', + 'migration', + 'system', + 'migration_repair' + )); + +ALTER TABLE document_change_events + DROP CONSTRAINT IF EXISTS chk_change_kind; +ALTER TABLE document_change_events + ADD CONSTRAINT chk_change_kind + CHECK (change_kind IN ( + 'human_revision', + 'agent_commit', + 'agent_noop', + 'import', + 'restore_as_new', + 'migration_repair' + )); + +-- +goose Down +-- Restore 00028 constraints. Fails if any migration_repair rows remain. + +ALTER TABLE document_snapshots + DROP CONSTRAINT IF EXISTS chk_snapshot_source_kind; +ALTER TABLE document_snapshots + ADD CONSTRAINT chk_snapshot_source_kind + CHECK (source_kind IN ( + 'template', + 'human', + 'agent', + 'agent_squad', + 'migration', + 'system' + )); + +ALTER TABLE document_change_events + DROP CONSTRAINT IF EXISTS chk_change_kind; +ALTER TABLE document_change_events + ADD CONSTRAINT chk_change_kind + CHECK (change_kind IN ( + 'human_revision', + 'agent_commit', + 'agent_noop', + 'import', + 'restore_as_new' + )); diff --git a/internal/db/migrate_test.go b/internal/db/migrate_test.go index ba7f3a9f..6f71e071 100644 --- a/internal/db/migrate_test.go +++ b/internal/db/migrate_test.go @@ -3,6 +3,8 @@ package db import ( "context" "os" + "path/filepath" + "strings" "testing" "time" @@ -45,3 +47,34 @@ func TestMigrationGate_ExpectedFilesMatchAppliedVersion(t *testing.T) { t.Fatalf("applied schema version %d behind migration files %d", version, expected) } } + +func TestMigration032_AllowsMigrationRepairKinds(t *testing.T) { + files, err := ListMigrationFiles(ResolveMigrationsDir()) + if err != nil { + t.Fatal(err) + } + var found string + for _, name := range files { + if strings.HasPrefix(name, "00032_") && strings.HasSuffix(name, ".sql") { + found = name + break + } + } + if found == "" { + t.Fatal("expected goose 00032 for migration_repair check constraints") + } + raw, err := os.ReadFile(filepath.Join(ResolveMigrationsDir(), found)) + if err != nil { + t.Fatal(err) + } + text := string(raw) + if !strings.Contains(text, "-- +goose Up") || !strings.Contains(text, "-- +goose Down") { + t.Fatal("00032 must have Up and Down") + } + if !strings.Contains(text, "chk_snapshot_source_kind") || !strings.Contains(text, "chk_change_kind") { + t.Fatal("00032 must replace source/change kind checks") + } + if strings.Count(text, "'migration_repair'") < 2 { + t.Fatalf("00032 must allow migration_repair on both constraints, got %s", found) + } +}