feat(load): emit daily_login_bonus via ILoginBonusService

Grant runs inside the existing inventory tx so streak-bump and reward
credit commit atomically with cosmetic backfill.
This commit is contained in:
gamer147
2026-06-13 16:40:44 -04:00
parent 5083d43e51
commit 7d83560fc9
2 changed files with 51 additions and 7 deletions

View File

@@ -49,12 +49,14 @@ public class LoadController : SVSimController
private readonly SVSimDbContext _db;
private readonly IInventoryService _inv;
private readonly ICardMasterPayloadProvider _cardMaster;
private readonly ILoginBonusService _loginBonus;
public LoadController(IViewerRepository viewerRepository, IGlobalsRepository globalsRepository,
IGameConfigService config,
IBattlePassService battlePass, IViewerMissionStateService missionState,
SVSimDbContext db, IInventoryService inv,
ICardMasterPayloadProvider cardMaster)
ICardMasterPayloadProvider cardMaster,
ILoginBonusService loginBonus)
{
_viewerRepository = viewerRepository;
_globalsRepository = globalsRepository;
@@ -64,6 +66,7 @@ public class LoadController : SVSimController
_db = db;
_inv = inv;
_cardMaster = cardMaster;
_loginBonus = loginBonus;
}
[HttpPost("index")]
@@ -88,6 +91,7 @@ public class LoadController : SVSimController
// the response payload would be one /load/index behind on newly-granted cosmetics.
await using var tx = await _inv.BeginAsync(viewer.Id, ct);
await tx.BackfillCardCosmeticsAsync(ct);
DailyLoginBonus? loginBonusDto = await _loginBonus.GrantIfDueAsync(tx, ct);
await tx.CommitAsync(ct);
// Lazy-materialize mission/achievement state. Idempotent — safe to call every /load/index.
@@ -229,9 +233,7 @@ public class LoadController : SVSimController
MaintenanceCards = (await _globalsRepository.GetMaintenanceCards())
.Select(e => e.Id).ToList(),
RedEtherOverrides = new List<RedEtherOverride>(),
// Optional per spec (load-index.md:247). Populated by ILoginBonusService (Task 6)
// when the viewer has an active bonus period.
DailyLoginBonus = null,
DailyLoginBonus = loginBonusDto,
UserRankedMatches = new List<UserRankedMatches>(),
UserRankInfo = RankFormats.Select(f => new UserRankInfo
{