package service import ( "context" "errors" "tailly_back_v2/internal/domain" "tailly_back_v2/internal/repository" "tailly_back_v2/pkg/auth" "time" ) type UserService interface { GetByID(ctx context.Context, id int) (*domain.User, error) GetAll(ctx context.Context, id int) ([]*domain.User, error) GetByEmail(ctx context.Context, email string) (*domain.User, error) UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error) ChangePassword(ctx context.Context, id int, oldPassword, newPassword string) error } type userService struct { userRepo repository.UserRepository tokenAuth *auth.TokenAuth } func (s *userService) GetByEmail(ctx context.Context, email string) (*domain.User, error) { user, err := s.userRepo.GetByEmail(ctx, email) if err != nil { if errors.Is(err, repository.ErrUserNotFound) { return nil, errors.New("user not found") } return nil, err } return user, nil } func NewUserService(userRepo repository.UserRepository) *userService { return &userService{ userRepo: userRepo, } } func (s *userService) GetByID(ctx context.Context, id int) (*domain.User, error) { user, err := s.userRepo.GetByID(ctx, id) if err != nil { if errors.Is(err, repository.ErrUserNotFound) { return nil, errors.New("user not found") } return nil, err } // Очищаем пароль перед возвратом user.Password = "" return user, nil } func (s *userService) UpdateProfile(ctx context.Context, id int, username, email, avatar string) (*domain.User, error) { user, err := s.userRepo.GetByID(ctx, id) if err != nil { return nil, err } // Проверяем email на уникальность if email != user.Email { if _, err := s.userRepo.GetByEmail(ctx, email); err == nil { return nil, errors.New("email already in use") } } user.Username = username user.Email = email user.Avatar = avatar user.UpdatedAt = time.Now() if err := s.userRepo.Update(ctx, user); err != nil { return nil, err } // Очищаем пароль перед возвратом user.Password = "" return user, nil } func (s *userService) ChangePassword(ctx context.Context, id int, oldPassword, newPassword string) error { user, err := s.userRepo.GetByID(ctx, id) if err != nil { return err } if !auth.CheckPasswordHash(oldPassword, user.Password) { return errors.New("invalid current password") } hashedPassword, err := auth.HashPassword(newPassword) if err != nil { return err } user.Password = hashedPassword return s.userRepo.Update(ctx, user) } func (s *userService) GetAll(ctx context.Context, id int) ([]*domain.User, error) { users, err := s.userRepo.GetAll(ctx, id) if err != nil { return nil, err } // Возвращаем пустой слайс вместо nil if users == nil { return []*domain.User{}, nil } return users, nil }