Handler.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using Application.Abstractions.Messaging;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Cache;
  4. using Application.Abstractions.Crypto;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.Crypto.Ticker.GetAll;
  7. public sealed class Handler(IAppDbContext db, ICacheService cache) : IQueryHandler<Query, Response>
  8. {
  9. public async Task<Response> Handle(Query request, CancellationToken ct)
  10. {
  11. // Redis에서 Ticker 목록 가져오기
  12. var tickers = await cache.GetAsync<List<UpbitTicker>>(CacheKeys.CryptoTickers, ct) ?? [];
  13. var tickerMap = tickers.ToDictionary(t => t.Market, t => t);
  14. // DB에서 코인 정보 가져오기
  15. var coinsQuery = db.Coin
  16. .AsNoTracking()
  17. .Where(c => c.IsActive && !c.IsDelisted);
  18. if (request.FeaturedOnly)
  19. {
  20. coinsQuery = coinsQuery.Where(c => c.IsFeatured);
  21. }
  22. var coins = await coinsQuery
  23. .OrderByDescending(c => c.IsFeatured)
  24. .ThenBy(c => c.DisplayOrder)
  25. .ThenBy(c => c.Symbol)
  26. .Select(c => new
  27. {
  28. c.Symbol,
  29. c.KorName,
  30. c.EngName,
  31. c.LogoImage,
  32. c.IsFeatured,
  33. c.DisplayOrder
  34. })
  35. .ToListAsync(ct);
  36. var rows = new List<Response.Row>();
  37. foreach (var coin in coins)
  38. {
  39. var market = $"KRW-{coin.Symbol.ToUpper()}";
  40. tickerMap.TryGetValue(market, out var ticker);
  41. rows.Add(new Response.Row(
  42. coin.Symbol,
  43. coin.KorName,
  44. coin.EngName,
  45. coin.LogoImage,
  46. ticker?.TradePrice ?? 0m,
  47. ticker?.Change ?? "",
  48. ticker?.SignedChangePrice ?? 0m,
  49. ticker?.SignedChangeRate ?? 0m,
  50. ticker?.AccTradePrice24h ?? 0m,
  51. coin.IsFeatured,
  52. coin.DisplayOrder
  53. ));
  54. }
  55. return new Response(rows);
  56. }
  57. }