| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Domain.Entities.Stocks.ValueObject;
- using Microsoft.EntityFrameworkCore;
- namespace Application.Features.Api.Stocks.GetIndices;
- /// <summary>
- /// 대표 시장지수 — 최신 거래일의 코스피/코스닥(+KRX 100)만 반환 (헤더 티커 + /market, d0 §3-D).
- /// 지수명이 정확히 대표명과 일치하는 행만 취하고, 계열 순서(KOSPI→KOSDAQ→KRX)로 정렬한다.
- /// </summary>
- internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
- {
- // (계열, 대표 지수명) — KRX OpenAPI IDX_NM 기준
- private static readonly (MarketIndexSeries Series, string Name)[] KeyIndices =
- [
- (MarketIndexSeries.KOSPI, "코스피"),
- (MarketIndexSeries.KOSDAQ, "코스닥"),
- (MarketIndexSeries.KRX, "KRX 100")
- ];
- public async Task<Response> 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
- };
- }
- }
|