using System.Text.Json.Serialization;
namespace NeonSprawl.Server.Game.Skills;
/// POST body for applying one skill XP grant (NEO-38).
public sealed class SkillProgressionGrantRequest
{
public const int CurrentSchemaVersion = 1;
[JsonPropertyName("schemaVersion")]
public int SchemaVersion { get; init; }
[JsonPropertyName("skillId")]
public required string SkillId { get; init; }
[JsonPropertyName("amount")]
public int Amount { get; init; }
/// Validated against target skill's allowedXpSourceKinds (ordinal ignore-case).
[JsonPropertyName("sourceKind")]
public required string SourceKind { get; init; }
}
/// POST responses for progression grants — success () or structured deny ().
public sealed class SkillProgressionGrantResponse
{
public const int CurrentSchemaVersion = 1;
[JsonPropertyName("schemaVersion")]
public int SchemaVersion { get; init; } = CurrentSchemaVersion;
[JsonPropertyName("granted")]
public bool Granted { get; init; }
/// Set when is false; stable snake_case values (see README).
[JsonPropertyName("reasonCode")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ReasonCode { get; init; }
[JsonPropertyName("progression")]
public required SkillProgressionSnapshotResponse Progression { get; init; }
/// Present on success only; empty array when XP changed but level did not.
[JsonPropertyName("levelUps")]
public required IReadOnlyList LevelUps { get; init; }
}
/// One skill crossed a level boundary on this grant (previousLevel < newLevel).
public sealed class SkillLevelUpJson
{
[JsonPropertyName("skillId")]
public required string SkillId { get; init; }
[JsonPropertyName("previousLevel")]
public int PreviousLevel { get; init; }
[JsonPropertyName("newLevel")]
public int NewLevel { get; init; }
}