Skip to content
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

refactor: cleaning all code and fixed service logic #62

Merged
merged 1 commit into from
Jan 20, 2024
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ If You using my Template. You get some endpoints that I have set up and an archi

https://documenter.getpostman.com/view/29665461/2s9YJaZQCG

![image](https://github.com/Caknoooo/go-gin-clean-template/assets/92671053/5aea055b-2420-4017-9310-e1c628209d0d)
![image](https://github.com/Caknoooo/go-gin-clean-architecture/assets/92671053/ad3e680c-4b4f-4c31-a70c-497e0a586812)

You will get an issue template as below

Expand Down
66 changes: 26 additions & 40 deletions controller/user_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@ import (
"net/http"

"github.com/Caknoooo/go-gin-clean-template/dto"
"github.com/Caknoooo/go-gin-clean-template/entity"
"github.com/Caknoooo/go-gin-clean-template/service"
"github.com/Caknoooo/go-gin-clean-template/utils"
"github.com/gin-gonic/gin"
)

type UserController interface {
Register(ctx *gin.Context)
GetAllUser(ctx *gin.Context)
Me(ctx *gin.Context)
SendVerificationEmail(ctx *gin.Context)
VerifyEmail(ctx *gin.Context)
Login(ctx *gin.Context)
Update(ctx *gin.Context)
Delete(ctx *gin.Context)
}
type (
UserController interface {
Register(ctx *gin.Context)
Login(ctx *gin.Context)
Me(ctx *gin.Context)
GetAllUser(ctx *gin.Context)
SendVerificationEmail(ctx *gin.Context)
VerifyEmail(ctx *gin.Context)
Update(ctx *gin.Context)
Delete(ctx *gin.Context)
}

type userController struct {
jwtService service.JWTService
userService service.UserService
}
userController struct {
userService service.UserService
}
)

func NewUserController(us service.UserService, jwt service.JWTService) UserController {
func NewUserController(us service.UserService) UserController {
return &userController{
jwtService: jwt,
userService: us,
}
}
Expand Down Expand Up @@ -67,13 +66,13 @@ func (c *userController) GetAllUser(ctx *gin.Context) {
return
}

resp := utils.Response {
Status: true,
resp := utils.Response{
Status: true,
Message: dto.MESSAGE_SUCCESS_GET_LIST_USER,
Data: result.Data,
Meta: result.PaginationResponse,
Data: result.Data,
Meta: result.PaginationResponse,
}

ctx.JSON(http.StatusOK, resp)
}

Expand All @@ -99,28 +98,15 @@ func (c *userController) Login(ctx *gin.Context) {
return
}

res, err := c.userService.Verify(ctx.Request.Context(), req.Email, req.Password)
if err != nil && !res {
response := utils.BuildResponseFailed(dto.MESSAGE_FAILED_LOGIN, err.Error(), nil)
ctx.AbortWithStatusJSON(http.StatusUnauthorized, response)
return
}

user, err := c.userService.GetUserByEmail(ctx.Request.Context(), req.Email)
result, err := c.userService.Verify(ctx.Request.Context(), req)
if err != nil {
response := utils.BuildResponseFailed(dto.MESSAGE_FAILED_LOGIN, err.Error(), nil)
ctx.AbortWithStatusJSON(http.StatusBadRequest, response)
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_LOGIN, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)
return
}

token := c.jwtService.GenerateToken(user.ID, user.Role)
userResponse := entity.Authorization{
Token: token,
Role: user.Role,
}

response := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_LOGIN, userResponse)
ctx.JSON(http.StatusOK, response)
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_LOGIN, result)
ctx.JSON(http.StatusOK, res)
}

func (c *userController) SendVerificationEmail(ctx *gin.Context) {
Expand Down
18 changes: 11 additions & 7 deletions dto/user_dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,21 @@ type (
GetAllUserRepositoryResponse struct {
Users []entity.User
PaginationResponse
}
}

UserUpdateRequest struct {
Name string `json:"name" form:"name"`
TelpNumber string `json:"telp_number" form:"telp_number"`
Email string `json:"email" form:"email"`
Password string `json:"password" form:"password"`
}

UserUpdateResponse struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
TelpNumber string `json:"telp_number,omitempty"`
Role string `json:"role,omitempty"`
Email string `json:"email,omitempty"`
IsVerified bool `json:"is_verified,omitempty"`
Name string `json:"name"`
TelpNumber string `json:"telp_number"`
Role string `json:"role"`
Email string `json:"email"`
IsVerified bool `json:"is_verified"`
}

SendVerificationEmailRequest struct {
Expand All @@ -117,6 +116,11 @@ type (
Password string `json:"password" form:"password" binding:"required"`
}

UserLoginResponse struct {
Token string `json:"token"`
Role string `json:"role"`
}

UpdateStatusIsVerifiedRequest struct {
UserId string `json:"user_id" form:"user_id" binding:"required"`
IsVerified bool `json:"is_verified" form:"is_verified"`
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func main() {
db *gorm.DB = config.SetUpDatabaseConnection()
jwtService service.JWTService = service.NewJWTService()
userRepository repository.UserRepository = repository.NewUserRepository(db)
userService service.UserService = service.NewUserService(userRepository)
userController controller.UserController = controller.NewUserController(userService, jwtService)
userService service.UserService = service.NewUserService(userRepository, jwtService)
userController controller.UserController = controller.NewUserController(userService)
)

server := gin.Default()
Expand Down
112 changes: 72 additions & 40 deletions repository/user_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,37 @@ import (
"gorm.io/gorm"
)

type UserRepository interface {
RegisterUser(ctx context.Context, user entity.User) (entity.User, error)
GetAllUserWithPagination(ctx context.Context, tx *gorm.DB, req dto.PaginationRequest) (dto.GetAllUserRepositoryResponse, error)
GetUserById(ctx context.Context, userId string) (entity.User, error)
GetUserByEmail(ctx context.Context, email string) (entity.User, error)
CheckEmail(ctx context.Context, email string) (bool, error)
UpdateUser(ctx context.Context, user entity.User) (entity.User, error)
DeleteUser(ctx context.Context, userId string) error
}
type (
UserRepository interface {
RegisterUser(ctx context.Context, tx *gorm.DB, user entity.User) (entity.User, error)
GetAllUserWithPagination(ctx context.Context, tx *gorm.DB, req dto.PaginationRequest) (dto.GetAllUserRepositoryResponse, error)
GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entity.User, error)
GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entity.User, error)
CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entity.User, bool, error)
UpdateUser(ctx context.Context, tx *gorm.DB, user entity.User) (entity.User, error)
DeleteUser(ctx context.Context, tx *gorm.DB, userId string) error
}

type userRepository struct {
db *gorm.DB
}
userRepository struct {
db *gorm.DB
}
)

func NewUserRepository(db *gorm.DB) UserRepository {
return &userRepository{
db: db,
}
}

func (r *userRepository) RegisterUser(ctx context.Context, user entity.User) (entity.User, error) {
if err := r.db.Create(&user).Error; err != nil {
func (r *userRepository) RegisterUser(ctx context.Context, tx *gorm.DB, user entity.User) (entity.User, error) {
if tx == nil {
tx = r.db
}

if err := tx.WithContext(ctx).Create(&user).Error; err != nil {
return entity.User{}, err
}

return user, nil
}

Expand All @@ -53,23 +60,23 @@ func (r *userRepository) GetAllUserWithPagination(ctx context.Context, tx *gorm.
req.Page = 1
}

query := tx.WithContext(ctx).Model(&entity.User{})
if req.Search != "" {
err = tx.WithContext(ctx).Model(&entity.User{}).Where("name ILIKE ?", "%"+req.Search+"%").Count(&count).Error
if err != nil {
return dto.GetAllUserRepositoryResponse{}, err
}
} else {
err = tx.WithContext(ctx).Model(&entity.User{}).Count(&count).Error
if err != nil {
return dto.GetAllUserRepositoryResponse{}, err
}
}

stmt := tx.WithContext(ctx).Where("name ILIKE ?", "%"+req.Search+"%")
maxPage := int64(math.Ceil(float64(count) / float64(req.PerPage)))
query = query.Where("name LIKE ?", "%"+req.Search+"%")
}

err = query.Count(&count).Error
if err != nil {
return dto.GetAllUserRepositoryResponse{}, err
}

offset := (req.Page - 1) * req.PerPage
_ = stmt.Offset(offset).Limit(req.PerPage).Find(&users).Error
maxPage := int64(math.Ceil(float64(count) / float64(req.PerPage)))

err = query.Offset(offset).Limit(req.PerPage).Find(&users).Error
if err != nil {
return dto.GetAllUserRepositoryResponse{}, err
}

return dto.GetAllUserRepositoryResponse{
Users: users,
Expand All @@ -82,40 +89,65 @@ func (r *userRepository) GetAllUserWithPagination(ctx context.Context, tx *gorm.
}, nil
}

func (r *userRepository) GetUserById(ctx context.Context, userId string) (entity.User, error) {
func (r *userRepository) GetUserById(ctx context.Context, tx *gorm.DB, userId string) (entity.User, error) {
if tx == nil {
tx = r.db
}

var user entity.User
if err := r.db.Where("id = ?", userId).Take(&user).Error; err != nil {
if err := tx.WithContext(ctx).Where("id = ?", userId).Take(&user).Error; err != nil {
return entity.User{}, err
}

return user, nil
}

func (r *userRepository) GetUserByEmail(ctx context.Context, email string) (entity.User, error) {
func (r *userRepository) GetUserByEmail(ctx context.Context, tx *gorm.DB, email string) (entity.User, error) {
if tx == nil {
tx = r.db
}

var user entity.User
if err := r.db.Where("email = ?", email).Take(&user).Error; err != nil {
if err := tx.WithContext(ctx).Where("email = ?", email).Take(&user).Error; err != nil {
return entity.User{}, err
}

return user, nil
}

func (r *userRepository) CheckEmail(ctx context.Context, email string) (bool, error) {
func (r *userRepository) CheckEmail(ctx context.Context, tx *gorm.DB, email string) (entity.User, bool, error) {
if tx == nil {
tx = r.db
}

var user entity.User
if err := r.db.Where("email = ?", email).Take(&user).Error; err != nil {
return false, err
if err := tx.WithContext(ctx).Where("email = ?", email).Take(&user).Error; err != nil {
return entity.User{}, false, err
}
return true, nil

return user, true, nil
}

func (r *userRepository) UpdateUser(ctx context.Context, user entity.User) (entity.User, error) {
if err := r.db.Updates(&user).Error; err != nil {
func (r *userRepository) UpdateUser(ctx context.Context, tx *gorm.DB, user entity.User) (entity.User, error) {
if tx == nil {
tx = r.db
}

if err := tx.WithContext(ctx).Updates(&user).Error; err != nil {
return entity.User{}, err
}

return user, nil
}

func (r *userRepository) DeleteUser(ctx context.Context, userId string) error {
if err := r.db.Delete(&entity.User{}, &userId).Error; err != nil {
func (r *userRepository) DeleteUser(ctx context.Context, tx *gorm.DB, userId string) error {
if tx == nil {
tx = r.db
}

if err := tx.WithContext(ctx).Delete(&entity.User{}, "id = ?", userId).Error; err != nil {
return err
}

return nil
}
4 changes: 2 additions & 2 deletions routes/user_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func User(route *gin.Engine, userController controller.UserController, jwtServic
routes.DELETE("", middleware.Authenticate(jwtService), userController.Delete)
routes.PATCH("", middleware.Authenticate(jwtService), userController.Update)
routes.GET("/me", middleware.Authenticate(jwtService), userController.Me)
routes.POST("/verify-email", userController.VerifyEmail)
routes.POST("/verification-email", userController.SendVerificationEmail)
routes.POST("/verify_email", userController.VerifyEmail)
routes.POST("/send_verification_email", userController.SendVerificationEmail)
}
}
Loading
Loading