feat(replay): add ReplayHistoryReader for newest-first list query

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-10 07:48:18 -04:00
parent 2b6c7bd6a4
commit 86d86f6ead
4 changed files with 62 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
namespace SVSim.Database.Services.Replay;
public interface IReplayHistoryReader
{
/// <summary>Newest-first by CreateTime. Caps at <paramref name="take"/> (default 50).</summary>
Task<IReadOnlyList<ReplayHistoryEntry>> GetRecentAsync(long viewerId, int take, CancellationToken ct);
}

View File

@@ -0,0 +1,27 @@
namespace SVSim.Database.Services.Replay;
/// <summary>
/// Read-side row returned by <see cref="IReplayHistoryReader"/>. The /replay/info
/// controller maps this to its wire DTO (all-stringified per prod capture).
/// </summary>
public sealed record ReplayHistoryEntry(
long BattleId,
int BattleType,
int DeckFormat,
int TwoPickType,
int IsLimitTurn,
int SelfClassId,
int SelfSubClassId,
int SelfCharaId,
string SelfRotationId,
int OpponentClassId,
int OpponentSubClassId,
int OpponentCharaId,
string OpponentName,
string OpponentCountryCode,
long OpponentEmblemId,
long OpponentDegreeId,
string OpponentRotationId,
bool IsWin,
DateTime BattleStartTime,
DateTime CreateTime);

View File

@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
namespace SVSim.Database.Services.Replay;
public sealed class ReplayHistoryReader : IReplayHistoryReader
{
private readonly SVSimDbContext _db;
public ReplayHistoryReader(SVSimDbContext db) => _db = db;
public async Task<IReadOnlyList<ReplayHistoryEntry>> GetRecentAsync(long viewerId, int take, CancellationToken ct)
{
return await _db.ViewerBattleHistories
.AsNoTracking()
.Where(h => h.ViewerId == viewerId)
.OrderByDescending(h => h.CreateTime)
.Take(take)
.Select(h => new ReplayHistoryEntry(
h.BattleId, h.BattleType, h.DeckFormat, h.TwoPickType, h.IsLimitTurn,
h.SelfClassId, h.SelfSubClassId, h.SelfCharaId, h.SelfRotationId,
h.OpponentClassId, h.OpponentSubClassId, h.OpponentCharaId,
h.OpponentName, h.OpponentCountryCode,
h.OpponentEmblemId, h.OpponentDegreeId, h.OpponentRotationId,
h.IsWin, h.BattleStartTime, h.CreateTime))
.ToListAsync(ct);
}
}