using System.Text.Json.Serialization; using NeonSprawl.Server.Game.Quests; namespace NeonSprawl.Server.Game.Contracts; /// POST body for POST /game/players/{{id}}/contracts/issue (NEO-151). public sealed class ContractIssueRequest { public const int CurrentSchemaVersion = 1; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } [JsonPropertyName("playerId")] public string? PlayerId { get; init; } [JsonPropertyName("templateId")] public string? TemplateId { get; init; } [JsonPropertyName("seedBucket")] public string? SeedBucket { get; init; } [JsonPropertyName("zoneDifficultyBand")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? ZoneDifficultyBand { get; init; } } /// POST response for contract issue (NEO-151). public sealed class ContractIssueResponse { public const int CurrentSchemaVersion = 1; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } = CurrentSchemaVersion; [JsonPropertyName("issued")] public bool Issued { get; init; } [JsonPropertyName("reasonCode")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasonCode { get; init; } [JsonPropertyName("contract")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ContractInstanceRowJson? Contract { get; init; } } /// JSON body for GET /game/players/{{id}}/contracts (NEO-151). public sealed class ContractListResponse { public const int CurrentSchemaVersion = 1; [JsonPropertyName("schemaVersion")] public int SchemaVersion { get; init; } = CurrentSchemaVersion; [JsonPropertyName("playerId")] public required string PlayerId { get; init; } [JsonPropertyName("contracts")] public required IReadOnlyList Contracts { get; init; } } /// Authoritative contract instance projection for HTTP clients (NEO-151). public sealed class ContractInstanceRowJson { [JsonPropertyName("contractInstanceId")] public required string ContractInstanceId { get; init; } [JsonPropertyName("templateId")] public required string TemplateId { get; init; } [JsonPropertyName("templateDisplayName")] public required string TemplateDisplayName { get; init; } /// active or completed. [JsonPropertyName("status")] public required string Status { get; init; } [JsonPropertyName("encounterTemplateId")] public required string EncounterTemplateId { get; init; } [JsonPropertyName("seedBucket")] public required string SeedBucket { get; init; } [JsonPropertyName("issuedAt")] public DateTimeOffset IssuedAt { get; init; } [JsonPropertyName("completedAt")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public DateTimeOffset? CompletedAt { get; init; } [JsonPropertyName("completionRewardSummary")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public QuestCompletionRewardSummaryJson? CompletionRewardSummary { get; init; } }