fix(canvas): 画布 - 防止旧内容覆盖并支持版本历史恢复
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const CurrentSchemaVersion int64 = 15
|
||||
const CurrentSchemaVersion int64 = 16
|
||||
|
||||
const baselineSchemaChecksum = "sha256:open-ai-canvas-schema-v1-20260830"
|
||||
const schemaMigrationAppliedAtIndexChecksum = "sha256:schema-migrations-applied-at-index-v2-20260830"
|
||||
@@ -67,6 +67,9 @@ var schemaMigrations = []migration{
|
||||
{version: 15, name: "agent_profiles", checksum: "sha256:agent-profiles-v15-20260914", apply: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(&model.AgentProfile{})
|
||||
}},
|
||||
{version: 16, name: "canvas_revision_history", checksum: "sha256:canvas-revision-history-v16", apply: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(&model.CanvasProject{}, &model.CanvasSnapshot{}, &model.CanvasSnapshotResource{})
|
||||
}},
|
||||
}
|
||||
|
||||
func migrateSchemaV14(tx *gorm.DB) error {
|
||||
|
||||
@@ -61,11 +61,49 @@ func TestMigrateSchemaV15UpgradesExistingDatabase(t *testing.T) {
|
||||
t.Fatal("v15 upgrade did not install Agent profile table and scope index")
|
||||
}
|
||||
status, err := ReadSchemaStatus(db)
|
||||
if err != nil || !status.Ready || status.Current != 15 {
|
||||
if err != nil || !status.Ready || status.Current != CurrentSchemaVersion {
|
||||
t.Fatalf("unexpected upgraded schema status: %+v, %v", status, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateSchemaV16BackfillsCanvasRevisions(t *testing.T) {
|
||||
db, err := Open(Config{Driver: "sqlite", DSN: "file:migration-canvas-revisions-v16?mode=memory&cache=shared"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Migrator().DropTable(&model.CanvasSnapshotResource{}, &model.CanvasSnapshot{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Migrator().DropColumn(&model.CanvasProject{}, "Revision"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Exec(`INSERT INTO canvas_projects (id, user_id, title, payload_json) VALUES ('legacy', 'owner', 'Existing canvas', '{"nodes":[]}')`).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Where("version = ?", 16).Delete(&schemaMigration{}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var project model.CanvasProject
|
||||
if err := db.First(&project, "id = ?", "legacy").Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if project.Revision != 1 || project.PayloadJSON != `{"nodes":[]}` {
|
||||
t.Fatalf("legacy canvas changed: %+v", project)
|
||||
}
|
||||
if !db.Migrator().HasTable(&model.CanvasSnapshot{}) || !db.Migrator().HasTable(&model.CanvasSnapshotResource{}) {
|
||||
t.Fatal("history tables missing")
|
||||
}
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatalf("migration not idempotent: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateSchemaV8AllowsReusingArchivedLogicalModelCode(t *testing.T) {
|
||||
db, err := Open(Config{Driver: "sqlite", DSN: "file:migration-logical-model-active-code?mode=memory&cache=shared"})
|
||||
if err != nil {
|
||||
|
||||
@@ -84,6 +84,8 @@ func Models() []any {
|
||||
&model.WorkflowStepTask{},
|
||||
&model.ProductionTaskLink{},
|
||||
&model.CanvasProject{},
|
||||
&model.CanvasSnapshot{},
|
||||
&model.CanvasSnapshotResource{},
|
||||
&model.CanvasShare{},
|
||||
&model.PromptTemplate{},
|
||||
&model.UserPromptCustomization{},
|
||||
|
||||
Reference in New Issue
Block a user