// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/auth/register.go package auth import ( "encoding/json" "net/http" "go.uber.org/zap" svc_auth "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/auth" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation" ) // RegisterHandler handles user registration type RegisterHandler struct { logger *zap.Logger service svc_auth.RegisterService } // NewRegisterHandler creates a new registration handler func NewRegisterHandler( logger *zap.Logger, service svc_auth.RegisterService, ) *RegisterHandler { return &RegisterHandler{ logger: logger.Named("RegisterHandler"), service: service, } } // ServeHTTP handles the HTTP request func (h *RegisterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() // Extract request ID from existing middleware requestID := httperror.ExtractRequestID(r) // Decode request var req svc_auth.RegisterRequestDTO if err := json.NewDecoder(r.Body).Decode(&req); err != nil { h.logger.Error("Failed to decode register request", zap.Error(err)) problem := httperror.NewBadRequestError("Invalid request payload: " + err.Error()) problem.WithInstance(r.URL.Path).WithTraceID(requestID) httperror.RespondWithProblem(w, problem) return } // Call service - service handles validation and returns RFC 9457 errors resp, err := h.service.Execute(ctx, &req) if err != nil { // Check if error is already a ProblemDetail if problem, ok := err.(*httperror.ProblemDetail); ok { h.logger.Warn("Registration failed with validation errors", zap.String("email", validation.MaskEmail(req.Email)), zap.Int("error_count", len(problem.Errors))) problem.WithInstance(r.URL.Path).WithTraceID(requestID) httperror.RespondWithProblem(w, problem) return } // Unexpected error - wrap in internal server error h.logger.Error("Registration failed with unexpected error", zap.String("email", validation.MaskEmail(req.Email)), zap.Error(err)) problem := httperror.NewInternalServerError("Registration failed: " + err.Error()) problem.WithInstance(r.URL.Path).WithTraceID(requestID) httperror.RespondWithProblem(w, problem) return } // Return success response h.logger.Info("User registered successfully", zap.String("user_id", resp.UserID)) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(resp) }