99 lines
3.7 KiB
C#
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);
|
|
}
|
|
);
|
|
}
|
|
}
|