feat(packs): wire PackDrawTableImporter; retire ICardPoolProvider

Bootstrap Program.cs now calls PackDrawTableImporter after PackImporter.
Delete DbCardPoolProvider, ICardPoolProvider, and the DbCardPoolProvider
tests — the new IPackDrawTableRepository covers what GachaPointService
needed (legendary-tier card_ids per pack) and PackOpenService takes the
draw table directly.

GachaPointService now resolves the legendary catalog from
PackDrawTable.CardWeights filtered by Tier==Legendary, instead of
ICardPoolProvider.GetPool then a rarity filter. Same end set, no DB pool
walk.

Test fallout: tests that fabricate custom card sets for gacha-point
tests now call factory.SeedPackDrawTableFromSetAsync(packId, setId)
to install a matching legendary-tier stub. Full suite: 647/647 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-05-30 22:45:02 -04:00
parent 1c386b5ed0
commit 517f855112
9 changed files with 60 additions and 239 deletions

View File

@@ -276,7 +276,32 @@ internal sealed class SVSimTestFactory : WebApplicationFactory<Program>
/// at 100% rate; slot 1-7 and slot 8 both draw from the same pool. Use for tests that need
/// /pack/open to succeed against a custom seeded card pool.
/// </summary>
public async Task SeedPackDrawTableAsync(int packId, params long[] cardIds)
public Task SeedPackDrawTableAsync(int packId, params long[] cardIds)
=> SeedPackDrawTableAsync(packId, DrawTier.Bronze, cardIds);
/// <summary>
/// Convenience for gacha-point tests: picks Legendary cards from <paramref name="cardSetId"/>
/// (skipping foils) and seeds them as the draw table's Legendary tier for <paramref name="packId"/>.
/// </summary>
public async Task SeedPackDrawTableFromSetAsync(int packId, int cardSetId)
{
using var scope = Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
var legendaryIds = await db.CardSets
.Where(s => s.Id == cardSetId)
.SelectMany(s => s.Cards)
.Where(c => c.Rarity == SVSim.Database.Enums.Rarity.Legendary && !c.IsFoil)
.Select(c => c.Id)
.ToListAsync();
if (legendaryIds.Count > 0)
{
await SeedPackDrawTableAsync(packId, DrawTier.Legendary, legendaryIds.ToArray());
}
}
public async Task SeedPackDrawTableAsync(int packId, DrawTier tier, params long[] cardIds)
{
using var scope = Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<SVSimDbContext>();
@@ -284,12 +309,12 @@ internal sealed class SVSimTestFactory : WebApplicationFactory<Program>
if (await db.PackDrawConfigs.AnyAsync(c => c.Id == packId)) return;
db.PackDrawConfigs.Add(new PackDrawConfigEntry { Id = packId, AnimationRatePct = 0 });
db.PackDrawSlotRates.Add(new PackDrawSlotRateEntry { PackId = packId, Slot = DrawSlot.General, Tier = DrawTier.Bronze, RatePct = 100 });
db.PackDrawSlotRates.Add(new PackDrawSlotRateEntry { PackId = packId, Slot = DrawSlot.Eighth, Tier = DrawTier.Bronze, RatePct = 100 });
db.PackDrawSlotRates.Add(new PackDrawSlotRateEntry { PackId = packId, Slot = DrawSlot.General, Tier = tier, RatePct = 100 });
db.PackDrawSlotRates.Add(new PackDrawSlotRateEntry { PackId = packId, Slot = DrawSlot.Eighth, Tier = tier, RatePct = 100 });
foreach (var cid in cardIds)
{
db.PackDrawCardWeights.Add(new PackDrawCardWeightEntry { PackId = packId, Slot = DrawSlot.General, Tier = DrawTier.Bronze, CardId = cid, RatePct = 100.0 / cardIds.Length });
db.PackDrawCardWeights.Add(new PackDrawCardWeightEntry { PackId = packId, Slot = DrawSlot.Eighth, Tier = DrawTier.Bronze, CardId = cid, RatePct = 100.0 / cardIds.Length });
db.PackDrawCardWeights.Add(new PackDrawCardWeightEntry { PackId = packId, Slot = DrawSlot.General, Tier = tier, CardId = cid, RatePct = 100.0 / cardIds.Length });
db.PackDrawCardWeights.Add(new PackDrawCardWeightEntry { PackId = packId, Slot = DrawSlot.Eighth, Tier = tier, CardId = cid, RatePct = 100.0 / cardIds.Length });
}
await db.SaveChangesAsync();
}