fix(database): 认证通知 - 补齐 v35 增量迁移
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const CurrentSchemaVersion int64 = 34
|
||||
const CurrentSchemaVersion int64 = 35
|
||||
|
||||
const baselineSchemaChecksum = "sha256:open-ai-canvas-schema-v1-20260830"
|
||||
const schemaMigrationAppliedAtIndexChecksum = "sha256:schema-migrations-applied-at-index-v2-20260830"
|
||||
@@ -22,6 +22,7 @@ const resourcePlaybackChecksum = "sha256:resource-playback-v6-20260902"
|
||||
const assetLibraryFoldersChecksum = "sha256:asset-library-folders-v6-20260902"
|
||||
const logicalModelActiveCodeChecksum = "sha256:logical-model-active-code-v8-20260905"
|
||||
const creationRuntimeChecksum = "sha256:creation-runtime-v10-20260909"
|
||||
const authNotificationsChecksum = "sha256:auth-notifications-v35-20260924"
|
||||
|
||||
const postgresSchemaMigrationLockID int64 = 73123910420260830
|
||||
|
||||
@@ -117,6 +118,7 @@ var schemaMigrations = []migration{
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{version: 35, name: "auth_notifications", checksum: authNotificationsChecksum, apply: migrateSchemaV35},
|
||||
}
|
||||
|
||||
func migrateChannelModelTags(tx *gorm.DB) error {
|
||||
|
||||
@@ -66,11 +66,67 @@ func TestMigrateSchemaRecordsAndValidatesVersion(t *testing.T) {
|
||||
if !db.Migrator().HasColumn(&model.BannerAnnouncement{}, "notice_type") {
|
||||
t.Fatal("schema migration v22 did not create banner announcements notice_type")
|
||||
}
|
||||
if !db.Migrator().HasTable(&model.AuthVerification{}) ||
|
||||
!db.Migrator().HasTable(&model.NotificationQuota{}) ||
|
||||
!db.Migrator().HasTable(&model.SMSChannel{}) ||
|
||||
!db.Migrator().HasTable(&model.SMSRecord{}) {
|
||||
t.Fatal("schema migration v35 did not create auth notification tables")
|
||||
}
|
||||
if !db.Migrator().HasColumn(&model.User{}, "phone") ||
|
||||
!db.Migrator().HasColumn(&model.User{}, "email_verified_at") ||
|
||||
!db.Migrator().HasColumn(&model.User{}, "phone_verified_at") ||
|
||||
!db.Migrator().HasColumn(&model.EmailVerificationCode{}, "attempts") {
|
||||
t.Fatal("schema migration v35 did not add authentication verification fields")
|
||||
}
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatalf("migration should be idempotent: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateSchemaV35UpgradesExistingDatabase(t *testing.T) {
|
||||
db, err := Open(Config{Driver: "sqlite", DSN: "file:migration-auth-notifications-v35?mode=memory&cache=shared"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, table := range []any{&model.AuthVerification{}, &model.NotificationQuota{}, &model.SMSChannel{}, &model.SMSRecord{}} {
|
||||
if err := db.Migrator().DropTable(table); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
for _, column := range []string{"phone", "email_verified_at", "phone_verified_at"} {
|
||||
if err := db.Migrator().DropColumn(&model.User{}, column); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := db.Migrator().DropColumn(&model.EmailVerificationCode{}, "attempts"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Where("version = ?", 35).Delete(&schemaMigration{}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := MigrateSchema(db); err != nil {
|
||||
t.Fatalf("upgrade from v34: %v", err)
|
||||
}
|
||||
for _, table := range []any{&model.AuthVerification{}, &model.NotificationQuota{}, &model.SMSChannel{}, &model.SMSRecord{}} {
|
||||
if !db.Migrator().HasTable(table) {
|
||||
t.Fatalf("migration v35 did not restore table %T", table)
|
||||
}
|
||||
}
|
||||
for _, column := range []string{"phone", "email_verified_at", "phone_verified_at"} {
|
||||
if !db.Migrator().HasColumn(&model.User{}, column) {
|
||||
t.Fatalf("migration v35 did not restore users.%s", column)
|
||||
}
|
||||
}
|
||||
if !db.Migrator().HasColumn(&model.EmailVerificationCode{}, "attempts") {
|
||||
t.Fatal("migration v35 did not restore email verification attempts")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMigrateSchemaV15UpgradesExistingDatabase(t *testing.T) {
|
||||
db, err := Open(Config{Driver: "sqlite", DSN: "file:migration-agent-profiles-v15?mode=memory&cache=shared"})
|
||||
if err != nil {
|
||||
|
||||
@@ -169,6 +169,23 @@ func migrateSchemaV1(db *gorm.DB) error {
|
||||
return db.Exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email_nonempty ON users(lower(email)) WHERE email <> ''").Error
|
||||
}
|
||||
|
||||
// migrateSchemaV35 installs the authentication notification tables and fields
|
||||
// added after the v34 deployment line. They cannot be added to the baseline
|
||||
// model registry alone because existing databases never rerun migration v1.
|
||||
func migrateSchemaV35(db *gorm.DB) error {
|
||||
if err := db.AutoMigrate(
|
||||
&model.User{},
|
||||
&model.EmailVerificationCode{},
|
||||
&model.AuthVerification{},
|
||||
&model.NotificationQuota{},
|
||||
&model.SMSChannel{},
|
||||
&model.SMSRecord{},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_users_phone_nonempty ON users(phone) WHERE phone <> ''").Error
|
||||
}
|
||||
|
||||
func backfillProjectUnitWordCounts(db *gorm.DB) error {
|
||||
var units []model.ProjectUnit
|
||||
if err := db.Select("id", "source_text").Where("word_count = 0 AND source_text <> ''").Find(&units).Error; err != nil {
|
||||
|
||||
Reference in New Issue
Block a user