package controllers import ( "58team_blog/internal/application/commands" "58team_blog/internal/application/queries" "58team_blog/internal/application/services" "58team_blog/internal/interfaces/api/mapper" "58team_blog/internal/interfaces/api/requests" "58team_blog/internal/interfaces/api/responses" "58team_blog/internal/utils" "log" "net/http" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type UserController struct { service *services.UserService } func CreateUserController(service *services.UserService) UserController { return UserController{ service: service, } } // @Summary Create new user // @Description Creates new user in system // @Tags user // @Accept json // @Produce json // @Param request body requests.CreateUserRequest true "User data" // @Success 201 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 409 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/ [post] func (r *UserController) Post(c *gin.Context) { var request requests.CreateUserRequest if err := c.BindJSON(&request); err != nil { log.Println("User invalid request: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, err.Error()) c.JSON(resp.ErrorCode, resp) return } encrypted_password, err := utils.EncryptPassword(request.Password) if err != nil { log.Println("User encrypt password error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } cmd := commands.CreateUserCommand{ Username: request.Username, Password: encrypted_password, } user, err := r.service.Create(cmd) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserResult(user) c.JSON(http.StatusCreated, response) } // @Summary Find user by id // @Description Find user by id // @Tags user // @Accept json // @Produce json // @Param id path string true "user id" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/{id} [get] func (r *UserController) FindById(c *gin.Context) { id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id") c.JSON(resp.ErrorCode, resp) return } query := queries.UserFindByIdQuery{ Id: id, } user, err := r.service.FindById(query) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserFindByIdResult(user) c.JSON(http.StatusOK, response) } // @Summary Find user by username // @Description Find user by username // @Tags user // @Accept json // @Produce json // @Param name path string true "User name" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/name/{name} [get] func (r *UserController) FindByName(c *gin.Context) { name := c.Param("name") query := queries.UserFindByNameQuery{ Name: name, } user, err := r.service.FindByName(query) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserFindByNameResult(user) c.JSON(http.StatusOK, response) } // @Summary Get all users // @Description Return all registered users // @Tags user // @Produce json // @Success 200 {object} responses.UserResponseList // @Failure 400 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/ [get] func (r *UserController) GetAll(c *gin.Context) { users, err := r.service.GetAll() if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } responses := mapper.ResponseFromUserGetAllResult(users) c.JSON(http.StatusOK, responses) } // @Summary Change user // @Description Change the user's name and password // @Tags user // @Accept json // @Produce json // @Param id path string true "User id" // @Param request body requests.PutUserRequest true "User data" // @Success 200 {object} responses.UserResponse // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/{id} [put] func (r *UserController) Put(c *gin.Context) { var request requests.PutUserRequest id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user ID") c.JSON(resp.ErrorCode, resp) return } if err := c.BindJSON(&request); err != nil { log.Println("User request error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, err.Error()) c.JSON(resp.ErrorCode, resp) return } password, err := utils.EncryptPassword(request.Password) if err != nil { log.Println("User password encrypt error: ", err) resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error") c.JSON(resp.ErrorCode, resp) return } cmd := commands.UpdateUserCommand{ Id: id, Username: request.Username, Password: password, } user, err := r.service.Update(cmd) if err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } response := mapper.ResponseFromUserResult(user) c.JSON(http.StatusOK, response) } // @Summary Delete user // @Description Delete user // @Tags user // @Produce json // @Param id path string true "User id" // @Success 200 // @Failure 400 {object} responses.ErrorResponse // @Failure 404 {object} responses.ErrorResponse // @Failure 500 {object} responses.ErrorResponse // @Router /user/{id} [delete] func (r *UserController) Delete(c *gin.Context) { id_path := c.Param("id") id, err := uuid.Parse(id_path) if err != nil { log.Println("User id error: ", err) resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id") c.JSON(resp.ErrorCode, resp) return } cmd := commands.DeleteUserCommand{ Id: id, } if err := r.service.Delete(cmd); err != nil { resp := utils.HandleError(err) c.JSON(resp.ErrorCode, resp) return } c.Status(http.StatusOK) }