using Application.Abstractions.Crypto; using Application.Abstractions.Data; using Domain.Entities.Common; using Microsoft.EntityFrameworkCore; namespace Infrastructure.StockData; /// /// 구현 — DB Config(DataCollection) 를 1회 로드해 캐시하고 /// 플래그/키를 해석한다. 키는 EncryptedConfigValue 로 복호화(레거시 평문은 통과). Scoped 등록. /// internal sealed class CollectorSettingsProvider(IAppDbContext db, IFieldEncryptor encryptor) : ICollectorSettingsProvider { private DataCollectionConfig? _loaded; private bool _hasConfig; private async Task EnsureLoadedAsync(CancellationToken ct) { if (_loaded is not null) { return; } var config = await db.Config.AsNoTracking().OrderByDescending(c => c.ID).FirstOrDefaultAsync(ct); _hasConfig = config is not null; _loaded = config?.DataCollection ?? new DataCollectionConfig(); } public async Task IsEnabledAsync(CollectorFlag flag, CancellationToken ct) { await EnsureLoadedAsync(ct); if (!_hasConfig) { return false; } var c = _loaded!; return flag switch { CollectorFlag.StockDataMaster => c.StockDataMasterSync, CollectorFlag.StockDataDailyPrice => c.StockDataDailyPriceSync, CollectorFlag.KrxIndex => c.KrxIndexSync, CollectorFlag.KrxBondIndex => c.KrxBondIndexSync, CollectorFlag.KrxStock => c.KrxStockSync, CollectorFlag.KrxEtp => c.KrxEtpSync, CollectorFlag.KrxWarrant => c.KrxWarrantSync, CollectorFlag.KrxBond => c.KrxBondSync, CollectorFlag.KrxDerivative => c.KrxDerivativeSync, CollectorFlag.KrxCommodity => c.KrxCommoditySync, CollectorFlag.KrxEsg => c.KrxEsgSync, CollectorFlag.OpenDartDisclosure => c.OpenDartDisclosureSync, CollectorFlag.KoreaEximMacro => c.KoreaEximMacroSync, CollectorFlag.Kosis => c.KosisSync, CollectorFlag.WorldIndex => c.WorldIndexEnabled, CollectorFlag.MarketQuote => c.MarketQuoteEnabled, CollectorFlag.SeibroIssuer => c.SeibroIssuerSync, CollectorFlag.SeibroDividend => c.SeibroDividendSync, CollectorFlag.SeibroSupply => c.SeibroSupplySync, CollectorFlag.SeibroCorpAction => c.SeibroCorpActionSync, CollectorFlag.SeibroBond => c.SeibroBondSync, CollectorFlag.SeibroDeriv => c.SeibroDerivSync, CollectorFlag.SeibroForeign => c.SeibroForeignSync, _ => false }; } public async Task GetKeyAsync(CollectorKey key, CancellationToken ct) { await EnsureLoadedAsync(ct); var c = _loaded!; var enc = key switch { CollectorKey.DataGoKr => c.DataGoKrServiceKeyEnc, CollectorKey.Krx => c.KrxApiKeyEnc, CollectorKey.OpenDart => c.OpenDartApiKeyEnc, CollectorKey.KoreaEximExchange => c.KoreaEximExchangeKeyEnc, CollectorKey.KoreaEximLoanRate => c.KoreaEximLoanRateKeyEnc, CollectorKey.KoreaEximIntlRate => c.KoreaEximIntlRateKeyEnc, CollectorKey.Seibro => c.SeibroApiKeyEnc, CollectorKey.Kosis => c.KosisApiKeyEnc, _ => null }; return string.IsNullOrWhiteSpace(enc) ? null : EncryptedConfigValue.Unprotect(encryptor, enc); } }