feat(missions): /load/index materializes viewer mission/achievement state

EnsureCurrentAsync now takes viewerId (was Viewer), so it works with
LoadController's AsNoTracking-loaded detached viewers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-05-27 10:45:31 -04:00
parent 640a77ec6c
commit 5693ec0302
6 changed files with 27 additions and 18 deletions

View File

@@ -1,5 +1,6 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using SVSim.Database;
using SVSim.Database.Enums;
using SVSim.Database.Models;
using SVSim.Database.Models.Config;
@@ -47,11 +48,14 @@ public class LoadController : SVSimController
private readonly ICardAcquisitionService _acquisition;
private readonly IGameConfigService _config;
private readonly IBattlePassService _battlePass;
private readonly IViewerMissionStateService _missionState;
private readonly SVSimDbContext _db;
public LoadController(IViewerRepository viewerRepository, ICardRepository cardRepository,
ICollectionRepository collectionRepository, IGlobalsRepository globalsRepository,
ICardAcquisitionService acquisition, IGameConfigService config,
IBattlePassService battlePass)
IBattlePassService battlePass, IViewerMissionStateService missionState,
SVSimDbContext db)
{
_viewerRepository = viewerRepository;
_cardRepository = cardRepository;
@@ -60,6 +64,8 @@ public class LoadController : SVSimController
_acquisition = acquisition;
_config = config;
_battlePass = battlePass;
_missionState = missionState;
_db = db;
}
[HttpPost("index")]
@@ -83,6 +89,11 @@ public class LoadController : SVSimController
// (on a separate tracked instance) won't appear on this snapshot. Without the re-fetch,
// the response payload would be one /load/index behind on newly-granted cosmetics.
await _acquisition.BackfillCosmeticsAsync(viewer.Id);
// Lazy-materialize mission/achievement state. Idempotent — safe to call every /load/index.
await _missionState.EnsureCurrentAsync(viewer.Id);
await _db.SaveChangesAsync();
viewer = await _viewerRepository.GetViewerByShortUdid(shortUdid);
if (viewer is null)
{