using FastEndpoints; using SpaceGame.Api.Auth.Runtime; using SpaceGame.Api.Auth.Simulation; using SpaceGame.Api.PlayerFaction.Simulation; namespace SpaceGame.Api.PlayerFaction.Api; public sealed class GetPlayerIdentitiesHandler(IAuthRepository authRepository, IPlayerStateStore playerStateStore) : EndpointWithoutRequest> { public override void Configure() { Get("/api/player-faction/identities"); Policies(AuthPolicyNames.GmAccess); } public override async Task HandleAsync(CancellationToken cancellationToken) { var users = await authRepository.ListUsersAsync(cancellationToken); var playerFactionsByPlayerId = playerStateStore.GetPlayerFactionsByPlayerId(); var responses = new List(users.Count + playerFactionsByPlayerId.Count); var seenIds = new HashSet(StringComparer.Ordinal); foreach (var user in users) { var userId = user.Id.ToString("N"); playerFactionsByPlayerId.TryGetValue(userId, out var playerFaction); responses.Add(new PlayerIdentitySummaryResponse( userId, user.Email, user.Roles, playerFaction is not null, playerFaction?.Id, playerFaction?.Label, playerFaction?.SovereignFactionId)); seenIds.Add(userId); } foreach (var (playerId, playerFaction) in playerFactionsByPlayerId) { if (!seenIds.Add(playerId)) { continue; } responses.Add(new PlayerIdentitySummaryResponse( playerId, $"{playerId}@unknown", Array.Empty(), true, playerId, playerFaction.Label, playerFaction.SovereignFactionId)); } await SendOkAsync( responses .OrderBy(response => response.Email, StringComparer.OrdinalIgnoreCase) .ThenBy(response => response.UserId, StringComparer.Ordinal) .ToList(), cancellationToken); } } public sealed record PlayerIdentitySummaryResponse( string UserId, string Email, IReadOnlyList Roles, bool HasPlayerFaction, string? PlayerFactionId, string? PlayerFactionLabel, string? SovereignFactionId);