refactor(battlepass): route premium-buy crystal spend through CurrencySpendService
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,19 +23,22 @@ public sealed class BattlePassService : IBattlePassService
|
||||
private readonly TimeProvider _time;
|
||||
private readonly SVSimDbContext _db;
|
||||
private readonly RewardGrantService _rewards;
|
||||
private readonly ICurrencySpendService _spend;
|
||||
|
||||
public BattlePassService(
|
||||
IBattlePassRepository bp,
|
||||
IViewerBattlePassRepository viewerBp,
|
||||
TimeProvider time,
|
||||
SVSimDbContext db,
|
||||
RewardGrantService rewards)
|
||||
RewardGrantService rewards,
|
||||
ICurrencySpendService spend)
|
||||
{
|
||||
_bp = bp;
|
||||
_viewerBp = viewerBp;
|
||||
_time = time;
|
||||
_db = db;
|
||||
_rewards = rewards;
|
||||
_spend = spend;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyDictionary<string, BattlePassLevel>?> GetLevelCurveAsync(CancellationToken ct)
|
||||
@@ -166,13 +169,13 @@ public sealed class BattlePassService : IBattlePassService
|
||||
if (progress.IsPremium)
|
||||
return new BattlePassBuyOutcome(23, Array.Empty<GrantedReward>(), Array.Empty<GrantedReward>());
|
||||
|
||||
if (viewer.Currency.Crystals < (ulong)season.PriceCrystal)
|
||||
var spendResult = await _spend.TrySpendAsync(viewer, SpendCurrency.Crystal, season.PriceCrystal, ct);
|
||||
if (!spendResult.Success)
|
||||
return new BattlePassBuyOutcome(22, Array.Empty<GrantedReward>(), Array.Empty<GrantedReward>());
|
||||
|
||||
// BeginTransactionAsync is a no-op on the SQLite in-memory test DB but is safe to call.
|
||||
await using var tx = await _db.Database.BeginTransactionAsync(ct);
|
||||
|
||||
viewer.Currency.Crystals -= (ulong)season.PriceCrystal;
|
||||
progress.IsPremium = true;
|
||||
|
||||
// Retroactive grants: every premium reward at level <= current_level not already claimed.
|
||||
@@ -206,7 +209,7 @@ public sealed class BattlePassService : IBattlePassService
|
||||
// append the post-deduction total so the client gets the correct final balance.
|
||||
postState.RemoveAll(r => r.RewardType == (int)UserGoodsType.Crystal);
|
||||
postState.Add(new GrantedReward(
|
||||
(int)UserGoodsType.Crystal, 0, (int)viewer.Currency.Crystals));
|
||||
(int)UserGoodsType.Crystal, 0, (int)spendResult.PostStateTotal));
|
||||
|
||||
return new BattlePassBuyOutcome(1, achieved, postState);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user