package main import ( "context" "fmt" "wm-backend/configs" "wm-backend/internal/initialization" "wm-backend/internal/models" "wm-backend/pkg/helper" "github.com/jackc/pgx/v5/pgxpool" "github.com/rs/zerolog/log" ) func main() { cfg, err := configs.LoadConfig("configs") if err != nil { log.Fatal().Err(err).Msg("Error loading config") } pool, err := initialization.ConnectPostgreSQL(&cfg) if err != nil { log.Fatal().Err(err).Msg("Error connecting to database") } defer pool.Close() err = seedAdmin(pool, &cfg) if err != nil { log.Fatal().Err(err).Msg("Error seeding admin") } log.Info().Msg("Seed completed successfully") } func seedAdmin(pool *pgxpool.Pool, cfg *models.Config) error { ctx := context.Background() // Check if admin user already exists var exists bool err := pool.QueryRow(ctx, "SELECT EXISTS(SELECT 1 FROM users WHERE username = $1)", cfg.Admin.Username, ).Scan(&exists) if err != nil { return fmt.Errorf("checking existing admin: %w", err) } if exists { log.Info().Str("username", cfg.Admin.Username).Msg("Admin user already exists, skipping") return nil } // Hash password hashedPassword, err := helper.HashPassword(cfg.Admin.Password) if err != nil { return fmt.Errorf("hashing password: %w", err) } // Get SYS_ADMIN role ID var roleID string err = pool.QueryRow(ctx, "SELECT id FROM roles WHERE name = 'SYS_ADMIN'", ).Scan(&roleID) if err != nil { return fmt.Errorf("SYS_ADMIN role not found (did init.sql run?): %w", err) } // Create admin user and assign role in a transaction tx, err := pool.Begin(ctx) if err != nil { return fmt.Errorf("begin transaction: %w", err) } defer tx.Rollback(ctx) var userID string err = tx.QueryRow(ctx, `INSERT INTO users (username, email, password_hash, full_name, is_active, created_by) VALUES ($1, $2, $3, $4, TRUE, 'system') RETURNING id`, cfg.Admin.Username, cfg.Admin.Email, hashedPassword, cfg.Admin.FullName, ).Scan(&userID) if err != nil { return fmt.Errorf("creating admin user: %w", err) } _, err = tx.Exec(ctx, `INSERT INTO user_roles (user_id, role_id) VALUES ($1, $2)`, userID, roleID, ) if err != nil { return fmt.Errorf("assigning SYS_ADMIN role: %w", err) } if err := tx.Commit(ctx); err != nil { return fmt.Errorf("commit transaction: %w", err) } log.Info(). Str("username", cfg.Admin.Username). Str("email", cfg.Admin.Email). Str("role", "SYS_ADMIN"). Msg("Admin user created successfully") return nil }