package main import ( "fmt" "log" "sql-platform/config" "sql-platform/internal/middleware" "sql-platform/internal/model" "sql-platform/router" "github.com/gin-gonic/gin" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func main() { // Load config config.Init() if !config.C.Debug { gin.SetMode(gin.ReleaseMode) } // Connect to SQLite db, err := gorm.Open(sqlite.Open(config.C.DBPath), &gorm.Config{}) if err != nil { log.Fatalf("Failed to connect to database: %v", err) } model.DB = db // Auto-migrate (add missing tables/columns, won\'t drop existing data) _ = db.AutoMigrate( &model.User{}, &model.Instance{}, &model.Ticket{}, &model.TicketApproval{}, &model.TicketSQLItem{}, &model.AuditRule{}, &model.AuditLog{}, &model.QueryHistory{}, &model.WorkflowDefinition{}, &model.WorkflowStep{}, &model.WorkflowVersion{}, &model.WorkflowExecutionLog{}, &model.Announcement{}, &model.InstanceGroup{}, &model.InstanceGroupMember{}, &model.LDAPConfig{}, &model.NotificationChannel{}, &model.NotificationTemplate{}, &model.SystemSetting{}, &model.OperationLog{}, &model.MaskingRule{}, &model.Backup{}, &model.SchemaRevision{}, &model.SlowLog{}, &model.ScheduledTask{}, &model.ScheduledTaskLog{}, &model.UserGroup{}, ) // Seed default settings (idempotent) seedDefaultSettings(db) // Setup Gin r := gin.Default() r.Use(middleware.CORSMiddleware()) // Health check r.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok", "version": "0.3.1", "backend": "go"}) }) // Routes router.Setup(r) // Start server addr := fmt.Sprintf(":%s", config.C.Port) log.Printf("SQL Platform Go backend starting on %s", addr) if err := r.Run(addr); err != nil { log.Fatalf("Failed to start server: %v", err) } } func seedDefaultSettings(db *gorm.DB) { defaults := []model.SystemSetting{ // Data masking group {Key: "data_masking_enabled", Value: "true", ValueType: "boolean", Group: "data_masking", Label: "启用数据脱敏", Desc: strPtr("启用后,查询结果中的敏感字段将被替换为 *"), DefaultValue: strPtr("true"), SortOrder: 1}, {Key: "data_masking_sensitive_fields", Value: "mobile,concat_mobile,email_alias,email,password,ga_key,private_key,secret,secret_key,key_snow,telephone,username,real_name,token,two_factor_secret,content,phone", ValueType: "string", Group: "data_masking", Label: "默认敏感字段列表", Desc: strPtr("全局敏感字段,逗号分隔。匹配列名(不区分大小写)"), DefaultValue: strPtr("mobile,concat_mobile,email_alias,email,password,ga_key,private_key,secret,secret_key,key_snow,telephone,username,real_name,token,two_factor_secret,content,phone"), SortOrder: 2}, } for _, s := range defaults { var existing model.SystemSetting if db.Where("`key` = ?", s.Key).First(&existing).Error != nil { db.Create(&s) } } } func strPtr(s string) *string { return &s }