91 lines
3.6 KiB
C#
91 lines
3.6 KiB
C#
using GameList.Data;
|
|
using GameList.Domain;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GameList.Endpoints;
|
|
|
|
public static class AdminEndpoints
|
|
{
|
|
public static void MapAdminEndpoints(this IEndpointRouteBuilder app)
|
|
{
|
|
var admin = app.MapGroup("/api/admin");
|
|
|
|
admin.MapPost("/results", async ([FromBody] Contracts.ResultsOpenRequest request, HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
|
{
|
|
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
|
|
|
var state = await db.AppState.FirstAsync();
|
|
state.ResultsOpen = request.ResultsOpen;
|
|
state.UpdatedAt = DateTimeOffset.UtcNow;
|
|
|
|
if (request.ResultsOpen)
|
|
{
|
|
await db.Players.ExecuteUpdateAsync(p => p.SetProperty(x => x.CurrentPhase, Phase.Results));
|
|
}
|
|
else
|
|
{
|
|
await db.Players.ExecuteUpdateAsync(p => p.SetProperty(x => x.CurrentPhase, Phase.Vote)
|
|
.SetProperty(x => x.VotesFinal, false));
|
|
}
|
|
|
|
await db.SaveChangesAsync();
|
|
var currentState = await db.AppState.AsNoTracking().FirstAsync();
|
|
return Results.Ok(new { currentState.ResultsOpen, currentState.UpdatedAt });
|
|
});
|
|
|
|
admin.MapGet("/vote-status", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
|
{
|
|
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
|
|
|
var voters = await db.Players
|
|
.AsNoTracking()
|
|
.Where(p => p.CurrentPhase == Phase.Vote)
|
|
.OrderBy(p => p.DisplayName ?? p.Username)
|
|
.Select(p => new VoteStatusDto(p.Id, p.DisplayName ?? p.Username, p.VotesFinal))
|
|
.ToListAsync();
|
|
|
|
var waiting = voters.Where(v => !v.Finalized).Select(v => v.Name).ToList();
|
|
var ready = waiting.Count == 0;
|
|
return Results.Ok(new { voters, ready, waiting });
|
|
});
|
|
|
|
admin.MapPost("/reset", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
|
{
|
|
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
|
|
|
await db.Votes.ExecuteDeleteAsync();
|
|
await db.Suggestions.ExecuteDeleteAsync();
|
|
|
|
await db.Players.ExecuteUpdateAsync(p => p.SetProperty(x => x.CurrentPhase, Phase.Suggest)
|
|
.SetProperty(x => x.VotesFinal, false));
|
|
var state = await db.AppState.FirstAsync();
|
|
state.ResultsOpen = false;
|
|
state.UpdatedAt = DateTimeOffset.UtcNow;
|
|
await db.SaveChangesAsync();
|
|
|
|
return Results.Ok(new { Phase = Phase.Suggest, state.ResultsOpen, state.UpdatedAt });
|
|
});
|
|
|
|
admin.MapPost("/factory-reset", async (HttpContext ctx, AppDbContext db, IConfiguration config) =>
|
|
{
|
|
if (!await EndpointHelpers.IsAdmin(ctx, db, config)) return Results.Unauthorized();
|
|
|
|
await using var tx = await db.Database.BeginTransactionAsync();
|
|
|
|
await db.Votes.ExecuteDeleteAsync();
|
|
await db.Suggestions.ExecuteDeleteAsync();
|
|
await db.Players.ExecuteDeleteAsync();
|
|
await db.AppState.ExecuteDeleteAsync();
|
|
|
|
var fresh = EndpointHelpers.NewAppState();
|
|
db.AppState.Add(fresh);
|
|
await db.SaveChangesAsync();
|
|
|
|
await tx.CommitAsync();
|
|
|
|
return Results.Ok(new { Phase = Phase.Suggest, fresh.ResultsOpen, fresh.UpdatedAt });
|
|
});
|
|
}
|
|
}
|