feat: added endpoint to update list item title only
This commit is contained in:
@@ -353,6 +353,56 @@ func (h *ListHandler) UpdateListItem(w http.ResponseWriter, r *http.Request) {
|
|||||||
response.Status(w, http.StatusNoContent)
|
response.Status(w, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetListItemTitle handles updating "title" of a list item
|
||||||
|
//
|
||||||
|
// @Summary Updates "title" of list item
|
||||||
|
// @Description Update an existing list item, setting the "title" field
|
||||||
|
// @Tags List
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "List Item ID"
|
||||||
|
// @Param payload body request.SetListItemTitlePayload true "Update list item title payload"
|
||||||
|
// @Success 204 {object} nil
|
||||||
|
// @Error 400 {object} response.ErrorResponse "failed to decode request url"
|
||||||
|
// @Error 400 {object} response.ErrorResponse "failed to decode request body"
|
||||||
|
// @Error 401 {object} response.ErrorResponse "not authorized"
|
||||||
|
// @Error 500 {object} response.ErrorResponse "failed to set list item title"
|
||||||
|
// @Router /lists/items/{id}/title [post]
|
||||||
|
func (h *ListHandler) SetListItemTitle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
listItemID := r.PathValue("id")
|
||||||
|
if listItemID == "" {
|
||||||
|
slog.ErrorContext(ctx, "failed to read list item id from path")
|
||||||
|
response.Error(ctx, w, http.StatusBadRequest, "failed to decode request url")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload, err := request.DecodeJSON[request.SetListItemTitlePayload](r)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "failed to decode set list item title payload", slog.Any("error", err))
|
||||||
|
response.Error(ctx, w, http.StatusBadRequest, "failed to decode request body")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
authContext, err := domain.GetAuthContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "failed to get auth context", slog.Any("error", err))
|
||||||
|
response.Error(ctx, w, http.StatusUnauthorized, "not authorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.ListService.SetListItemTitle(ctx, authContext.UserID, listItemID, payload.Title)
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "failed to set list item title", slog.Any("error", err))
|
||||||
|
response.Error(ctx, w, http.StatusInternalServerError, "failed to set list item title")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.InfoContext(ctx, "update list item title successful", slog.String("list_item_id", listItemID))
|
||||||
|
response.Status(w, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
// SetListItemCompleted handles updating "is_completed" of a list item
|
// SetListItemCompleted handles updating "is_completed" of a list item
|
||||||
//
|
//
|
||||||
// @Summary Updates "is_completed" of list item
|
// @Summary Updates "is_completed" of list item
|
||||||
@@ -366,8 +416,8 @@ func (h *ListHandler) UpdateListItem(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Error 400 {object} response.ErrorResponse "failed to decode request url"
|
// @Error 400 {object} response.ErrorResponse "failed to decode request url"
|
||||||
// @Error 400 {object} response.ErrorResponse "failed to decode request body"
|
// @Error 400 {object} response.ErrorResponse "failed to decode request body"
|
||||||
// @Error 401 {object} response.ErrorResponse "not authorized"
|
// @Error 401 {object} response.ErrorResponse "not authorized"
|
||||||
// @Error 500 {object} response.ErrorResponse "failed to update list item"
|
// @Error 500 {object} response.ErrorResponse "failed to set list item completed"
|
||||||
// @Router /lists/items/{id} [post]
|
// @Router /lists/items/{id}/complete [post]
|
||||||
func (h *ListHandler) SetListItemCompleted(w http.ResponseWriter, r *http.Request) {
|
func (h *ListHandler) SetListItemCompleted(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
@@ -399,7 +449,7 @@ func (h *ListHandler) SetListItemCompleted(w http.ResponseWriter, r *http.Reques
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.InfoContext(ctx, "updated list item completed successful", slog.String("list_item_id", listItemID))
|
slog.InfoContext(ctx, "update list item completed successful", slog.String("list_item_id", listItemID))
|
||||||
response.Status(w, http.StatusNoContent)
|
response.Status(w, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ type UpdateListItemPayload struct {
|
|||||||
IsCompleted bool `json:"is_completed"`
|
IsCompleted bool `json:"is_completed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SetListItemTitlePayload struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
type SetListItemCompletedPayload struct {
|
type SetListItemCompletedPayload struct {
|
||||||
IsCompleted bool `json:"is_completed"`
|
IsCompleted bool `json:"is_completed"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ func NewMux(cfg Config) http.Handler {
|
|||||||
apiMux.Handle("POST /lists/items", protected(listHandler.CreateListItem))
|
apiMux.Handle("POST /lists/items", protected(listHandler.CreateListItem))
|
||||||
apiMux.Handle("DELETE /lists/items/{id}", protected(listHandler.DeleteListItem))
|
apiMux.Handle("DELETE /lists/items/{id}", protected(listHandler.DeleteListItem))
|
||||||
apiMux.Handle("PUT /lists/items", protected(listHandler.UpdateListItem))
|
apiMux.Handle("PUT /lists/items", protected(listHandler.UpdateListItem))
|
||||||
apiMux.Handle("POST /lists/items/{id}", protected(listHandler.SetListItemCompleted))
|
apiMux.Handle("POST /lists/items/{id}/title", protected(listHandler.SetListItemTitle))
|
||||||
|
apiMux.Handle("POST /lists/items/{id}/complete", protected(listHandler.SetListItemCompleted))
|
||||||
apiMux.Handle("GET /lists/{id}", protected(listHandler.GetListItems))
|
apiMux.Handle("GET /lists/{id}", protected(listHandler.GetListItems))
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ type ListRepository interface {
|
|||||||
CreateListItem(ctx context.Context, listID string, title string) (*ListItem, error)
|
CreateListItem(ctx context.Context, listID string, title string) (*ListItem, error)
|
||||||
DeleteListItem(ctx context.Context, listItemID string) error
|
DeleteListItem(ctx context.Context, listItemID string) error
|
||||||
UpdateListItem(ctx context.Context, listItemID string, title string, isCompleted bool) error
|
UpdateListItem(ctx context.Context, listItemID string, title string, isCompleted bool) error
|
||||||
|
SetListItemTitle(ctx context.Context, listItemID string, title string) error
|
||||||
SetListItemCompleted(ctx context.Context, listItemID string, isCompleted bool) error
|
SetListItemCompleted(ctx context.Context, listItemID string, isCompleted bool) error
|
||||||
GetListItems(ctx context.Context, listID string) ([]ListItem, error)
|
GetListItems(ctx context.Context, listID string) ([]ListItem, error)
|
||||||
}
|
}
|
||||||
@@ -172,6 +173,21 @@ func (s *ListService) UpdateListItem(ctx context.Context, authUserID string, lis
|
|||||||
return s.repo.UpdateListItem(ctx, listItemID, title, isCompleted)
|
return s.repo.UpdateListItem(ctx, listItemID, title, isCompleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ListService) SetListItemTitle(ctx context.Context, authUserID string, listItemID string, title string) error {
|
||||||
|
if listItemID == "" {
|
||||||
|
return ErrListItemIDMissing
|
||||||
|
}
|
||||||
|
if title == "" {
|
||||||
|
return ErrListItemTitleMissing
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.userAllowedToAccessListItem(ctx, authUserID, listItemID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.SetListItemTitle(ctx, listItemID, title)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ListService) SetListItemCompleted(ctx context.Context, authUserID string, listItemID string, isCompleted bool) error {
|
func (s *ListService) SetListItemCompleted(ctx context.Context, authUserID string, listItemID string, isCompleted bool) error {
|
||||||
if listItemID == "" {
|
if listItemID == "" {
|
||||||
return ErrListItemIDMissing
|
return ErrListItemIDMissing
|
||||||
|
|||||||
@@ -150,6 +150,17 @@ func (r *ListRepo) UpdateListItem(ctx context.Context, listItemID string, title
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ListRepo) SetListItemTitle(ctx context.Context, listItemID string, title string) error {
|
||||||
|
_, err := r.conn(ctx).ExecContext(ctx, "UPDATE list_items SET title = $1, modified_at = NOW() WHERE id = $2",
|
||||||
|
title, listItemID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update list item title: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ListRepo) SetListItemCompleted(ctx context.Context, listItemID string, isCompleted bool) error {
|
func (r *ListRepo) SetListItemCompleted(ctx context.Context, listItemID string, isCompleted bool) error {
|
||||||
_, err := r.conn(ctx).ExecContext(ctx, "UPDATE list_items SET is_completed = $1, modified_at = NOW() WHERE id = $2",
|
_, err := r.conn(ctx).ExecContext(ctx, "UPDATE list_items SET is_completed = $1, modified_at = NOW() WHERE id = $2",
|
||||||
isCompleted, listItemID,
|
isCompleted, listItemID,
|
||||||
|
|||||||
Reference in New Issue
Block a user