Extract admin and results workflows into services
This commit is contained in:
85
Endpoints/ResultsWorkflowService.cs
Normal file
85
Endpoints/ResultsWorkflowService.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
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();
|
||||
|
||||
return new
|
||||
{
|
||||
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 = linkedIds,
|
||||
LinkedTitles = linkedIds
|
||||
.Where(nameLookup.ContainsKey)
|
||||
.Select(id => nameLookup[id])
|
||||
.ToList()
|
||||
};
|
||||
});
|
||||
|
||||
return Results.Ok(shaped);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user