| 123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- namespace Application.Features.Api.Stocks.GetQuotes;
- /// <summary>경량 배치 시세 — 코드/종가/등락률만, 최대 50개 (d0 §3-D, D1 소유). Stock denorm 만 읽어 조인 없음.</summary>
- internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
- {
- public const int MaxCodes = 50;
- public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
- {
- var codes = request.Codes.Where(c => !string.IsNullOrWhiteSpace(c)).Select(c => c.Trim()).Distinct().ToList();
- if (codes.Count == 0)
- {
- return new Response
- {
- List = []
- };
- }
- if (codes.Count > MaxCodes)
- {
- return Result.Failure<Response>(Error.Problem("Stock.TooManyCodes", $"코드는 최대 {MaxCodes}개까지 조회할 수 있습니다."));
- }
- var list = await db.Stock.AsNoTracking()
- .Where(c => codes.Contains(c.Code))
- .Select(c => new Response.Row
- {
- Code = c.Code,
- ClosePrice = c.LastClosePrice,
- ChangeRate = c.LastChangeRate
- })
- .ToListAsync(ct);
- return new Response
- {
- List = list
- };
- }
- }
|