using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Domain.Entities.Stocks.ValueObject;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.Api.Stocks.GetIndices;
///
/// 대표 시장지수 — 최신 거래일의 코스피/코스닥(+KRX 100)만 반환 (헤더 티커 + /market, d0 §3-D).
/// 지수명이 정확히 대표명과 일치하는 행만 취하고, 계열 순서(KOSPI→KOSDAQ→KRX)로 정렬한다.
///
internal sealed class Handler(IAppDbContext db) : IQueryHandler
{
// (계열, 대표 지수명) — KRX OpenAPI IDX_NM 기준
private static readonly (MarketIndexSeries Series, string Name)[] KeyIndices =
[
(MarketIndexSeries.KOSPI, "코스피"),
(MarketIndexSeries.KOSDAQ, "코스닥"),
(MarketIndexSeries.KRX, "KRX 100")
];
public async Task Handle(Query request, CancellationToken ct)
{
var latest = await db.IndexDailyPrice.AsNoTracking().OrderByDescending(c => c.TradeDate).Select(c => (DateOnly?)c.TradeDate).FirstOrDefaultAsync(ct);
if (latest is null)
{
return new Response
{
List = []
};
}
var names = KeyIndices.Select(c => c.Name).ToArray();
var rows = await db.IndexDailyPrice.AsNoTracking()
.Where(c => c.TradeDate == latest.Value && names.Contains(c.IndexName))
.Select(c => new Response.Row
{
Series = c.Series,
Name = c.IndexName,
Close = c.Close,
ChangeVal = c.ChangeVal,
FlucRateBp = c.FlucRateBp,
TradeDate = c.TradeDate
})
.ToListAsync(ct);
// 대표 지수명 순서(KOSPI→KOSDAQ→KRX)로 정렬
var ordered = KeyIndices
.Select(k => rows.FirstOrDefault(r => r.Series == k.Series && r.Name == k.Name))
.Where(r => r is not null)
.Select(r => r!)
.ToList();
return new Response
{
List = ordered
};
}
}