Both types stay in namespace SVSim.Database.Services so existing using directives in controllers, services, and tests resolve without change. Their definitions are extracted to SVSim.Database/Services/Inventory/InventoryGrantTypes.cs; the empty husks in RewardGrantService.cs and IViewerEntitlements.cs will be deleted in the next commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
43 lines
1.9 KiB
C#
43 lines
1.9 KiB
C#
using SVSim.Database.Enums;
|
|
using SVSim.Database.Models;
|
|
|
|
namespace SVSim.Database.Services;
|
|
|
|
/// <summary>
|
|
/// The single read/ownership authority for what a viewer is *treated as* owning. Knows the
|
|
/// Freeplay flag; all freeplay read-side behavior lives here. See
|
|
/// docs/superpowers/specs/2026-05-29-freeplay-mode-design.md.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <b>Include precondition:</b> methods that inspect the viewer's collections require the
|
|
/// viewer to have been loaded with <c>.Include(v => v.Cards).ThenInclude(c => c.Card)</c>
|
|
/// and the cosmetic collections
|
|
/// (<c>Sleeves</c>, <c>Emblems</c>, <c>Degrees</c>, <c>LeaderSkins</c>, <c>MyPageBackgrounds</c>)
|
|
/// included. Without those includes the EF owned-collection nav refs are null or zero-filled
|
|
/// (see the EF owned-collection nav-include pitfall in MEMORY.md).
|
|
/// </remarks>
|
|
public interface IViewerEntitlements
|
|
{
|
|
/// <summary>True when the global Freeplay config section is enabled.</summary>
|
|
bool IsFreeplay { get; }
|
|
|
|
/// <summary>
|
|
/// The balance the viewer is treated as having: the configured freeplay amount for
|
|
/// Crystal/Rupee/RedEther when freeplay is on, otherwise (and always for SpotPoint) the real
|
|
/// <c>viewer.Currency</c> field.
|
|
/// </summary>
|
|
long EffectiveBalance(Viewer viewer, SpendCurrency currency);
|
|
|
|
bool OwnsCard(Viewer viewer, long cardId);
|
|
|
|
/// <summary><paramref name="type"/> uses <see cref="CosmeticType"/> (Skin == leader skin).</summary>
|
|
bool OwnsCosmetic(Viewer viewer, CosmeticType type, int id);
|
|
|
|
/// <summary>The full owned-card projection for /load/index's user_card_list.</summary>
|
|
Task<IReadOnlyList<OwnedCardEntry>> EffectiveOwnedCardsAsync(Viewer viewer, CancellationToken ct = default);
|
|
|
|
/// <summary>The cosmetic id-lists + leader-skin catalog/owned-set for /load/index.</summary>
|
|
Task<EffectiveCosmetics> EffectiveCosmeticsAsync(Viewer viewer, CancellationToken ct = default);
|
|
}
|
|
|