From 9bab3a1212f582760c8dc475162a234e257d9b06 Mon Sep 17 00:00:00 2001 From: dnabil Date: Sat, 9 Dec 2023 11:42:18 +0700 Subject: [PATCH] feat(todo): update --- todo-list-be/app/http/handler/todo_handler.go | 29 ++++++++++++++++ todo-list-be/app/http/route/route.go | 1 + todo-list-be/dto/todo_dto.go | 15 ++++++++ todo-list-be/repo/todo_repo.go | 5 +++ todo-list-be/service/todo_service.go | 34 +++++++++++++++++++ 5 files changed, 84 insertions(+) diff --git a/todo-list-be/app/http/handler/todo_handler.go b/todo-list-be/app/http/handler/todo_handler.go index 28b483e..3cdd5cd 100644 --- a/todo-list-be/app/http/handler/todo_handler.go +++ b/todo-list-be/app/http/handler/todo_handler.go @@ -48,4 +48,33 @@ func (h *TodoHandler) Create(c *gin.Context){ } Response(c, http.StatusCreated, "todo created", todo) +} + +func (h *TodoHandler) Update(c *gin.Context){ + req := new(dto.UpdateTodoRequest) + if err := c.ShouldBindJSON(&req); err != nil { + Response(c, http.StatusBadRequest, "bad request", nil) + return + } + + if err := req.Validate(); err != nil { + Response(c, http.StatusBadRequest, "validation fail", err) + return + } + + auth, _, err := getAuth(c, h.Log) + if err != nil { + Response(c, err.Code(), err.Error(), nil) + return + } + + req.UserID = auth.ID + + todo, err := h.Service.Update(c.Request.Context(), req) + if err != nil { + Response(c, err.Code(), err.Error(), nil) + return + } + + Response(c, http.StatusOK, "update success", todo) } \ No newline at end of file diff --git a/todo-list-be/app/http/route/route.go b/todo-list-be/app/http/route/route.go index f0f6c44..5c2d21f 100644 --- a/todo-list-be/app/http/route/route.go +++ b/todo-list-be/app/http/route/route.go @@ -28,6 +28,7 @@ func (r *RouteConfig) Load() { todo := api.Group("/todos") todo.Use(r.AuthMiddleware) todo.POST("/", r.TodoHandler.Create) + todo.PUT("/", r.TodoHandler.Update) // api.GET("/todos", r.TodoHandler.Index) // ada yang completed ada yang ngga (param) // api.DELETE("/todos", r.TodoHandler.DELETE) } \ No newline at end of file diff --git a/todo-list-be/dto/todo_dto.go b/todo-list-be/dto/todo_dto.go index f3ffbd8..fe62cc1 100644 --- a/todo-list-be/dto/todo_dto.go +++ b/todo-list-be/dto/todo_dto.go @@ -43,4 +43,19 @@ func (r *CreateTodoRequest) Validate() error{ return validation.ValidateStruct(r, validation.Field(&r.Name, validation.Required, validation.Length(2, 255)), ) +} + +type UpdateTodoRequest struct { + ID uint `json:"id"` + UserID uint `json:"-"` + + Name string `json:"name"` + IsDone *bool `json:"is_done"` +} +func (r *UpdateTodoRequest) Validate() error{ + return validation.ValidateStruct(r, + validation.Field(&r.ID, validation.Required), + validation.Field(&r.Name, validation.Required, validation.Length(2, 255)), + validation.Field(&r.IsDone, validation.Required), // https://github.com/go-ozzo/ozzo-validation/issues/79 jadi pake * + ) } \ No newline at end of file diff --git a/todo-list-be/repo/todo_repo.go b/todo-list-be/repo/todo_repo.go index c8b3dc4..0a3b3b5 100644 --- a/todo-list-be/repo/todo_repo.go +++ b/todo-list-be/repo/todo_repo.go @@ -4,6 +4,7 @@ import ( "todo-list-be/model" "github.com/sirupsen/logrus" + "gorm.io/gorm" ) type TodoRepo struct { @@ -15,4 +16,8 @@ func NewTodoRepo(log *logrus.Logger) *TodoRepo { return &TodoRepo{ Log: log, } +} + +func (r *TodoRepo) FindByIdAndUserId(db *gorm.DB, todo *model.Todo, id uint, userId uint) error { + return db.Where("id = ? AND user_id = ?", id, userId).Take(todo).Error } \ No newline at end of file diff --git a/todo-list-be/service/todo_service.go b/todo-list-be/service/todo_service.go index e7dc3f5..65ee174 100644 --- a/todo-list-be/service/todo_service.go +++ b/todo-list-be/service/todo_service.go @@ -48,5 +48,39 @@ func (s *TodoService) Create(ctx context.Context, req *dto.CreateTodoRequest) (* resource := dto.NewTodoResource(todo) + return resource, nil +} + +func (s *TodoService) Update(ctx context.Context, req *dto.UpdateTodoRequest) (*dto.TodoResource, errcode.ErrCodeI) { + tx := s.DB.WithContext(ctx).Begin() + defer tx.Rollback() + + // + // find by id and userid + todo := new(model.Todo) + if err := s.Repo.FindByIdAndUserId(tx, todo, req.ID, req.UserID); err != nil { + if err == gorm.ErrRecordNotFound { + return nil, errcode.ErrNotFound + } + + s.Log.WithError(err).Errorln("failed to find todo by id and user id") + return nil, errcode.ErrInternalServer + } + + // update + todo.Name = req.Name + todo.IsDone = *req.IsDone + if err := s.Repo.Update(tx, todo); err != nil { + s.Log.WithError(err).Errorln("failed to update(s) todo") + return nil, errcode.ErrInternalServer + } + // + + if err := tx.Commit().Error; err != nil { + s.Log.WithError(err).Warnln("Failed commit transaction") + return nil, errcode.ErrInternalServer + } + + resource := dto.NewTodoResource(todo) return resource, nil } \ No newline at end of file