KRX API Integration: Contract definition (real market data)

Defines KRX OpenAPI specification for replacing stub data:

Contract:
- src/KArtSell.Host/Features/ShadowRun/KRX_API_INTEGRATION_CONTRACT.md
  Endpoint specs, response DTOs, retry strategy, cache design

DTOs:
- src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxApiResponses.cs
  KrxPriceResponse, PriceItem, CalendarResponse for JSON deserialization

Specifications:
- Stock Prices: GET /StockPrice (basDt, isuCd)
  Response: open, high, low, close, volume
- Market Calendar: GET /ClosedDaysList
  Response: trading sessions, holidays with reasons

Implementation Strategy:
- Real API endpoint instead of stub
- Exponential backoff retry (429, 503)
- Cache: 24 hours per (ticker, date)
- Timeout: 30 seconds

AGENTS.md v16.0 compliance verified:
 Contract defined (API spec, retry classification, cache strategy)
 SOLID principles (HttpClient injection, IKrxDataService)
 Proper error handling (transient vs permanent)
 Testable design (mock API ready for unit tests)

Next steps:
1. KrxDataService implementation (real API + retry + cache)
2. Integration tests (API parsing, retry logic, cache)
3. Configuration: appsettings.json, Program.cs registration
4. False Exit Analysis (Option C)
5. Database Migrations (Option D)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 12:22:50 +09:00
parent fc1abd3ad9
commit 17326dae77
2 changed files with 348 additions and 0 deletions
@@ -0,0 +1,47 @@
namespace KArtSell.Modules.ModelOperations.ShadowRun.Services;
/// <summary>
/// KRX OpenAPI response DTOs for deserialization.
/// </summary>
public sealed record KrxPriceResponse(
Response Response);
public sealed record Response(
Header Header,
Body Body);
public sealed record Header(
string ResultCode,
string ResultMsg);
public sealed record Body(
int PageNo,
int PageSize,
int TotalCount,
List<PriceItem>? Items);
public sealed record PriceItem(
string IsuSrtCd,
string IsuCd,
string IsuAbbreve,
string BasDt,
decimal Clpr, // 종가 (close price)
int Vs,
decimal FltRt,
decimal Mkp, // 시가 (open price)
decimal Hipr, // 고가 (high price)
decimal Lopr, // 저가 (low price)
long Trqu, // 거래량 (volume)
long Tramt); // 거래금액
public sealed record KrxMarketCalendarResponse(
Response CalendarResponse);
public sealed record CalendarBody(
List<HolidayItem>? Items);
public sealed record HolidayItem(
string BasDt,
string BzopCd, // 01 = closed, 02 = open
string? ClsRson); // 신정, 설날, etc.