style: reformatted all files

This commit is contained in:
ITQ
2025-12-19 21:04:12 +03:00
parent d7320f2198
commit 5c89ca5f09
21 changed files with 288 additions and 107 deletions
+1 -1
View File
@@ -8,4 +8,4 @@ var (
ErrDuplicateResult = errors.New("duplicate result")
ErrCompetitionNotFound = errors.New("competition not found")
ErrUserNotFound = errors.New("user not found")
)
)
+13 -2
View File
@@ -29,7 +29,18 @@ type Result struct {
UpdatedAt time.Time
}
func NewResult(id uuid.UUID, competitionID uuid.UUID, userID uuid.UUID, score float64, rank *int, status ResultStatus, submissionID *uuid.UUID, metadata map[string]interface{}, createdAt time.Time, updatedAt time.Time) *Result {
func NewResult(
id uuid.UUID,
competitionID uuid.UUID,
userID uuid.UUID,
score float64,
rank *int,
status ResultStatus,
submissionID *uuid.UUID,
metadata map[string]interface{},
createdAt time.Time,
updatedAt time.Time,
) *Result {
return &Result{
ID: id,
CompetitionID: competitionID,
@@ -42,4 +53,4 @@ func NewResult(id uuid.UUID, competitionID uuid.UUID, userID uuid.UUID, score fl
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}
}
}
+37 -7
View File
@@ -24,9 +24,23 @@ type IResultService interface {
GetResult(ctx context.Context, id uuid.UUID) (*domain.Result, error)
UpdateResult(ctx context.Context, result *domain.Result) (*domain.Result, error)
DeleteResult(ctx context.Context, id uuid.UUID) error
ListResults(ctx context.Context, pageSize int32, pageToken int32, competitionID *uuid.UUID, userID *uuid.UUID, status *domain.ResultStatus, minScore *float64, maxScore *float64) (results []domain.Result, totalCount int32, nextPageToken int32, err error)
ListResults(
ctx context.Context,
pageSize int32,
pageToken int32,
competitionID *uuid.UUID,
userID *uuid.UUID,
status *domain.ResultStatus,
minScore *float64,
maxScore *float64,
) (results []domain.Result, totalCount int32, nextPageToken int32, err error)
GetByCompetitionAndUser(ctx context.Context, competitionID uuid.UUID, userID uuid.UUID) (*domain.Result, error)
GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int32, offset int32) ([]domain.Result, int32, error)
GetLeaderboard(
ctx context.Context,
competitionID uuid.UUID,
limit int32,
offset int32,
) ([]domain.Result, int32, error)
UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error)
RecalculateRanks(ctx context.Context, competitionID uuid.UUID) error
}
@@ -43,7 +57,10 @@ type ResultsHandler struct {
mu sync.RWMutex
}
func NewResultsHandler(s IResultService, userServiceAddr, submissionServiceAddr, taskServiceAddr string) *ResultsHandler {
func NewResultsHandler(
s IResultService,
userServiceAddr, submissionServiceAddr, taskServiceAddr string,
) *ResultsHandler {
return &ResultsHandler{
service: s,
userServiceAddr: userServiceAddr,
@@ -210,7 +227,11 @@ func (h *ResultsHandler) fetchTaskStatuses(ctx context.Context, competitionID, u
return taskStatuses
}
func (h *ResultsHandler) enrichUserResult(ctx context.Context, result *domain.Result, competitionID string) *pb.UserResult {
func (h *ResultsHandler) enrichUserResult(
ctx context.Context,
result *domain.Result,
competitionID string,
) *pb.UserResult {
userID := result.UserID.String()
username := h.fetchUsername(ctx, userID)
taskStatuses := h.fetchTaskStatuses(ctx, competitionID, userID)
@@ -230,7 +251,10 @@ func (h *ResultsHandler) enrichUserResult(ctx context.Context, result *domain.Re
return pbResult
}
func (h *ResultsHandler) GetCompetitionResults(ctx context.Context, req *pb.GetCompetitionResultsRequest) (*pb.GetCompetitionResultsResponse, error) {
func (h *ResultsHandler) GetCompetitionResults(
ctx context.Context,
req *pb.GetCompetitionResultsRequest,
) (*pb.GetCompetitionResultsResponse, error) {
competitionID, err := uuid.Parse(req.GetCompetitionId())
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid competition id format: %v", err)
@@ -267,7 +291,10 @@ func (h *ResultsHandler) GetCompetitionResults(ctx context.Context, req *pb.GetC
}, nil
}
func (h *ResultsHandler) GetUserCompetitionResults(ctx context.Context, req *pb.GetUserCompetitionResultsRequest) (*pb.GetUserCompetitionResultsResponse, error) {
func (h *ResultsHandler) GetUserCompetitionResults(
ctx context.Context,
req *pb.GetUserCompetitionResultsRequest,
) (*pb.GetUserCompetitionResultsResponse, error) {
competitionID, err := uuid.Parse(req.GetCompetitionId())
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid competition id format: %v", err)
@@ -294,7 +321,10 @@ func (h *ResultsHandler) GetUserCompetitionResults(ctx context.Context, req *pb.
}, nil
}
func (h *ResultsHandler) RecalculateResults(ctx context.Context, req *pb.RecalculateResultsRequest) (*emptypb.Empty, error) {
func (h *ResultsHandler) RecalculateResults(
ctx context.Context,
req *pb.RecalculateResultsRequest,
) (*emptypb.Empty, error) {
competitionID, err := uuid.Parse(req.GetCompetitionId())
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid competition id format: %v", err)
+26 -4
View File
@@ -53,28 +53,50 @@ func (m *MockResultService) DeleteResult(ctx context.Context, id uuid.UUID) erro
return errors.New("not implemented")
}
func (m *MockResultService) ListResults(ctx context.Context, pageSize int32, pageToken int32, competitionID *uuid.UUID, userID *uuid.UUID, status *domain.ResultStatus, minScore *float64, maxScore *float64) (results []domain.Result, totalCount int32, nextPageToken int32, err error) {
func (m *MockResultService) ListResults(
ctx context.Context,
pageSize int32,
pageToken int32,
competitionID *uuid.UUID,
userID *uuid.UUID,
status *domain.ResultStatus,
minScore *float64,
maxScore *float64,
) (results []domain.Result, totalCount int32, nextPageToken int32, err error) {
if m.ListResultsFunc != nil {
return m.ListResultsFunc(ctx, pageSize, pageToken, competitionID, userID, status, minScore, maxScore)
}
return nil, 0, 0, errors.New("not implemented")
}
func (m *MockResultService) GetByCompetitionAndUser(ctx context.Context, competitionID uuid.UUID, userID uuid.UUID) (*domain.Result, error) {
func (m *MockResultService) GetByCompetitionAndUser(
ctx context.Context,
competitionID uuid.UUID,
userID uuid.UUID,
) (*domain.Result, error) {
if m.GetByCompetitionAndUserFunc != nil {
return m.GetByCompetitionAndUserFunc(ctx, competitionID, userID)
}
return nil, errors.New("not implemented")
}
func (m *MockResultService) GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int32, offset int32) ([]domain.Result, int32, error) {
func (m *MockResultService) GetLeaderboard(
ctx context.Context,
competitionID uuid.UUID,
limit int32,
offset int32,
) ([]domain.Result, int32, error) {
if m.GetLeaderboardFunc != nil {
return m.GetLeaderboardFunc(ctx, competitionID, limit, offset)
}
return nil, 0, errors.New("not implemented")
}
func (m *MockResultService) UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error) {
func (m *MockResultService) UpdateStatus(
ctx context.Context,
id uuid.UUID,
status domain.ResultStatus,
) (*domain.Result, error) {
if m.UpdateStatusFunc != nil {
return m.UpdateStatusFunc(ctx, id, status)
}
+26 -7
View File
@@ -3,13 +3,14 @@ package postgres
import (
"context"
"database/sql"
"datarush/internal/results/domain"
"datarush/internal/results/repository"
"encoding/json"
"fmt"
"strings"
"time"
"datarush/internal/results/domain"
"datarush/internal/results/repository"
"github.com/google/uuid"
"github.com/lib/pq"
"github.com/redis/go-redis/v9"
@@ -257,8 +258,13 @@ func (r *ResultRepository) List(ctx context.Context, opts repository.ListResults
return nil, 0, err
}
query := fmt.Sprintf(`SELECT id, competition_id, user_id, score, rank, status, submission_id, metadata, created_at, updated_at
FROM results %s ORDER BY score DESC, created_at ASC LIMIT $%d OFFSET $%d`, where, argId, argId+1)
query := fmt.Sprintf(
`SELECT id, competition_id, user_id, score, rank, status, submission_id, metadata, created_at, updated_at
FROM results %s ORDER BY score DESC, created_at ASC LIMIT $%d OFFSET $%d`,
where,
argId,
argId+1,
)
args = append(args, opts.PageSize, opts.Page*opts.PageSize)
rows, err := r.db.QueryContext(ctx, query, args...)
@@ -299,7 +305,11 @@ func (r *ResultRepository) List(ctx context.Context, opts repository.ListResults
return results, total, nil
}
func (r *ResultRepository) GetByCompetitionAndUser(ctx context.Context, competitionID uuid.UUID, userID uuid.UUID) (*domain.Result, error) {
func (r *ResultRepository) GetByCompetitionAndUser(
ctx context.Context,
competitionID uuid.UUID,
userID uuid.UUID,
) (*domain.Result, error) {
query := `SELECT id, competition_id, user_id, score, rank, status, submission_id, metadata, created_at, updated_at
FROM results WHERE competition_id = $1 AND user_id = $2`
row := r.db.QueryRowContext(ctx, query, competitionID, userID)
@@ -334,7 +344,12 @@ func (r *ResultRepository) GetByCompetitionAndUser(ctx context.Context, competit
return &result, nil
}
func (r *ResultRepository) GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int, offset int) ([]domain.Result, int, error) {
func (r *ResultRepository) GetLeaderboard(
ctx context.Context,
competitionID uuid.UUID,
limit int,
offset int,
) ([]domain.Result, int, error) {
if r.cacheEnabled {
key := r.leaderboardCacheKey(competitionID, limit, offset)
val, err := r.redisClient.Get(ctx, key).Result()
@@ -404,7 +419,11 @@ func (r *ResultRepository) GetLeaderboard(ctx context.Context, competitionID uui
return results, total, nil
}
func (r *ResultRepository) UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error) {
func (r *ResultRepository) UpdateStatus(
ctx context.Context,
id uuid.UUID,
status domain.ResultStatus,
) (*domain.Result, error) {
query := `UPDATE results SET status = $1, updated_at = $2 WHERE id = $3`
now := time.Now()
res, err := r.db.ExecContext(ctx, query, status, now, id)
+2 -1
View File
@@ -2,6 +2,7 @@ package repository
import (
"context"
"datarush/internal/results/domain"
"github.com/google/uuid"
@@ -27,4 +28,4 @@ type ResultRepository interface {
GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int, offset int) ([]domain.Result, int, error)
UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error)
RecalculateRanks(ctx context.Context, competitionID uuid.UUID) error
}
}
+22 -4
View File
@@ -52,7 +52,16 @@ 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) {
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),
@@ -76,11 +85,20 @@ func (s *Service) ListResults(ctx context.Context, pageSize int32, pageToken int
return results, int32(total), nextPageToken, nil
}
func (s *Service) GetByCompetitionAndUser(ctx context.Context, competitionID uuid.UUID, userID uuid.UUID) (*domain.Result, error) {
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) {
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
@@ -94,4 +112,4 @@ func (s *Service) UpdateStatus(ctx context.Context, id uuid.UUID, status domain.
func (s *Service) RecalculateRanks(ctx context.Context, competitionID uuid.UUID) error {
return s.repo.RecalculateRanks(ctx, competitionID)
}
}
+30 -17
View File
@@ -59,21 +59,34 @@ func (m *MockRepository) List(ctx context.Context, opts repository.ListResultsOp
return nil, 0, errors.New("not implemented")
}
func (m *MockRepository) GetByCompetitionAndUser(ctx context.Context, competitionID uuid.UUID, userID uuid.UUID) (*domain.Result, error) {
func (m *MockRepository) GetByCompetitionAndUser(
ctx context.Context,
competitionID uuid.UUID,
userID uuid.UUID,
) (*domain.Result, error) {
if m.GetByCompetitionAndUserFunc != nil {
return m.GetByCompetitionAndUserFunc(ctx, competitionID, userID)
}
return nil, errors.New("not implemented")
}
func (m *MockRepository) GetLeaderboard(ctx context.Context, competitionID uuid.UUID, limit int, offset int) ([]domain.Result, int, error) {
func (m *MockRepository) GetLeaderboard(
ctx context.Context,
competitionID uuid.UUID,
limit int,
offset int,
) ([]domain.Result, int, error) {
if m.GetLeaderboardFunc != nil {
return m.GetLeaderboardFunc(ctx, competitionID, limit, offset)
}
return nil, 0, errors.New("not implemented")
}
func (m *MockRepository) UpdateStatus(ctx context.Context, id uuid.UUID, status domain.ResultStatus) (*domain.Result, error) {
func (m *MockRepository) UpdateStatus(
ctx context.Context,
id uuid.UUID,
status domain.ResultStatus,
) (*domain.Result, error) {
if m.UpdateStatusFunc != nil {
return m.UpdateStatusFunc(ctx, id, status)
}
@@ -423,20 +436,20 @@ func TestListResults(t *testing.T) {
}
tests := []struct {
name string
pageSize int32
pageToken int32
competitionID *uuid.UUID
userID *uuid.UUID
status *domain.ResultStatus
minScore *float64
maxScore *float64
repoResults []domain.Result
repoTotal int
repoError error
expectError bool
expectedTotal int32
expectedNext int32
name string
pageSize int32
pageToken int32
competitionID *uuid.UUID
userID *uuid.UUID
status *domain.ResultStatus
minScore *float64
maxScore *float64
repoResults []domain.Result
repoTotal int
repoError error
expectError bool
expectedTotal int32
expectedNext int32
}{
{
name: "successful list with filters",