package models import ( "log/slog" "strings" "gorm.io/gorm" ) // AllModels returns all models for auto-migration func AllModels() []interface{} { return []interface{}{ &User{}, &Category{}, &LotMetadata{}, &Configuration{}, &PriceOverride{}, &PricingAlert{}, &ComponentUsageStats{}, &Pricelist{}, &PricelistItem{}, } } // Migrate runs auto-migration for all QuoteForge tables // Handles MySQL constraint errors gracefully for existing tables func Migrate(db *gorm.DB) error { for _, model := range AllModels() { if err := db.AutoMigrate(model); err != nil { // Skip known MySQL constraint errors for existing tables errStr := err.Error() if strings.Contains(errStr, "Can't DROP") || strings.Contains(errStr, "Duplicate key name") || strings.Contains(errStr, "check that it exists") { slog.Warn("migration warning (skipped)", "model", model, "error", errStr) continue } return err } } return nil } // SeedCategories inserts default categories if not exist func SeedCategories(db *gorm.DB) error { for _, cat := range DefaultCategories { result := db.Where("code = ?", cat.Code).FirstOrCreate(&cat) if result.Error != nil { return result.Error } } return nil } // SeedAdminUser creates default admin user if not exists // Default credentials: admin / admin123 func SeedAdminUser(db *gorm.DB, passwordHash string) error { var count int64 db.Model(&User{}).Where("username = ?", "admin").Count(&count) if count > 0 { return nil } admin := &User{ Username: "admin", Email: "admin@example.com", PasswordHash: passwordHash, Role: RoleAdmin, IsActive: true, } return db.Create(admin).Error } // EnsureDBUser creates or returns the user corresponding to the database connection username. // This is used when RBAC is disabled - configurations are owned by the DB user. // Returns the user ID that should be used for all operations. func EnsureDBUser(db *gorm.DB, dbUsername string) (uint, error) { if dbUsername == "" { return 0, nil } var user User err := db.Where("username = ?", dbUsername).First(&user).Error if err == nil { return user.ID, nil } // User doesn't exist, create it user = User{ Username: dbUsername, Email: dbUsername + "@db.local", PasswordHash: "-", // No password - this is a DB user, not an app user Role: RoleAdmin, IsActive: true, } if err := db.Create(&user).Error; err != nil { slog.Error("failed to create DB user", "username", dbUsername, "error", err) return 0, err } slog.Info("created DB user for configurations", "username", dbUsername, "user_id", user.ID) return user.ID, nil }