using SVSim.Database.Enums; using SVSim.Database.Models; namespace SVSim.Database.Services.RankProgress; /// /// Wire-shape result of a single rank-battle finish grant. All fields map 1:1 to /// RankBattleFinishResponseDto keys the client reads via GetValueOrDefault /// in Wizard/RankBattleFinishTask.cs:57-63. /// /// rank_id post-grant (1..29). /// Point post-grant (accumulated). /// MasterPoint post-grant (accumulated). /// Signed Point delta (+100/-50/0). /// Signed MasterPoint delta. /// True iff Rank == 25. /// True iff Rank >= 26. public sealed record RankProgressResult( int Rank, int AfterBattlePoint, int AfterMasterPoint, int BattlePoint, int MasterPoint, bool IsMasterRank, bool IsGrandMasterRank); public interface IRankProgressService { /// /// Applies a +100 (win) or -50 (loss) delta to the viewer's rank progression in the /// given format, respecting tier floors from ranks.csv's LowerLimitPoint column. /// Creates a ViewerRankProgress row for (viewer, format) if none exists. Caller must /// have loaded the viewer with .Include(v => v.RankProgress) and must call /// SaveChangesAsync after this returns. /// /// Must be Format.Rotation or Format.Unlimited. Task GrantAsync( Viewer viewer, Format format, bool isWin, CancellationToken ct = default); /// /// Read-only current progression snapshot for (viewer, format). Returns a zero-value /// result if no row exists. Does not mutate the viewer or hit the DB. /// Task GetAsync( Viewer viewer, Format format, CancellationToken ct = default); }