| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- namespace SharedKernel;
- public sealed class AppSettings
- {
- public AppSection App { get; init; } = new();
- public ConnectionStringsSection ConnectionStrings { get; init; } = new();
- public RedisSection Redis { get; init; } = new();
- public SmtpSection SMTP { get; init; } = new();
- public JwtSection JWT { get; init; } = new();
- public ForwardedHeadersSection ForwardedHeaders { get; init; } = new();
- public CorsPolicySection CorsPolicy { get; init; } = new();
- public YouTubeSection YouTube { get; init; } = new();
- public BackgroundJobsSection BackgroundJobs { get; init; } = new();
- public EncryptionSection Encryption { get; init; } = new();
- public FeaturesSection Features { get; init; } = new();
- public StockDataSection StockData { get; init; } = new();
- public OAuthSection OAuth { get; init; } = new();
- public sealed class AppSection
- {
- public string Name { get; init; } = string.Empty;
- public string Company { get; init; } = string.Empty;
- public string BaseURL { get; init; } = string.Empty;
- public string ApiURL { get; init; } = string.Empty;
- public string FrontURL { get; init; } = string.Empty;
- }
- public sealed class ConnectionStringsSection
- {
- public string DefaultConnection { get; init; } = string.Empty;
- public int Timeout { get; init; }
- }
- public class RedisSection
- {
- public string DefaultConnection { get; init; } = string.Empty;
- public string CachePrefix { get; init; } = string.Empty;
- public string AuthTicketPrefix { get; init; } = string.Empty;
- public string DataProtectionKey { get; init; } = string.Empty;
- public TimeSpan DefaultKeyLifetime { get; init; }
- }
- public class SmtpSection
- {
- public string Host { get; init; } = default!;
- public int Port { get; init; } = 587;
- public string? User { get; init; }
- public string? Password { get; init; }
- public bool UseStartTls { get; init; } = true;
- public string FromEmail { get; init; } = default!;
- public string FromName { get; init; } = "no-reply";
- }
- public class JwtSection
- {
- public string SecretKey { get; init; } = string.Empty;
- public string Issuer { get; init; } = string.Empty;
- public string Audience { get; init; } = string.Empty;
- public int AccessTokenExpiration { get; init; }
- public int RefreshTokenExpiration { get; init; }
- }
- public class ForwardedHeadersSection
- {
- public int? ForwardLimit { get; init; } = default;
- public List<string> KnownProxies { get; init; } = [];
- public List<string> KnownNetworks { get; init; } = [];
- }
- public class CorsPolicySection
- {
- public string Name { get; init; } = string.Empty;
- public long PreflightMaxAgeSeconds { get; init; } = 0;
- public List<string> AllowedOrigins { get; init; } = [];
- }
- public class YouTubeSection
- {
- public string HubUrl { get; init; } = "https://pubsubhubbub.appspot.com/subscribe";
- public string CallbackUrl { get; init; } = string.Empty;
- public string HmacSecret { get; init; } = string.Empty;
- public int FeedPollingIntervalMinutes { get; init; } = 3;
- }
- public class BackgroundJobsSection
- {
- public bool LiveChat { get; init; } = true;
- public bool PubSubRenewal { get; init; } = true;
- public bool FeedPolling { get; init; } = true;
- public bool LiveViewerPoller { get; init; } = true;
- public bool ChannelCacheRefresh { get; init; } = true;
- public bool YouTubeDailyAggregator { get; init; } = true;
- public bool YouTubeStaleDataPurge { get; init; } = true;
- }
- /// <summary>
- /// 기능 단위 활성화 플래그. 코드/스키마는 보존하고 노출만 차단하는 soft-off 스위치.
- /// Channel=false 시 채널/스튜디오/YouTube 관련 API 와 백그라운드 서비스 전체 비활성 (기본 false).
- /// </summary>
- public class FeaturesSection
- {
- public bool Channel { get; init; } = false;
- }
- /// <summary>
- /// 회원 PII(주소/연락처 등) 필드 암호화에 사용하는 AES-GCM 키 묶음.
- /// Keys 딕셔너리는 KeyVersion -> Base64(32바이트) 매핑. CurrentKeyVersion 은 신규 암호화에 사용할 버전.
- /// 키 회전 시 Keys 에 새 버전 추가 + CurrentKeyVersion 갱신. 복호화는 row 의 KeyVersion 컬럼으로 매핑하여 과거 키 사용.
- /// </summary>
- public class EncryptionSection
- {
- public int CurrentKeyVersion { get; init; } = 1;
- public Dictionary<string, string> Keys { get; init; } = new();
- }
- /// <summary>
- /// 소셜 로그인 OAuth 설정 (개미투자 D5 — Naver/Kakao). 키는 각 개발자센터 발급 후 채움 (빈 값이면 해당 provider 로그인 비활성).
- /// Google 은 DB Config(External.GoogleClientId) 현행 유지 — 여기 포함하지 않는다.
- /// </summary>
- public class OAuthSection
- {
- public OAuthProviderSection Naver { get; init; } = new();
- public OAuthProviderSection Kakao { get; init; } = new();
- public class OAuthProviderSection
- {
- /// <summary>네이버: Client ID / 카카오: REST API 키</summary>
- public string ClientId { get; init; } = string.Empty;
- /// <summary>네이버: Client Secret(필수) / 카카오: 콘솔에서 활성화한 경우만 (빈 값이면 미전송)</summary>
- public string ClientSecret { get; init; } = string.Empty;
- /// <summary>기본 redirect URI — 요청에서 미전달 시 사용. 개발자센터에 등록한 값과 일치해야 함</summary>
- public string RedirectUri { get; init; } = string.Empty;
- }
- }
- /// <summary>
- /// 주식 데이터 수집 배치 설정 (개미투자 D1). 플래그 기본 false — API 키 발급/운영 결정 후 활성화.
- /// Features:Channel 게이트와 무관하게 별도 등록 (AddStockDataServices).
- /// </summary>
- public class StockDataSection
- {
- /// <summary>종목 마스터 동기화 배치 (StockMasterSyncService) 활성화</summary>
- public bool MasterSync { get; init; } = false;
- /// <summary>T+1 일별 시세 수집 배치 (DailyPriceSyncService) 활성화</summary>
- public bool DailyPriceSync { get; init; } = false;
- /// <summary>마스터 동기화 실행 시각 (KST, "HH:mm")</summary>
- public string MasterSyncTime { get; init; } = "07:30";
- /// <summary>일별 시세 수집 실행 시각 (KST, "HH:mm") — 금융위 API 는 영업일+1 13시 이후 반영</summary>
- public string DailyPriceSyncTime { get; init; } = "13:10";
- public DataGoKrSection DataGoKr { get; init; } = new();
- /// <summary>공공데이터포털 (data.go.kr) 금융위 API</summary>
- public class DataGoKrSection
- {
- /// <summary>서비스 키 (Decoding 원본 키 — 요청 시 URL 인코딩). 비어 있으면 배치는 로그만 남기고 skip.</summary>
- public string ServiceKey { get; init; } = string.Empty;
- public string BaseUrl { get; init; } = "https://apis.data.go.kr";
- /// <summary>페이지당 행 수 (numOfRows)</summary>
- public int PageSize { get; init; } = 1000;
- }
- }
- }
|