Files
GameList/Endpoints/ResultsEndpoints.cs

99 lines
3.7 KiB
C#

using GameList.Data;
using GameList.Domain;
using Microsoft.EntityFrameworkCore;
using GameList.Infrastructure;
namespace GameList.Endpoints;
public static class ResultsEndpoints
{
public static void MapResultsEndpoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/api/results")
.RequireAuthorization()
.AddEndpointFilter(new PhaseRequirementFilter(Phase.Results));
group.MapGet(
"/",
async (HttpContext ctx, AppDbContext db) =>
{
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
if (player is null)
return Results.Unauthorized();
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.GetPhase(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),
Count = 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(id => nameLookup.ContainsKey(id))
.Select(id => nameLookup[id])
.ToList()
};
});
return Results.Ok(shaped);
}
);
}
}