using GameList.Data; using GameList.Domain; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace GameList.Endpoints; internal static class EndpointHelpers { public static async Task GetOrCreatePlayer(HttpContext ctx, AppDbContext db) { if (!ctx.Items.TryGetValue(Infrastructure.PlayerIdentityExtensions.PlayerCookieName, out var value) || value is not Guid playerId) { throw new InvalidOperationException("Player cookie missing."); } var existing = await db.Players.FindAsync(playerId); if (existing != null) return existing; var player = new Player { Id = playerId }; db.Players.Add(player); await db.SaveChangesAsync(); return player; } public static async Task GetPhase(AppDbContext db) { var state = await db.AppState.AsNoTracking().FirstAsync(); return state.CurrentPhase; } public static IResult PhaseMismatch(Phase required, Phase current) => Results.BadRequest(new { error = $"This endpoint is available in the {required} phase. Current phase is {current}." }); public static string? TrimTo(string? input, int max) => string.IsNullOrWhiteSpace(input) ? null : input.Trim() is var t && t.Length > 0 ? t[..Math.Min(t.Length, max)] : null; public static bool IsAuthorized(HttpContext ctx, IConfiguration config) { var provided = ctx.Request.Headers["X-Admin-Key"].FirstOrDefault() ?? ctx.Request.Query["key"].FirstOrDefault(); var expected = config["ADMIN_PASSWORD"]; return !string.IsNullOrWhiteSpace(expected) && provided == expected; } public static AppState NewAppState() => new() { Id = 1, CurrentPhase = Phase.Suggest, UpdatedAt = DateTimeOffset.UnixEpoch }; }