Implement phone number validation for customer and user registration and updates
Added functionality to check for existing customers and users by phone number during registration and updates. Updated the handler, service, and repository layers to include phone number checks, ensuring unique phone numbers across customers and users.
This commit is contained in:
@@ -22,6 +22,7 @@ type Repository interface {
|
||||
UpdatePasswordReset(ctx context.Context, id, hashedPassword, updatedBy string) error
|
||||
GetByEmail(ctx context.Context, email string) (*User, error)
|
||||
GetByUsername(ctx context.Context, username string) (*User, error)
|
||||
GetByPhone(ctx context.Context, phone string) (*User, error)
|
||||
GetByIDs(ctx context.Context, userIDs []string) ([]User, error)
|
||||
Search(ctx context.Context, form *SearchUsersForm, pagination *response.Pagination) (*orm.PaginatedResult[User], error)
|
||||
}
|
||||
@@ -38,6 +39,8 @@ func NewRepository(mongoManager *orm.ConnectionManager, logger logger.Logger) Re
|
||||
// Create indexes using the ORM's index management
|
||||
indexes := []orm.Index{
|
||||
*orm.CreateTextIndex("search_idx", "full_name", "email", "username"),
|
||||
*orm.CreateUniqueIndex("phone_idx", bson.D{{Key: "phone", Value: 1}}).
|
||||
WithPartialFilterExpression(bson.M{"phone": bson.M{"$type": "string", "$ne": ""}}),
|
||||
}
|
||||
|
||||
// Create indexes
|
||||
@@ -250,6 +253,23 @@ func (r *userRepository) GetByEmail(ctx context.Context, email string) (*User, e
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// GetByPhone retrieves a user by phone number
|
||||
func (r *userRepository) GetByPhone(ctx context.Context, phone string) (*User, error) {
|
||||
user, err := r.ormRepo.FindOne(ctx, bson.M{"phone": phone})
|
||||
if err != nil {
|
||||
if errors.Is(err, orm.ErrDocumentNotFound) {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
r.logger.Error("Failed to get user by phone", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"phone": phone,
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// GetByUsername retrieves a user by username
|
||||
func (r *userRepository) GetByUsername(ctx context.Context, username string) (*User, error) {
|
||||
user, err := r.ormRepo.FindOne(ctx, bson.M{"username": username})
|
||||
|
||||
@@ -77,6 +77,13 @@ func (s *userService) Register(ctx context.Context, form *CreateUserForm) (*User
|
||||
return nil, errors.New("username already exists")
|
||||
}
|
||||
|
||||
if form.Phone != nil && *form.Phone != "" {
|
||||
existingUser, _ = s.repository.GetByPhone(ctx, *form.Phone)
|
||||
if existingUser != nil {
|
||||
return nil, errors.New("phone number already exists")
|
||||
}
|
||||
}
|
||||
|
||||
// Hash password
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(form.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
@@ -185,6 +192,12 @@ func (s *userService) Update(ctx context.Context, id string, form *UpdateUserFor
|
||||
}
|
||||
|
||||
if form.Phone != nil {
|
||||
if *form.Phone != "" {
|
||||
existingUser, _ := s.repository.GetByPhone(ctx, *form.Phone)
|
||||
if existingUser != nil && existingUser.ID.Hex() != id {
|
||||
return nil, errors.New("phone number already exists")
|
||||
}
|
||||
}
|
||||
user.Phone = form.Phone
|
||||
}
|
||||
|
||||
@@ -574,6 +587,12 @@ func (s *userService) UpdateProfile(ctx context.Context, userID string, form *Up
|
||||
user.Position = form.Position
|
||||
}
|
||||
if form.Phone != nil {
|
||||
if *form.Phone != "" {
|
||||
existingUser, _ := s.repository.GetByPhone(ctx, *form.Phone)
|
||||
if existingUser != nil && existingUser.ID.Hex() != userID {
|
||||
return errors.New("phone number already exists")
|
||||
}
|
||||
}
|
||||
user.Phone = form.Phone
|
||||
}
|
||||
if form.ProfileImage != nil {
|
||||
|
||||
Reference in New Issue
Block a user