Files
2025-12-19 21:04:12 +03:00

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