using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; using SVSim.Database.Enums; namespace SVSim.Database.Models; /// /// One active Grand Prix (Arena Colosseum) bracket run per viewer. Mirrors /// in shape so the 2-Pick draft state machine can be /// lifted onto it in Phase 3 — the schema is the union of constructed-mode lifecycle /// (registered decks, bracket counts, rank-match promotion flag) and TK2-style draft /// state. Standalone (not a Viewer owned collection) per /// project_ef_nav_include_pitfall, with a unique index on ViewerId to enforce /// "one active run per viewer". Row is deleted on /finish or /retire. /// [Index(nameof(ViewerId), IsUnique = true)] public class ViewerArenaColosseumRun { public long Id { get; set; } public long ViewerId { get; set; } /// Wire entry_info.id. Set to on insert. public long EntryId { get; set; } /// Stamped from at entry time so /// mid-run season-config edits don't shift the run's identity. public int SeasonId { get; set; } /// Current bracket round (1..3 in the canonical 3-round schedule). Indexes /// at entry time, advances on bracket /// promotion via ColosseumProgressionService. public int RoundId { get; set; } /// Format the bracket plays in (Rotation/Unlimited/TwoPick/HOF/WindFall/Avatar/...). /// Stamped from season config at entry time. public Format DeckFormat { get; set; } public long LeaderSkinId { get; set; } /// eARENA_PAY: 1 = ticket, 2 = crystal, 3 = rupy, 0 = free entry. Stamped at entry. public int ConsumeItemType { get; set; } // --- 2-Pick / Chaos draft state (lifted from ViewerArenaTwoPickRun for Phase 3) --- [Column(TypeName = "jsonb")] public string CandidateClassIdsJson { get; set; } = "[]"; /// Stored as 0 in constructed mode (no draft turn machinery). public int SelectTurn { get; set; } public bool IsSelectCompleted { get; set; } [Column(TypeName = "jsonb")] public string SelectedCardIdsJson { get; set; } = "[]"; [Column(TypeName = "jsonb")] public string PendingPickSetsJson { get; set; } = "[]"; /// Monotonic counter for CandidatePair.Id; advances by 2 each draft turn. public long NextCandidateId { get; set; } = 1; /// Selected class for 2-Pick / Chaos modes; 0 in constructed mode. public int ClassId { get; set; } /// Optional Chaos sub-mode replay id. 0 when not in Chaos. public int ChaosId { get; set; } // --- Per-round bracket state --- [Column(TypeName = "jsonb")] public string ResultListJson { get; set; } = "[]"; public int WinCount { get; set; } public int LossCount { get; set; } public int BattleCountThisRound { get; set; } /// Cap copied from the matching ColosseumRoundsConfig.Rounds[RoundId-1].Groups[0] /// at entry — stamped so mid-run round-config edits don't shift the cap. public int MaxBattleCountThisRound { get; set; } /// Wins required to break through to the next round. Same stamping rule as /// . public int BreakthroughNumberThisRound { get; set; } /// Remaining attempts in the current entry. Decremented per battle finish until /// 0 or breakthrough. public int RestEntryNum { get; set; } /// Flipped exactly once when the node signals matching_state == 3008. /// Subsequent battle URLs use the colosseum_rank_battle/* prefix. public bool IsRankMatching { get; set; } public bool IsChampion { get; set; } // --- Registered deck slot (constructed mode) --- [Column(TypeName = "jsonb")] public string RegisteredDeckNoListJson { get; set; } = "[]"; public bool IsPublished { get; set; } public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } }