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 /// 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. /// re-seeding so the next read fetches fresh rows.
/// </summary> /// </summary>
public static void ResetLevelCurveCache() => _curveCache = null; internal static void ResetLevelCurveCache() => _curveCache = null;
} }

View File

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

View File

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

View File

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