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) }