using NeonSprawl.Server.Game.PositionState; namespace NeonSprawl.Server.Game.Skills; /// Maps GET /game/players/{{id}}/skill-progression (NEO-37). public static class SkillProgressionSnapshotApi { public static WebApplication MapSkillProgressionSnapshotApi(this WebApplication app) { app.MapGet( "/game/players/{id}/skill-progression", (string id, IPositionStateStore positions, ISkillDefinitionRegistry registry) => { if (!positions.TryGetPosition(id, out _)) { return Results.NotFound(); } var trimmedId = id.Trim(); return Results.Json(BuildSnapshot(trimmedId, registry)); }); return app; } internal static SkillProgressionSnapshotResponse BuildSnapshot( string playerId, ISkillDefinitionRegistry registry) { var defs = registry.GetDefinitionsInIdOrder(); var skills = new List(defs.Count); foreach (var d in defs) { skills.Add( new SkillProgressionRowJson { Id = d.Id, Xp = 0, Level = 1, }); } // Ordinal sort for stable serialization; consumers must index rows by skill id (NEO-37). skills.Sort(static (a, b) => string.CompareOrdinal(a.Id, b.Id)); return new SkillProgressionSnapshotResponse { PlayerId = playerId, Skills = skills, SchemaVersion = SkillProgressionSnapshotResponse.CurrentSchemaVersion, }; } }