Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/backend/Shared/Providers/OpenDartAdapter.cs
T

49 lines
3.3 KiB
C#

using System.Text.Json;
namespace Kbx.Shared.Providers;
public sealed class OpenDartAdapter(HttpClient http, IKbxProviderSecretStore secrets) : IKbxExternalProviderAdapter
{
private static readonly Uri BaseUri = new("https://opendart.fss.or.kr/api/");
public string ProviderId => "provider.opendart";
public Task<KbxProviderResult<JsonDocument>> GetDisclosuresAsync(IReadOnlyDictionary<string,string?> query, CancellationToken ct)
=> GetJsonAsync("list.json", query, ct);
public Task<KbxProviderResult<JsonDocument>> GetCompanyAsync(string corpCode, CancellationToken ct)
=> GetJsonAsync("company.json", new Dictionary<string,string?> { ["corp_code"] = corpCode }, ct);
public async Task<KbxProviderResult<byte[]>> DownloadCorpCodeAsync(CancellationToken ct)
{
var key = await secrets.GetRequiredAsync("ExternalProviders:OpenDart:ApiKey", ct);
var uri = new Uri(BaseUri, $"corpCode.xml?crtfc_key={Uri.EscapeDataString(key)}");
using var response = await http.GetAsync(uri, ct);
var bytes = await response.Content.ReadAsByteArrayAsync(ct);
if (response.IsSuccessStatusCode) return new(KbxProviderResultKind.Success, bytes, HttpStatus:(int)response.StatusCode);
return new((int)response.StatusCode >= 500 ? KbxProviderResultKind.TransientFailure : KbxProviderResultKind.PermanentFailure, Code:$"HTTP_{(int)response.StatusCode}", Message:"OPENDART 고유번호 파일 호출 실패", HttpStatus:(int)response.StatusCode);
}
private async Task<KbxProviderResult<JsonDocument>> GetJsonAsync(string path, IReadOnlyDictionary<string,string?> query, CancellationToken ct)
{
var key = await secrets.GetRequiredAsync("ExternalProviders:OpenDart:ApiKey", ct);
var pairs = new List<string> { $"crtfc_key={Uri.EscapeDataString(key)}" };
pairs.AddRange(query.Where(x=>x.Value is not null).Select(x=>$"{Uri.EscapeDataString(x.Key)}={Uri.EscapeDataString(x.Value!)}"));
var uri = new Uri(BaseUri, path + "?" + string.Join("&", pairs));
using var response = await http.GetAsync(uri, ct);
var text = await response.Content.ReadAsStringAsync(ct);
if (!response.IsSuccessStatusCode)
return new((int)response.StatusCode >= 500 || (int)response.StatusCode == 429 ? KbxProviderResultKind.TransientFailure : KbxProviderResultKind.PermanentFailure, Code:$"HTTP_{(int)response.StatusCode}", Message:"OPENDART HTTP 호출 실패", HttpStatus:(int)response.StatusCode);
JsonDocument doc;
try { doc = JsonDocument.Parse(text); } catch { return new(KbxProviderResultKind.PermanentFailure, Code:"DART_INVALID_JSON", Message:"OPENDART 응답 JSON을 해석할 수 없습니다."); }
var root = doc.RootElement;
var status = root.TryGetProperty("status", out var s) ? s.GetString() : null;
var message = root.TryGetProperty("message", out var m) ? m.GetString() : null;
return status switch
{
"000" or null => new(KbxProviderResultKind.Success, doc),
"013" => new(KbxProviderResultKind.NoData, doc, status, message),
"020" or "800" or "900" => new(KbxProviderResultKind.TransientFailure, doc, status, message),
_ => new(KbxProviderResultKind.PermanentFailure, doc, status, message)
};
}
}