package service import ( "errors" "time" "dating-app/internal/dto" "dating-app/internal/models" "dating-app/internal/repository" ) var ErrUserNotOnboarded = errors.New("کاربر هنوز آنبوردینگ را تکمیل نکرده است") type AdminService struct { optionRepo *repository.OptionRepository questionRepo *repository.QuestionRepository userRepo *repository.UserRepository } func NewAdminService( optionRepo *repository.OptionRepository, questionRepo *repository.QuestionRepository, userRepo *repository.UserRepository, ) *AdminService { return &AdminService{optionRepo: optionRepo, questionRepo: questionRepo, userRepo: userRepo} } // ---------------- بررسی و تایید کاربران ---------------- // GetUser یک کاربر رو برای نمایش به ادمین (بررسی درخواست) برمی‌گردونه func (s *AdminService) GetUser(id uint) (*models.User, error) { return s.userRepo.FindByID(id) } // ListPendingUsers کاربرانی که آنبوردینگ رو تکمیل کردن و منتظر بررسی‌اند func (s *AdminService) ListPendingUsers() ([]models.User, error) { return s.userRepo.ListPendingApproval() } // ApproveUser کاربر رو تایید می‌کنه تا بتونه وارد صفحه‌ی دوستیابی بشه func (s *AdminService) ApproveUser(id uint) (*models.User, error) { user, err := s.userRepo.FindByID(id) if err != nil { return nil, err } if !user.IsOnboarded { return nil, ErrUserNotOnboarded } now := time.Now() updates := map[string]interface{}{ "approval_status": models.ApprovalApproved, "rejection_reason": nil, "reviewed_at": now, } if err := s.userRepo.UpdateFields(user, updates); err != nil { return nil, err } user.ApprovalStatus = models.ApprovalApproved user.RejectionReason = nil user.ReviewedAt = &now return user, nil } // RejectUser درخواست عضویت کاربر رو با یک دلیل مشخص رد می‌کنه func (s *AdminService) RejectUser(id uint, reason string) (*models.User, error) { user, err := s.userRepo.FindByID(id) if err != nil { return nil, err } if !user.IsOnboarded { return nil, ErrUserNotOnboarded } now := time.Now() updates := map[string]interface{}{ "approval_status": models.ApprovalRejected, "rejection_reason": reason, "reviewed_at": now, } if err := s.userRepo.UpdateFields(user, updates); err != nil { return nil, err } user.ApprovalStatus = models.ApprovalRejected user.RejectionReason = &reason user.ReviewedAt = &now return user, nil } // ---------------- دسته‌ها و گزینه‌ها ---------------- func (s *AdminService) GetCategory(key models.CategoryKey) (*models.Category, error) { return s.optionRepo.GetCategoryByKey(key) } func (s *AdminService) UpdateCategory(key models.CategoryKey, req dto.UpdateCategoryRequest) (*models.Category, error) { cat, err := s.optionRepo.GetCategoryByKey(key) if err != nil { return nil, err } if req.Title != nil { cat.Title = *req.Title } if req.MinSelect != nil { cat.MinSelect = *req.MinSelect } if req.MaxSelect != nil { cat.MaxSelect = *req.MaxSelect } if err := s.optionRepo.UpdateCategory(cat); err != nil { return nil, err } return cat, nil } func (s *AdminService) ListOptions(key models.CategoryKey) ([]models.Option, error) { return s.optionRepo.ListOptionsByCategoryKeyAdmin(key) } func (s *AdminService) CreateOption(key models.CategoryKey, req dto.CreateOptionRequest) (*models.Option, error) { cat, err := s.optionRepo.GetCategoryByKey(key) if err != nil { return nil, err } opt := &models.Option{ CategoryID: cat.ID, Title: req.Title, SortOrder: req.SortOrder, IsActive: true, } if err := s.optionRepo.CreateOption(opt); err != nil { return nil, err } return opt, nil } func (s *AdminService) UpdateOption(id uint, req dto.UpdateOptionRequest) (*models.Option, error) { opt, err := s.optionRepo.FindOptionByID(id) if err != nil { return nil, err } if req.Title != nil { opt.Title = *req.Title } if req.SortOrder != nil { opt.SortOrder = *req.SortOrder } if req.IsActive != nil { opt.IsActive = *req.IsActive } if err := s.optionRepo.UpdateOption(opt); err != nil { return nil, err } return opt, nil } func (s *AdminService) DeleteOption(id uint) error { return s.optionRepo.DeleteOption(id) } // ---------------- سوالات پروفایل ---------------- func (s *AdminService) ListQuestions() ([]models.ProfileQuestion, error) { return s.questionRepo.ListAllAdmin() } func (s *AdminService) CreateQuestion(req dto.CreateProfileQuestionRequest) (*models.ProfileQuestion, error) { q := &models.ProfileQuestion{ Text: req.Text, SortOrder: req.SortOrder, IsActive: true, } if err := s.questionRepo.Create(q); err != nil { return nil, err } return q, nil } func (s *AdminService) UpdateQuestion(id uint, req dto.UpdateProfileQuestionRequest) (*models.ProfileQuestion, error) { q, err := s.questionRepo.FindByID(id) if err != nil { return nil, err } if req.Text != nil { q.Text = *req.Text } if req.SortOrder != nil { q.SortOrder = *req.SortOrder } if req.IsActive != nil { q.IsActive = *req.IsActive } if err := s.questionRepo.Update(q); err != nil { return nil, err } return q, nil } func (s *AdminService) DeleteQuestion(id uint) error { return s.questionRepo.Delete(id) }