package database import ( _ "embed" "fmt" "juhe-factory/api/internal/model" "gorm.io/gorm" "gorm.io/gorm/logger" ) //go:embed schema.sql var baselineSchema string func bootstrapEmptyDatabase(db *gorm.DB) error { var businessTableCount int64 if err := db.Raw(`SELECT count(*) FROM pg_tables WHERE schemaname = 'public' AND tablename NOT IN ('jcf_schema_migrations', 'schema_migrations')`). Scan(&businessTableCount).Error; err != nil { return fmt.Errorf("inspect database schema: %w", err) } if businessTableCount == 0 { baselineDB := db.Session(&gorm.Session{Logger: logger.Default.LogMode(logger.Silent)}) if err := baselineDB.Transaction(func(tx *gorm.DB) error { return tx.Exec(baselineSchema).Error }); err != nil { return fmt.Errorf("initialize database baseline: %w", err) } if err := db.Exec(`SET search_path TO public`).Error; err != nil { return fmt.Errorf("restore database search path: %w", err) } } if err := autoMigrateMissingTables(db, autoMigrateModels()...); err != nil { return fmt.Errorf("auto migrate database models: %w", err) } return nil } func autoMigrateMissingTables(db *gorm.DB, tableModels ...any) error { for _, tableModel := range tableModels { if db.Migrator().HasTable(tableModel) { continue } if err := db.AutoMigrate(tableModel); err != nil { return err } } return nil } func autoMigrateModels() []any { return []any{ &model.AdminUser{}, &model.AdminRefreshToken{}, &model.AdminAuditLog{}, &model.WebUser{}, &model.WebRefreshToken{}, &model.MediaAsset{}, &model.CreativeProject{}, &model.ProjectModelConfig{}, &model.UserModelConfig{}, &model.ScriptAnalysis{}, &model.ScriptAnalysisCharacter{}, &model.ProjectEpisode{}, &model.ProjectAsset{}, &model.EpisodeStoryboard{}, &model.EpisodeSource{}, &model.DramaImportSession{}, &model.DramaParseBatch{}, &model.DramaParseTask{}, &model.GenerationTask{}, &model.GenerationOutput{}, } }