using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Stocks.GetQuotes; /// 경량 배치 시세 — 코드/종가/등락률만, 최대 50개 (d0 §3-D, D1 소유). Stock denorm 만 읽어 조인 없음. internal sealed class Handler(IAppDbContext db) : IQueryHandler> { public const int MaxCodes = 50; public async Task> 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(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 }; } }