Skip to content

[feature] endpoint update status user #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions internal/users/delivery/http/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package handler

import (
"context"
"errors"
"net/http"
"strconv"
"time"
Expand All @@ -17,6 +18,7 @@ type (
Handlers interface {
CreateUser(c echo.Context) error
UpdateUser(c echo.Context) error
UpdateUserStatus(c echo.Context) error
}

handlers struct {
Expand All @@ -25,6 +27,15 @@ type (
}
)

const (
BooleanTextTrue = "true"
BooleanTextFalse = "false"
)

var (
ErrInvalidIsActive = errors.New("invalid is_active")
)

func NewHandlers(uc usecases.Usecase, log *zerolog.Logger) Handlers {
return &handlers{uc, log}
}
Expand Down Expand Up @@ -133,3 +144,49 @@ func (h *handlers) UpdateUser(c echo.Context) error {

return c.JSON(http.StatusOK, dtos.NewResponse(http.StatusOK, dtos.MsgSuccess, nil))
}

func (h *handlers) UpdateUserStatus(c echo.Context) error {
var (
ctx, cancel = context.WithTimeout(c.Request().Context(), time.Duration(30*time.Second))
payload dtos.UpdateUserStatusPayload
)
defer cancel()

userID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
h.log.Z().Err(err).Msg("[handlers]UpdateUser.ParseParam")

return c.JSON(http.StatusBadRequest, dtos.NewResponseError(
http.StatusBadRequest,
dtos.MsgFailed,
dtos.Text(http.StatusBadRequest),
err.Error()),
)
}

switch c.QueryParam("is_active") {
case BooleanTextFalse:
payload.IsActive = false
case BooleanTextTrue:
payload.IsActive = true
default:
return c.JSON(http.StatusBadRequest, dtos.NewResponseError(
http.StatusBadRequest,
dtos.MsgFailed,
dtos.Text(http.StatusBadRequest),
ErrInvalidIsActive.Error()),
)
}

err = h.uc.UpdateUserStatus(ctx, &entities.UpdateUsers{UserID: userID, IsActive: payload.IsActive})
if err != nil {
return c.JSON(http.StatusBadRequest, dtos.NewResponseError(
http.StatusInternalServerError,
dtos.MsgFailed,
dtos.Text(http.StatusInternalServerError),
err.Error()),
)
}

return c.JSON(http.StatusOK, dtos.NewResponse(http.StatusOK, dtos.MsgSuccess, nil))
}
7 changes: 4 additions & 3 deletions internal/users/delivery/http/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import (
"github.com/labstack/echo/v4"
)

func RouteUsers(version *echo.Group, ctrl handler.Handlers) {
func RouteUsers(version *echo.Group, handler handler.Handlers) {
users := version.Group("users")
users.POST("", ctrl.CreateUser)
users.PATCH("/:id", ctrl.UpdateUser)
users.POST("", handler.CreateUser)
users.PATCH("/:id", handler.UpdateUser)
users.PUT("/:id", handler.UpdateUserStatus)
}
6 changes: 6 additions & 0 deletions internal/users/dtos/update_user_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dtos

type UpdateUserStatusPayload struct {
UserID int64
IsActive bool
}
1 change: 1 addition & 0 deletions internal/users/entities/update_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type UpdateUsers struct {
Fullname string
PhoneNumber string
UserType string
IsActive bool
UpdatedAt string
UpdatedBy string
}
Expand Down
29 changes: 28 additions & 1 deletion internal/users/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"context"
"errors"

"github.com/DoWithLogic/golang-clean-architecture/internal/users/entities"
"github.com/DoWithLogic/golang-clean-architecture/internal/users/repository/repository_query"
Expand All @@ -15,6 +16,7 @@ type (
SaveNewUser(context.Context, *entities.Users) (int64, error)
UpdateUserByID(context.Context, *entities.UpdateUsers) error
GetUserByID(context.Context, int64, entities.LockingOpt) (entities.Users, error)
UpdateUserStatusByID(context.Context, *entities.Users) error
}

repository struct {
Expand All @@ -23,6 +25,10 @@ type (
}
)

var (
ErrUserNotFound = errors.New("user not found")
)

func NewRepository(conn database.SQLTxConn, log *zerolog.Logger) Repository {
return &repository{conn, log}
}
Expand Down Expand Up @@ -86,7 +92,6 @@ func (repo *repository) GetUserByID(ctx context.Context, userID int64, lockOpt e
&userData.IsActive,
&userData.CreatedAt,
}

}

query := repository_query.GetUserByID
Expand All @@ -102,5 +107,27 @@ func (repo *repository) GetUserByID(ctx context.Context, userID int64, lockOpt e
return userData, err
}

if userData.UserID != userID {
return userData, ErrUserNotFound
}

return userData, err
}

func (repo *repository) UpdateUserStatusByID(ctx context.Context, req *entities.Users) error {
args := custom.Array{
req.IsActive,
req.UpdatedAt,
req.UpdatedBy,
req.UserID,
}

err := new(database.SQL).Exec(repo.conn.ExecContext(ctx, repository_query.UpdateUserStatusByID, args...)).Scan(nil, nil)
if err != nil {
repo.log.Z().Err(err).Msg("[repository]UpdateUserStatusByID.ExecContext")

return err
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ var (
InsertUsers string
//go:embed users/update.sql
UpdateUsers string
//go:embed users/update_status_by_id.sql
UpdateUserStatusByID string
//go:embed users/select.sql
GetUserByID string
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
UPDATE users SET
is_active = ?,
updated_at = ?,
updated_by = ?
WHERE id = ?
26 changes: 26 additions & 0 deletions internal/users/usecase/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package usecase

import (
"context"
"fmt"
"time"

"github.com/DoWithLogic/golang-clean-architecture/internal/users/entities"
"github.com/DoWithLogic/golang-clean-architecture/internal/users/repository"
Expand All @@ -14,6 +16,7 @@ type (
Usecase interface {
CreateUser(context.Context, *entities.Users) (int64, error)
UpdateUser(context.Context, *entities.UpdateUsers) error
UpdateUserStatus(context.Context, *entities.UpdateUsers) error
}

usecase struct {
Expand Down Expand Up @@ -66,3 +69,26 @@ func (uc *usecase) UpdateUser(ctx context.Context, updateData *entities.UpdateUs
return nil
}(uc.dbTx)
}

func (uc *usecase) UpdateUserStatus(ctx context.Context, req *entities.UpdateUsers) error {
userDetail, err := uc.repo.GetUserByID(ctx, req.UserID, entities.LockingOpt{})
if err != nil {
uc.log.Z().Err(err).Msg("[usecase]UpdateUserStatus.GetUserByID")
return err
}

fmt.Println("user_id", userDetail.UserID)

updateStatusArgs := &entities.Users{
UserID: userDetail.UserID,
IsActive: req.IsActive,
UpdatedAt: time.Now().Format("2006-01-02 15:04:05"),
UpdatedBy: "martin",
}

if err := uc.repo.UpdateUserStatusByID(ctx, updateStatusArgs); err != nil {
uc.log.Z().Err(err).Msg("[usecase]UpdateUserStatus.UpdateUserStatusByID")
}

return nil
}