Handler.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Abstractions.Paper;
  4. using Application.Helpers;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.Paper.GetMyLeaderboardRank;
  7. /// <summary>
  8. /// 내 리더보드 순위·지표 (인증) — 미등재(등재요건 미달·계좌/스냅샷 없음)면 HasRank=false (d4 M3 리더보드 백엔드 구현).
  9. /// </summary>
  10. internal sealed class Handler(IAppDbContext db, IPaperLeaderboardCache cache) : IQueryHandler<Query, Response>
  11. {
  12. public async Task<Response> Handle(Query request, CancellationToken ct)
  13. {
  14. var sort = PaperLeaderboardMetrics.ParseSort(request.Sort);
  15. var period = PaperLeaderboardMetrics.ParsePeriod(request.Period);
  16. var sortStr = PaperLeaderboardMetrics.SortToString(sort);
  17. var periodStr = PaperLeaderboardMetrics.PeriodToString(period);
  18. var minFillsForRank = await db.Config.AsNoTracking().OrderByDescending(c => c.ID).Select(c => c.Paper.MinFillsForRank).FirstOrDefaultAsync(ct);
  19. if (minFillsForRank <= 0)
  20. {
  21. minFillsForRank = 3;
  22. }
  23. var my = await cache.GetMyRankAsync(sort, period, request.MemberID, db, minFillsForRank, ct);
  24. if (my is null)
  25. {
  26. return new Response(sortStr, periodStr, false, 0, 0, 0, 0, 0, 0);
  27. }
  28. var metrics = await PaperLeaderboardMetrics.ComputeAllAsync(db, period, minFillsForRank, ct);
  29. var metric = metrics.FirstOrDefault(c => c.MemberID == request.MemberID);
  30. return new Response(
  31. sortStr,
  32. periodStr,
  33. true,
  34. my.Rank + 1,
  35. my.Total,
  36. metric?.ReturnBp ?? 0,
  37. metric?.WinRateBp ?? 0,
  38. metric?.MddBp ?? 0,
  39. metric?.FillCount ?? 0);
  40. }
  41. }