feat(matching): MatchContextBuilder.BuildForRankBattleAsync for rank battles

Sibling to BuildForTwoPickAsync. Routes through IDeckRepository.GetDeck
to pull the viewer's deck #1 for the requested format (avoiding the
viewer-graph nav-ref auto-load pitfall — DeckCard.Card silently ships
card_id=0 via the default include path). Throws if the viewer has no
deck for the format. Cosmetics fall back to DefaultLoadoutConfig
defaults when unequipped, same shape as TK2.

Used by RankBattleController in a later task to build self-context for
/ai_<fmt>_rank_battle/start and to pair-up under /<fmt>_rank_battle/do_matching.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-02 01:13:19 -04:00
parent b65cf81977
commit 7eaf13893e
3 changed files with 95 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
using SVSim.BattleNode.Bridge;
using SVSim.Database.Enums;
namespace SVSim.EmulatedEntrypoint.Services;
@@ -15,4 +16,15 @@ public interface IMatchContextBuilder
/// Throws <see cref="ArenaTwoPickException"/> on missing run / incomplete draft.
/// </summary>
Task<MatchContext> BuildForTwoPickAsync(long viewerId);
/// <summary>
/// Build a context for a rank-battle viewer + format (rotation / unlimited). Pulls the
/// viewer's deck #1 for that format + viewer cosmetics. Throws if the viewer has no
/// deck registered for the format.
/// </summary>
/// <remarks>
/// Deck-selection persistence (which deck number is "current" for this format) is a
/// separate concern; deck #1 is a placeholder until that lands.
/// </remarks>
Task<MatchContext> BuildForRankBattleAsync(long viewerId, Format format);
}