package ownership import ( "RenewCMS/api/pkg/access" "RenewCMS/api/pkg/apperr" validator "RenewCMS/api/pkg/validator" "RenewCMS/internal/domain/user" "RenewCMS/internal/infrastructure/useCases" "encoding/json" "errors" "net/http" ) type Handler struct { TransferUseCase *useCases.TransferOwnershipUseCase } type TransferRequest struct { UserID uint32 `json:"user_id" validate:"required"` ConfirmEmail string `json:"confirm_email" validate:"required"` } func NewHandler(transfer *useCases.TransferOwnershipUseCase) *Handler { return &Handler{TransferUseCase: transfer} } func (h *Handler) Transfer(w http.ResponseWriter, r *http.Request) { var request TransferRequest if err := json.NewDecoder(r.Body).Decode(&request); err != nil { http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest) return } if err := validator.Validate.Struct(request); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } transferred, err := h.TransferUseCase.Transfer(r.Context(), useCases.TransferOwnershipCommand{ Caller: access.CallerOf(r), UserID: request.UserID, ConfirmEmail: request.ConfirmEmail, }) if err != nil { writeTransferError(w, err) return } body, err := json.Marshal(transferred) if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } w.Header().Set("Cache-Control", "no-store") _, _ = w.Write(body) } func writeTransferError(w http.ResponseWriter, err error) { switch { case errors.Is(err, user.ErrInvalidTransfer): http.Error(w, apperr.InvalidTransferErrorMessage, http.StatusBadRequest) case errors.Is(err, user.ErrConfirmationMismatch): http.Error(w, apperr.ConfirmationMismatchErrorMessage, http.StatusBadRequest) case errors.Is(err, user.ErrRoleChanged): http.Error(w, apperr.UserRoleChangedErrorMessage, http.StatusConflict) default: http.Error(w, "Internal server error", http.StatusInternalServerError) } }