From d8942fa9188e11dfde04ad1661cd869717deea54 Mon Sep 17 00:00:00 2001 From: efrilm Date: Fri, 3 Oct 2025 13:40:49 +0700 Subject: [PATCH] fix user update role and department --- internal/contract/user_contract.go | 2 +- internal/processor/user_processor.go | 6 ++++ internal/processor/user_role_processor.go | 34 +++++++++++++++++++++++ internal/transformer/user_transformer.go | 2 ++ internal/validator/user_validator.go | 16 +++++------ 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/internal/contract/user_contract.go b/internal/contract/user_contract.go index 813a180..6141307 100644 --- a/internal/contract/user_contract.go +++ b/internal/contract/user_contract.go @@ -17,7 +17,7 @@ type CreateUserRequest struct { type UpdateUserRequest struct { Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"` Email *string `json:"email,omitempty" validate:"omitempty,email"` - Role *string `json:"role,omitempty" validate:"omitempty,oneof=admin manager cashier waiter"` + Role *uuid.UUID `json:"role,omitempty"` IsActive *bool `json:"is_active,omitempty"` Permissions *map[string]interface{} `json:"permissions,omitempty"` DepartmentIDs *[]uuid.UUID `json:"department_ids,omitempty"` diff --git a/internal/processor/user_processor.go b/internal/processor/user_processor.go index d4d1bbc..21772d4 100644 --- a/internal/processor/user_processor.go +++ b/internal/processor/user_processor.go @@ -136,6 +136,12 @@ func (p *UserProcessorImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *c } } + if req.Role != nil { + if err := p.userRoleProc.ReplaceUserRole(ctx, updated.ID, *req.Role); err != nil { + return nil, fmt.Errorf("failed to assign role to user: %w", err) + } + } + // Update departments if provided if req.DepartmentIDs != nil { departments := make([]entities.Department, len(*req.DepartmentIDs)) diff --git a/internal/processor/user_role_processor.go b/internal/processor/user_role_processor.go index 49fa8e7..2dc4a31 100644 --- a/internal/processor/user_role_processor.go +++ b/internal/processor/user_role_processor.go @@ -15,6 +15,7 @@ type UserRoleProcessor interface { RemoveRoleFromUser(ctx context.Context, userID, roleID uuid.UUID) error GetUserRoles(ctx context.Context, userID uuid.UUID) ([]entities.Role, error) HasRole(ctx context.Context, userID uuid.UUID, roleCode string) (bool, error) + ReplaceUserRole(ctx context.Context, userID, roleID uuid.UUID) error } type UserRoleProcessorImpl struct { @@ -94,4 +95,37 @@ func (p *UserRoleProcessorImpl) HasRole(ctx context.Context, userID uuid.UUID, r } return count > 0, nil +} + +func (p *UserRoleProcessorImpl) ReplaceUserRole(ctx context.Context, userID uuid.UUID, roleID uuid.UUID) error { + return p.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + // Delete old role + if err := tx.Where("user_id = ?", userID). + Delete(&UserRoleEntry{}).Error; err != nil { + return err + } + + // Check if new role already exists + var existingEntry UserRoleEntry + err := tx.Where("user_id = ?", userID). + First(&existingEntry).Error + + if err == nil { + // Role already assigned + return nil + } + + if err != gorm.ErrRecordNotFound { + return err + } + + // Assign new role + newEntry := UserRoleEntry{ + UserID: userID, + RoleID: roleID, + AssignedAt: time.Now(), + } + + return tx.Create(&newEntry).Error + }) } \ No newline at end of file diff --git a/internal/transformer/user_transformer.go b/internal/transformer/user_transformer.go index ec50e64..22f25b1 100644 --- a/internal/transformer/user_transformer.go +++ b/internal/transformer/user_transformer.go @@ -25,9 +25,11 @@ func UpdateUserEntity(existing *entities.User, req *contract.UpdateUserRequest) if req.Name != nil { existing.Name = *req.Name } + if req.Email != nil { existing.Email = *req.Email } + if req.IsActive != nil { existing.IsActive = *req.IsActive } diff --git a/internal/validator/user_validator.go b/internal/validator/user_validator.go index d34d5a7..21f4b2b 100644 --- a/internal/validator/user_validator.go +++ b/internal/validator/user_validator.go @@ -62,14 +62,14 @@ func (v *UserValidatorImpl) ValidateUpdateUserRequest(req *contract.UpdateUserRe } } - if req.Role != nil { - if strings.TrimSpace(*req.Role) == "" { - return errors.New("role cannot be empty"), constants.MalformedFieldErrorCode - } - if !isValidUserRole(*req.Role) { - return errors.New("invalid user role"), constants.MalformedFieldErrorCode - } - } + // if req.Role != nil { + // if strings.TrimSpace(*req.Role) == "" { + // return errors.New("role cannot be empty"), constants.MalformedFieldErrorCode + // } + // // if !isValidUserRole(*req.Role) { + // // return errors.New("invalid user role"), constants.MalformedFieldErrorCode + // // } + // } return nil, "" }