Files
SVSimServer/SVSim.Database/Services/Inventory/InventoryService.cs
gamer147 02e86cf16c feat(inventory): BeginAsync loads viewer with canonical graph
Includes Cards/Sleeves/Emblems/LeaderSkins/Degrees/MyPageBackgrounds/Items
under AsSplitQuery, plus caller-supplied extras via InventoryLoadConfig.
Opens a DB transaction and returns an InventoryTransaction shell. All
mutation methods throw NotImplementedException until subsequent tasks
land them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 15:46:20 -04:00

73 lines
2.4 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using SVSim.Database.Models;
using SVSim.Database.Models.Config;
using SVSim.Database.Repositories.Card;
using SVSim.Database.Repositories.Collectibles;
namespace SVSim.Database.Services.Inventory;
public sealed class InventoryService : IInventoryService
{
private readonly SVSimDbContext _db;
private readonly IGameConfigService _config;
private readonly ICardRepository _cards;
private readonly ICollectionRepository _collection;
private readonly ILogger<InventoryService> _log;
public InventoryService(
SVSimDbContext db,
IGameConfigService config,
ICardRepository cards,
ICollectionRepository collection,
ILogger<InventoryService> log)
{
_db = db;
_config = config;
_cards = cards;
_collection = collection;
_log = log;
}
public async Task<IInventoryTransaction> BeginAsync(
long viewerId,
CancellationToken ct = default,
Action<InventoryLoadConfig>? configure = null)
{
var loadCfg = new InventoryLoadConfig();
configure?.Invoke(loadCfg);
IQueryable<Viewer> query = _db.Viewers
.Include(v => v.Cards).ThenInclude(c => c.Card)
.Include(v => v.Sleeves)
.Include(v => v.Emblems)
.Include(v => v.LeaderSkins)
.Include(v => v.Degrees)
.Include(v => v.MyPageBackgrounds)
.Include(v => v.Items).ThenInclude(i => i.Item);
foreach (var include in loadCfg.Includes)
query = include(query);
var viewer = await query
.AsSplitQuery()
.FirstOrDefaultAsync(v => v.Id == viewerId, ct)
?? throw new InventoryViewerNotFoundException(viewerId);
var freeplay = _config.Get<FreeplayConfig>();
var dbTx = await _db.Database.BeginTransactionAsync(ct);
return new InventoryTransaction(_db, dbTx, viewer, freeplay, _log);
}
// Stubs for later tasks.
public Task<IReadOnlyList<OwnedCardEntry>> EffectiveOwnedCardsAsync(Viewer viewer, CancellationToken ct = default)
=> throw new NotImplementedException();
public Task<EffectiveCosmetics> EffectiveCosmeticsAsync(Viewer viewer, CancellationToken ct = default)
=> throw new NotImplementedException();
public long EffectiveBalance(Viewer viewer, SpendCurrency currency)
=> throw new NotImplementedException();
}