using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Stocks.GetDetail; internal sealed class Handler(IAppDbContext db) : IQueryHandler> { private const int RecentPriceCount = 30; public async Task> Handle(Query request, CancellationToken ct) { var stock = await db.Stock.AsNoTracking().FirstOrDefaultAsync(c => c.Code == request.Code, ct); if (stock is null) { return Result.Failure(Error.NotFound("Stock.NotFound", "종목을 찾을 수 없습니다.")); } var prices = await db.StockDailyPrice.AsNoTracking() .Where(c => c.StockID == stock.ID) .OrderByDescending(c => c.TradingDate) .Take(RecentPriceCount) .Select(c => new Response.PriceRow { TradingDate = c.TradingDate, Open = c.Open, High = c.High, Low = c.Low, Close = c.Close, Volume = c.Volume, TradingValue = c.TradingValue, ChangeAmount = c.ChangeAmount, ChangeRate = c.ChangeRate }) .ToListAsync(ct); return new Response { Code = stock.Code, ISIN = stock.ISIN, Name = stock.Name, EnglishName = stock.EnglishName, Market = stock.Market.ToString(), TradingStatus = stock.TradingStatus.ToString(), SectorName = stock.SectorName, IsActive = stock.IsActive, ListedDate = stock.ListedDate, DelistedDate = stock.DelistedDate, LastTradingDate = stock.LastTradingDate, ClosePrice = stock.LastClosePrice, ChangeRate = stock.LastChangeRate, MarketCap = stock.MarketCap, RecentPrices = prices }; } }