review(bp): doc fixes + sales_period_info non-nullable + drop checked cast + TODO
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,10 @@ namespace SVSim.Database.Repositories.BattlePass;
|
|||||||
public interface IViewerBattlePassRepository
|
public interface IViewerBattlePassRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get-or-create progress row for (viewer, season). New rows are added to the change-tracker
|
/// Get-or-create progress row for (viewer, season). New rows are saved IMMEDIATELY (with
|
||||||
/// but NOT saved — caller batches with other mutations.
|
/// DbUpdateException catch-and-retry to handle the concurrent-first-visit race against
|
||||||
|
/// the (ViewerId, SeasonId) unique index). Existing rows are returned tracked so callers
|
||||||
|
/// can mutate them and batch the save with other changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<ViewerBattlePassProgressEntry> GetOrCreateProgressAsync(long viewerId, int seasonId, CancellationToken ct);
|
Task<ViewerBattlePassProgressEntry> GetOrCreateProgressAsync(long viewerId, int seasonId, CancellationToken ct);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,12 @@ public class BattlePassController : SVSimController
|
|||||||
if (!TryGetViewerId(out long viewerId)) return Unauthorized();
|
if (!TryGetViewerId(out long viewerId)) return Unauthorized();
|
||||||
|
|
||||||
var info = await _battlePass.GetInfoAsync(viewerId, ct);
|
var info = await _battlePass.GetInfoAsync(viewerId, ct);
|
||||||
if (info is null) return Ok(new { }); // off-season: empty payload
|
// TODO(off-season-crash): Empty {} body crashes BattlePassInfoTask.Parse() on the
|
||||||
|
// client (unconditional jsonData["season_info"] access). Unreachable in practice —
|
||||||
|
// season 23 outlasts the Cygames shutdown. If a season-24+ ever lands, set
|
||||||
|
// data_headers.result_code != 1 here so base.Parse() short-circuits before the
|
||||||
|
// subclass Parse runs.
|
||||||
|
if (info is null) return Ok(new { });
|
||||||
return Ok(info);
|
return Ok(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +40,11 @@ public class BattlePassController : SVSimController
|
|||||||
if (!TryGetViewerId(out long viewerId)) return Unauthorized();
|
if (!TryGetViewerId(out long viewerId)) return Unauthorized();
|
||||||
|
|
||||||
var list = await _battlePass.GetItemListAsync(viewerId, ct);
|
var list = await _battlePass.GetItemListAsync(viewerId, ct);
|
||||||
|
// TODO(off-season-crash): Empty {} body crashes BattlePassPurchaseInfoTask.Parse() on the
|
||||||
|
// client (unconditional jsonData["premium_pass_description"] access). Unreachable in
|
||||||
|
// practice — season 23 outlasts the Cygames shutdown. If a season-24+ ever lands, set
|
||||||
|
// data_headers.result_code != 1 here so base.Parse() short-circuits before the
|
||||||
|
// subclass Parse runs.
|
||||||
if (list is null) return Ok(new { });
|
if (list is null) return Ok(new { });
|
||||||
return Ok(list);
|
return Ok(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ public class BattlePassItemListResponse
|
|||||||
|
|
||||||
[JsonPropertyName("sales_period_info")]
|
[JsonPropertyName("sales_period_info")]
|
||||||
[Key("sales_period_info")]
|
[Key("sales_period_info")]
|
||||||
public BattlePassSalesPeriodInfoDto? SalesPeriodInfo { get; set; }
|
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||||
|
public BattlePassSalesPeriodInfoDto SalesPeriodInfo { get; set; } = new();
|
||||||
|
|
||||||
[JsonPropertyName("products")]
|
[JsonPropertyName("products")]
|
||||||
[Key("products")]
|
[Key("products")]
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ public sealed class BattlePassService : IBattlePassService
|
|||||||
// append the post-deduction total so the client gets the correct final balance.
|
// append the post-deduction total so the client gets the correct final balance.
|
||||||
postState.RemoveAll(r => r.RewardType == (int)UserGoodsType.Crystal);
|
postState.RemoveAll(r => r.RewardType == (int)UserGoodsType.Crystal);
|
||||||
postState.Add(new GrantedReward(
|
postState.Add(new GrantedReward(
|
||||||
(int)UserGoodsType.Crystal, 0, checked((int)viewer.Currency.Crystals)));
|
(int)UserGoodsType.Crystal, 0, (int)viewer.Currency.Crystals));
|
||||||
|
|
||||||
return new BattlePassBuyOutcome(1, achieved, postState);
|
return new BattlePassBuyOutcome(1, achieved, postState);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user