171 lines
5.1 KiB
Go
171 lines
5.1 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"eslogad-be/internal/contract"
|
|
"eslogad-be/internal/entities"
|
|
"eslogad-be/internal/transformer"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type UserServiceImpl struct {
|
|
userProcessor UserProcessor
|
|
titleRepo TitleRepository
|
|
}
|
|
|
|
type TitleRepository interface {
|
|
ListAll(ctx context.Context) ([]entities.Title, error)
|
|
}
|
|
|
|
func NewUserService(userProcessor UserProcessor, titleRepo TitleRepository) *UserServiceImpl {
|
|
return &UserServiceImpl{
|
|
userProcessor: userProcessor,
|
|
titleRepo: titleRepo,
|
|
}
|
|
}
|
|
|
|
func (s *UserServiceImpl) CreateUser(ctx context.Context, req *contract.CreateUserRequest) (*contract.UserResponse, error) {
|
|
return s.userProcessor.CreateUser(ctx, req)
|
|
}
|
|
|
|
func (s *UserServiceImpl) BulkCreateUsers(ctx context.Context, req *contract.BulkCreateUsersRequest) (*contract.BulkCreateUsersResponse, error) {
|
|
response := &contract.BulkCreateUsersResponse{
|
|
Created: []contract.UserResponse{},
|
|
Failed: []contract.BulkUserErrorResult{},
|
|
Summary: contract.BulkCreationSummary{
|
|
Total: len(req.Users),
|
|
Succeeded: 0,
|
|
Failed: 0,
|
|
},
|
|
}
|
|
|
|
// Process in batches to avoid memory and database issues
|
|
batchSize := 50
|
|
for i := 0; i < len(req.Users); i += batchSize {
|
|
end := i + batchSize
|
|
if end > len(req.Users) {
|
|
end = len(req.Users)
|
|
}
|
|
|
|
batch := req.Users[i:end]
|
|
batchResults, err := s.processBulkUserBatch(ctx, batch)
|
|
if err != nil {
|
|
// Log batch error but continue with other batches
|
|
for _, userReq := range batch {
|
|
response.Failed = append(response.Failed, contract.BulkUserErrorResult{
|
|
User: userReq,
|
|
Error: "Batch processing error: " + err.Error(),
|
|
})
|
|
response.Summary.Failed++
|
|
}
|
|
continue
|
|
}
|
|
|
|
response.Created = append(response.Created, batchResults.Created...)
|
|
response.Failed = append(response.Failed, batchResults.Failed...)
|
|
response.Summary.Succeeded += batchResults.Summary.Succeeded
|
|
response.Summary.Failed += batchResults.Summary.Failed
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (s *UserServiceImpl) processBulkUserBatch(ctx context.Context, batch []contract.BulkUserRequest) (*contract.BulkCreateUsersResponse, error) {
|
|
response := &contract.BulkCreateUsersResponse{
|
|
Created: []contract.UserResponse{},
|
|
Failed: []contract.BulkUserErrorResult{},
|
|
Summary: contract.BulkCreationSummary{
|
|
Total: len(batch),
|
|
Succeeded: 0,
|
|
Failed: 0,
|
|
},
|
|
}
|
|
|
|
// Use transaction for batch processing
|
|
created, failed, err := s.userProcessor.BulkCreateUsersWithTransaction(ctx, batch)
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
|
|
response.Created = created
|
|
response.Failed = failed
|
|
response.Summary.Succeeded = len(created)
|
|
response.Summary.Failed = len(failed)
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (s *UserServiceImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *contract.UpdateUserRequest) (*contract.UserResponse, error) {
|
|
return s.userProcessor.UpdateUser(ctx, id, req)
|
|
}
|
|
|
|
func (s *UserServiceImpl) DeleteUser(ctx context.Context, id uuid.UUID) error {
|
|
return s.userProcessor.DeleteUser(ctx, id)
|
|
}
|
|
|
|
func (s *UserServiceImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*contract.UserResponse, error) {
|
|
return s.userProcessor.GetUserByID(ctx, id)
|
|
}
|
|
|
|
func (s *UserServiceImpl) GetUserByEmail(ctx context.Context, email string) (*contract.UserResponse, error) {
|
|
return s.userProcessor.GetUserByEmail(ctx, email)
|
|
}
|
|
|
|
func (s *UserServiceImpl) ListUsers(ctx context.Context, req *contract.ListUsersRequest) (*contract.ListUsersResponse, error) {
|
|
page := req.Page
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
limit := req.Limit
|
|
if limit <= 0 {
|
|
limit = 10
|
|
}
|
|
|
|
userResponses, totalCount, err := s.userProcessor.ListUsersWithFilters(ctx, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &contract.ListUsersResponse{
|
|
Users: userResponses,
|
|
Pagination: transformer.CreatePaginationResponse(totalCount, page, limit),
|
|
}, nil
|
|
}
|
|
|
|
func (s *UserServiceImpl) ChangePassword(ctx context.Context, userID uuid.UUID, req *contract.ChangePasswordRequest) error {
|
|
return s.userProcessor.ChangePassword(ctx, userID, req)
|
|
}
|
|
|
|
func (s *UserServiceImpl) GetProfile(ctx context.Context, userID uuid.UUID) (*contract.UserProfileResponse, error) {
|
|
prof, err := s.userProcessor.GetUserProfile(ctx, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if roles, err := s.userProcessor.GetUserRoles(ctx, userID); err == nil {
|
|
prof.Roles = roles
|
|
}
|
|
return prof, nil
|
|
}
|
|
|
|
func (s *UserServiceImpl) UpdateProfile(ctx context.Context, userID uuid.UUID, req *contract.UpdateUserProfileRequest) (*contract.UserProfileResponse, error) {
|
|
return s.userProcessor.UpdateUserProfile(ctx, userID, req)
|
|
}
|
|
|
|
func (s *UserServiceImpl) ListTitles(ctx context.Context) (*contract.ListTitlesResponse, error) {
|
|
if s.titleRepo == nil {
|
|
return &contract.ListTitlesResponse{Titles: []contract.TitleResponse{}}, nil
|
|
}
|
|
titles, err := s.titleRepo.ListAll(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &contract.ListTitlesResponse{Titles: transformer.TitlesToContract(titles)}, nil
|
|
}
|
|
|
|
// GetActiveUsersForMention retrieves active users for mention purposes
|
|
func (s *UserServiceImpl) GetActiveUsersForMention(ctx context.Context, search *string, limit int) ([]contract.UserResponse, error) {
|
|
return s.userProcessor.GetActiveUsersForMention(ctx, search, limit)
|
|
}
|