116 lines
2.7 KiB
Go
116 lines
2.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"datarush/internal/results/domain"
|
|
"datarush/internal/results/repository"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type Service struct {
|
|
repo repository.ResultRepository
|
|
}
|
|
|
|
func NewService(repo repository.ResultRepository) *Service {
|
|
return &Service{repo: repo}
|
|
}
|
|
|
|
func (s *Service) CreateResult(ctx context.Context, result *domain.Result) (*domain.Result, error) {
|
|
now := time.Now()
|
|
if result.ID == uuid.Nil {
|
|
result.ID = uuid.New()
|
|
}
|
|
result.CreatedAt = now
|
|
result.UpdatedAt = now
|
|
|
|
if result.Status == "" {
|
|
result.Status = domain.ResultStatusPending
|
|
}
|
|
|
|
if err := s.repo.Create(ctx, result); err != nil {
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *Service) GetResult(ctx context.Context, id uuid.UUID) (*domain.Result, error) {
|
|
return s.repo.Get(ctx, id)
|
|
}
|
|
|
|
func (s *Service) UpdateResult(ctx context.Context, result *domain.Result) (*domain.Result, error) {
|
|
result.UpdatedAt = time.Now()
|
|
if err := s.repo.Update(ctx, result); err != nil {
|
|
return nil, err
|
|
}
|
|
return s.repo.Get(ctx, result.ID)
|
|
}
|
|
|
|
func (s *Service) DeleteResult(ctx context.Context, id uuid.UUID) error {
|
|
return s.repo.Delete(ctx, id)
|
|
}
|
|
|
|
func (s *Service) ListResults(
|
|
ctx context.Context,
|
|
pageSize int32,
|
|
pageToken int32,
|
|
competitionID *uuid.UUID,
|
|
userID *uuid.UUID,
|
|
status *domain.ResultStatus,
|
|
minScore *float64,
|
|
maxScore *float64,
|
|
) ([]domain.Result, int32, int32, error) {
|
|
opts := repository.ListResultsOptions{
|
|
Page: int(pageToken),
|
|
PageSize: int(pageSize),
|
|
CompetitionID: competitionID,
|
|
UserID: userID,
|
|
Status: status,
|
|
MinScore: minScore,
|
|
MaxScore: maxScore,
|
|
}
|
|
|
|
results, total, err := s.repo.List(ctx, opts)
|
|
if err != nil {
|
|
return nil, 0, 0, err
|
|
}
|
|
|
|
var nextPageToken int32
|
|
if (opts.Page+1)*opts.PageSize < total {
|
|
nextPageToken = int32(opts.Page + 1)
|
|
}
|
|
|
|
return results, int32(total), nextPageToken, nil
|
|
}
|
|
|
|
func (s *Service) GetByCompetitionAndUser(
|
|
ctx context.Context,
|
|
competitionID uuid.UUID,
|
|
userID uuid.UUID,
|
|
) (*domain.Result, error) {
|
|
return s.repo.GetByCompetitionAndUser(ctx, competitionID, userID)
|
|
}
|
|
|
|
func (s *Service) GetLeaderboard(
|
|
ctx context.Context,
|
|
competitionID uuid.UUID,
|
|
limit int32,
|
|
offset int32,
|
|
) ([]domain.Result, int32, error) {
|
|
results, total, err := s.repo.GetLeaderboard(ctx, competitionID, int(limit), int(offset))
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return results, int32(total), nil
|
|
}
|
|
|
|
func (s *Service) UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error) {
|
|
return s.repo.UpdateStatus(ctx, id, status)
|
|
}
|
|
|
|
func (s *Service) RecalculateRanks(ctx context.Context, competitionID uuid.UUID) error {
|
|
return s.repo.RecalculateRanks(ctx, competitionID)
|
|
}
|