review(bp): drop fragile cast, thread CT, internalize cache reset

- IndexResponse.BattlePassLevelInfo widened to IReadOnlyDictionary<string,BattlePassLevel>?
  so any IReadOnlyDictionary impl (FrozenDictionary, wrapper, etc.) serializes correctly
  instead of silently null-ing via a failed as-cast
- LoadController.Index now takes CancellationToken ct and threads it to GetLevelCurveAsync
  instead of CancellationToken.None
- BattlePassRepository.ResetLevelCurveCache changed from public to internal; added
  InternalsVisibleTo("SVSim.UnitTests") to SVSim.Database.csproj (was absent)
This commit is contained in:
gamer147
2026-05-26 23:01:26 -04:00
parent 9bec1df52f
commit 7abdfe27cb
4 changed files with 8 additions and 5 deletions

View File

@@ -56,5 +56,5 @@ public sealed class BattlePassRepository : IBattlePassRepository
/// cache has already been populated (by an earlier test's HTTP call) must call this before
/// re-seeding so the next read fetches fresh rows.
/// </summary>
public static void ResetLevelCurveCache() => _curveCache = null;
internal static void ResetLevelCurveCache() => _curveCache = null;
}

View File

@@ -6,6 +6,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="SVSim.UnitTests" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />

View File

@@ -63,7 +63,7 @@ public class LoadController : SVSimController
}
[HttpPost("index")]
public async Task<ActionResult<IndexResponse>> Index(IndexRequest request)
public async Task<ActionResult<IndexResponse>> Index(IndexRequest request, CancellationToken ct)
{
var shortUdidClaim = User.Claims.FirstOrDefault(c => c.Type == ShadowverseClaimTypes.ShortUdidClaim)?.Value;
if (shortUdidClaim is null || !long.TryParse(shortUdidClaim, out long shortUdid))
@@ -197,8 +197,7 @@ public class LoadController : SVSimController
LootBoxRegulations = new LootBoxRegulations(),
GatheringInfo = new GatheringInfo(),
IsBattlePassPeriod = rotation.IsBattlePassPeriod,
BattlePassLevelInfo = (await _battlePass.GetLevelCurveAsync(CancellationToken.None))
as Dictionary<string, BattlePassLevel>,
BattlePassLevelInfo = await _battlePass.GetLevelCurveAsync(ct),
SpecialCrystalInfos = new List<SpecialCrystalInfo>(),
AvatarRotationInfo = await BuildAvatarInfoAsync(),
MyRotationInfo = await BuildMyRotationInfoAsync(),

View File

@@ -243,7 +243,7 @@ public class IndexResponse
/// </summary>
[JsonPropertyName("battle_pass_level_info")]
[Key("battle_pass_level_info")]
public Dictionary<string, BattlePassLevel>? BattlePassLevelInfo { get; set; }
public IReadOnlyDictionary<string, BattlePassLevel>? BattlePassLevelInfo { get; set; }
/// <summary>
/// Wire is string[]; parser calls .ToString() on each element (LoadDetail.cs:493-499).