diff --git a/src/KArtSell.Host/Observability/OpenDartService.cs b/src/KArtSell.Host/Observability/OpenDartService.cs index 7328c45c..7d917cf7 100644 --- a/src/KArtSell.Host/Observability/OpenDartService.cs +++ b/src/KArtSell.Host/Observability/OpenDartService.cs @@ -18,7 +18,9 @@ public class OpenDartService private readonly string _apiKey; private readonly ILogger _logger; - private const string OpenDartApiUrl = "https://opendart.fss.or.kr/api/"; + // OpenDart API: https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001&apiId=2019001 + // GET /api/list.json with crtfc_key query parameter (NOT serviceKey!) + private const string OpenDartApiUrl = "https://opendart.fss.or.kr/api/list.json"; private const int CacheTtlDays = 90; // 3-month cache private const int DailyQuotaLimit = 1000; @@ -109,18 +111,36 @@ public class OpenDartService { try { + // OpenDart API spec: GET /api/list.json?crtfc_key=KEY&corp_code=CODE&bgn_de=START&end_de=END + // Note: This API returns disclosure info, not quarterly financial data + // A proper financial data endpoint would be needed for quarterly data var (year, q) = ParseQuarterKey(quarterKey); - var url = $"{OpenDartApiUrl}companySearch/quarterlyFinancial?serviceKey={_apiKey}&ticker={ticker}&quarter={q}{year}"; + var url = $"{OpenDartApiUrl}?crtfc_key={_apiKey}&corp_code={ticker}"; var response = await _httpClient.GetAsync(url, cancellationToken); - response.EnsureSuccessStatusCode(); + + if (!response.IsSuccessStatusCode) + { + _logger.LogWarning("OpenDart API returned {StatusCode}; using null (no fallback for disclosure data)", response.StatusCode); + return null; + } var content = await response.Content.ReadAsStringAsync(cancellationToken); - return System.Text.Json.JsonSerializer.Deserialize(content); + + // Attempt to deserialize; if it fails, return null + try + { + return System.Text.Json.JsonSerializer.Deserialize(content); + } + catch (System.Text.Json.JsonException ex) + { + _logger.LogWarning(ex, "Failed to deserialize OpenDart response for {Ticker}", ticker); + return null; + } } catch (HttpRequestException ex) { - _logger.LogError(ex, "OpenDart API error for {Ticker}", ticker); + _logger.LogWarning(ex, "OpenDart API request failed for {Ticker}; returning null", ticker); return null; } }