package api import ( "encoding/json" "net/http" "dance-lessons-coach/pkg/user" "github.com/go-chi/chi/v5" "github.com/rs/zerolog/log" ) // UserHandler handles user management requests type UserHandler struct { userRepo user.UserRepository passwordService user.PasswordService } // NewUserHandler creates a new user handler func NewUserHandler(userRepo user.UserRepository, passwordService user.PasswordService) *UserHandler { return &UserHandler{ userRepo: userRepo, passwordService: passwordService, } } // RegisterRoutes registers user routes func (h *UserHandler) RegisterRoutes(router chi.Router) { router.Post("/register", h.handleRegister) } // RegisterRequest represents a user registration request // handleRegister handles user registration requests func (h *UserHandler) handleRegister(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var req RegisterRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, `{"error":"invalid_request","message":"Invalid JSON request body"}`, http.StatusBadRequest) return } // Check if user already exists exists, err := h.userRepo.UserExists(ctx, req.Username) if err != nil { log.Error().Ctx(ctx).Err(err).Msg("Failed to check if user exists") http.Error(w, `{"error":"server_error","message":"Failed to process registration"}`, http.StatusInternalServerError) return } if exists { http.Error(w, `{"error":"user_exists","message":"Username already taken"}`, http.StatusConflict) return } // Hash password hashedPassword, err := h.passwordService.HashPassword(ctx, req.Password) if err != nil { log.Error().Ctx(ctx).Err(err).Msg("Failed to hash password") http.Error(w, `{"error":"server_error","message":"Failed to process registration"}`, http.StatusInternalServerError) return } // Create user newUser := &user.User{ Username: req.Username, PasswordHash: hashedPassword, IsAdmin: false, } if err := h.userRepo.CreateUser(ctx, newUser); err != nil { log.Error().Ctx(ctx).Err(err).Msg("Failed to create user") http.Error(w, `{"error":"server_error","message":"Failed to create user"}`, http.StatusInternalServerError) return } // Return success w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]string{"message": "User registered successfully"}) }