Handler.cs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. using SharedKernel.Results;
  5. namespace Application.Features.Api.Stocks.GetQuotes;
  6. /// <summary>경량 배치 시세 — 코드/종가/등락률만, 최대 50개 (d0 §3-D, D1 소유). Stock denorm 만 읽어 조인 없음.</summary>
  7. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  8. {
  9. public const int MaxCodes = 50;
  10. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  11. {
  12. var codes = request.Codes.Where(c => !string.IsNullOrWhiteSpace(c)).Select(c => c.Trim()).Distinct().ToList();
  13. if (codes.Count == 0)
  14. {
  15. return new Response
  16. {
  17. List = []
  18. };
  19. }
  20. if (codes.Count > MaxCodes)
  21. {
  22. return Result.Failure<Response>(Error.Problem("Stock.TooManyCodes", $"코드는 최대 {MaxCodes}개까지 조회할 수 있습니다."));
  23. }
  24. var list = await db.Stock.AsNoTracking()
  25. .Where(c => codes.Contains(c.Code))
  26. .Select(c => new Response.Row
  27. {
  28. Code = c.Code,
  29. ClosePrice = c.LastClosePrice,
  30. ChangeRate = c.LastChangeRate
  31. })
  32. .ToListAsync(ct);
  33. return new Response
  34. {
  35. List = list
  36. };
  37. }
  38. }