88 lines
2.8 KiB
C#
88 lines
2.8 KiB
C#
using GameList.Contracts;
|
|
using GameList.Data;
|
|
using GameList.Domain;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GameList.Endpoints;
|
|
|
|
internal sealed class ResultsWorkflowService(AppDbContext db)
|
|
{
|
|
public async Task<IResult> GetResultsAsync(Player player)
|
|
{
|
|
var appState = await db.AppState.AsNoTracking().FirstAsync();
|
|
if (!appState.ResultsOpen)
|
|
return Results.BadRequest(new { error = "Results are locked until the admin enables them." });
|
|
|
|
var phase = await EndpointHelpers.GetCurrentPhaseAsync(db, player.Id);
|
|
if (phase != Phase.Results)
|
|
return EndpointHelpers.PhaseMismatch(Phase.Results, phase);
|
|
|
|
var results = await db
|
|
.Suggestions.AsNoTracking()
|
|
.Include(s => s.Player)
|
|
.Include(s => s.Votes)
|
|
.Select(s => new
|
|
{
|
|
s.Id,
|
|
s.Name,
|
|
Author = s.Player!.DisplayName,
|
|
s.MinPlayers,
|
|
s.MaxPlayers,
|
|
Total = s.Votes.Sum(v => v.Score),
|
|
s.Votes.Count,
|
|
Average = s.Votes.Count == 0 ? 0 : s.Votes.Average(v => v.Score),
|
|
Votes = s.Votes.Select(v => v.Score).ToList(),
|
|
MyVote = s.Votes
|
|
.Where(v => v.PlayerId == player.Id)
|
|
.Select(v => (int?)v.Score)
|
|
.FirstOrDefault(),
|
|
s.ScreenshotUrl,
|
|
s.YoutubeUrl,
|
|
s.GameUrl,
|
|
s.Description,
|
|
s.Genre,
|
|
s.ParentSuggestionId
|
|
})
|
|
.OrderByDescending(r => r.Average)
|
|
.ToListAsync();
|
|
|
|
var rootIndex = EndpointHelpers.BuildLinkRoots(results.Select(r => (r.Id, r.ParentSuggestionId)));
|
|
var nameLookup = results.ToDictionary(r => r.Id, r => r.Name);
|
|
|
|
var shaped = results.Select(r =>
|
|
{
|
|
var linkedIds = EndpointHelpers.LinkedIdsFor(r.Id, rootIndex)
|
|
.Where(id => id != r.Id)
|
|
.ToList();
|
|
|
|
var linkedTitles = linkedIds
|
|
.Where(nameLookup.ContainsKey)
|
|
.Select(id => nameLookup[id])
|
|
.ToList();
|
|
|
|
return new ResultItemDto(
|
|
r.Id,
|
|
r.Name,
|
|
r.Author,
|
|
r.MinPlayers,
|
|
r.MaxPlayers,
|
|
r.Total,
|
|
r.Count,
|
|
r.Average,
|
|
r.Votes,
|
|
r.MyVote,
|
|
r.ScreenshotUrl,
|
|
r.YoutubeUrl,
|
|
r.GameUrl,
|
|
r.Description,
|
|
r.Genre,
|
|
r.ParentSuggestionId,
|
|
linkedIds,
|
|
linkedTitles
|
|
);
|
|
});
|
|
|
|
return Results.Ok(shaped);
|
|
}
|
|
}
|