package database import ( "fmt" "log" "strings" "time" "golang.org/x/crypto/bcrypt" "social-raiting.nekiiinkognito.ru/internal/config" "social-raiting.nekiiinkognito.ru/internal/models" "gorm.io/driver/mysql" "gorm.io/gorm" ) func Connect(cfg config.Config) *gorm.DB { dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", cfg.DBUser, cfg.DBPassword, cfg.DBHost, cfg.DBPort, cfg.DBName, ) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatalf("failed to connect to mysql: %v", err) } sqlDB, err := db.DB() if err != nil { log.Fatalf("failed to create sql database handle: %v", err) } sqlDB.SetConnMaxLifetime(5 * time.Minute) sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(25) if err := sqlDB.Ping(); err != nil { log.Fatalf("failed to ping mysql: %v", err) } if err := db.AutoMigrate(&models.User{}); err != nil { log.Fatalf("failed to migrate database: %v", err) } if err := db.AutoMigrate(&models.UserSocialRating{}, &models.SocialRatingOperation{}); err != nil { log.Fatalf("failed to migrate database: %v", err) } ensureDefaultAdmin(db, cfg) return db } func ensureDefaultAdmin(db *gorm.DB, cfg config.Config) { email := strings.ToLower(strings.TrimSpace(cfg.DefaultAdminEmail)) password := strings.TrimSpace(cfg.DefaultAdminPassword) if email == "" || password == "" { log.Println("skipping default admin bootstrap because admin credentials are empty") return } var user models.User err := db.Where("email = ?", email).First(&user).Error if err == nil { if !user.IsAdmin { if updateErr := db.Model(&user).Update("is_admin", true).Error; updateErr != nil { log.Fatalf("failed to promote default admin user: %v", updateErr) } } return } if err != gorm.ErrRecordNotFound { log.Fatalf("failed to check default admin user: %v", err) } passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { log.Fatalf("failed to hash default admin password: %v", err) } user = models.User{ Email: email, PasswordHash: string(passwordHash), IsAdmin: true, } if err := db.Create(&user).Error; err != nil { log.Fatalf("failed to create default admin user: %v", err) } }