V13-FE-011: finalize search list layout slice
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
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)
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user