Config.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. namespace Domain.Entities.Common;
  2. public sealed class Config
  3. {
  4. public int ID { get; private set; }
  5. public DateTime LastUpdatedAt { get; private set; } = DateTime.UtcNow;
  6. public byte[] RowVersion { get; private set; } = [];
  7. public BasicConfig Basic { get; private set; } = new();
  8. public ImagesConfig Images { get; private set; } = new();
  9. public MetaConfig Meta { get; private set; } = new();
  10. public CompanyConfig Company { get; private set; } = new();
  11. public AccountConfig Account { get; private set; } = new();
  12. public EmailTemplateConfig EmailTemplate { get; private set; } = new();
  13. public ExternalApiConfig External { get; private set; } = new();
  14. public CryptoConfig Crypto { get; private set; } = new();
  15. public AttendanceConfig Attendance { get; private set; } = new();
  16. public SignupRewardConfig SignupReward { get; private set; } = new();
  17. public RewardConfig Reward { get; private set; } = new();
  18. public ChatExpConfig ChatExp { get; private set; } = new();
  19. public PaperConfig Paper { get; private set; } = new();
  20. public DataCollectionConfig DataCollection { get; private set; } = new();
  21. private Config() { }
  22. public static Config Create()
  23. {
  24. return new();
  25. }
  26. public void Update(
  27. BasicConfig basic,
  28. ImagesConfig images,
  29. MetaConfig meta,
  30. CompanyConfig company,
  31. AccountConfig account,
  32. EmailTemplateConfig emailTemplate,
  33. ExternalApiConfig external,
  34. CryptoConfig crypto,
  35. AttendanceConfig attendance,
  36. SignupRewardConfig signupReward
  37. ) {
  38. Basic = basic ?? throw new ArgumentNullException(nameof(basic));
  39. Images = images ?? throw new ArgumentNullException(nameof(images));
  40. Meta = meta ?? throw new ArgumentNullException(nameof(meta));
  41. Company = company ?? throw new ArgumentNullException(nameof(company));
  42. Account = account ?? throw new ArgumentNullException(nameof(account));
  43. EmailTemplate = emailTemplate ?? throw new ArgumentNullException(nameof(emailTemplate));
  44. External = external ?? throw new ArgumentNullException(nameof(external));
  45. Crypto = crypto ?? throw new ArgumentNullException(nameof(crypto));
  46. Attendance = attendance ?? throw new ArgumentNullException(nameof(attendance));
  47. SignupReward = signupReward ?? throw new ArgumentNullException(nameof(signupReward));
  48. LastUpdatedAt = DateTime.UtcNow;
  49. }
  50. public void UpdateChatExp(ChatExpConfig chatExp)
  51. {
  52. ChatExp = chatExp ?? throw new ArgumentNullException(nameof(chatExp));
  53. LastUpdatedAt = DateTime.UtcNow;
  54. }
  55. public void UpdateReward(RewardConfig reward)
  56. {
  57. Reward = reward ?? throw new ArgumentNullException(nameof(reward));
  58. LastUpdatedAt = DateTime.UtcNow;
  59. }
  60. public void UpdatePaper(PaperConfig paper)
  61. {
  62. Paper = paper ?? throw new ArgumentNullException(nameof(paper));
  63. LastUpdatedAt = DateTime.UtcNow;
  64. }
  65. public void UpdateDataCollection(DataCollectionConfig dataCollection)
  66. {
  67. DataCollection = dataCollection ?? throw new ArgumentNullException(nameof(dataCollection));
  68. LastUpdatedAt = DateTime.UtcNow;
  69. }
  70. }
  71. #region Owned Groups
  72. // ==================================================
  73. // 기본 정보 (Basic)
  74. // ==================================================
  75. public sealed class BasicConfig
  76. {
  77. public string? SiteName { get; set; }
  78. public string? SiteURL { get; set; }
  79. public string? RootID { get; set; }
  80. public string? FromEmail { get; set; }
  81. public string? FromName { get; set; }
  82. public string? SmtpServer { get; set; }
  83. public int? SmtpPort { get; set; }
  84. public bool SmtpEnableSSL { get; set; }
  85. public string? SmtpUsername { get; set; }
  86. public string? SmtpPassword { get; set; }
  87. public string? AdminWhiteIPList { get; set; }
  88. public string? FrontWhiteIPList { get; set; }
  89. public string? BlockAlertTitle { get; set; }
  90. public string? BlockAlertContent { get; set; }
  91. public bool IsMaintenance { get; set; } = false;
  92. public string? MaintenanceContent { get; set; }
  93. /// <summary>쪽지 일일 발송 제한 (사용자 1인당 / 시스템 쪽지 제외). 0 = 발송 차단</summary>
  94. public int NoteDailySendLimit { get; set; } = 3;
  95. }
  96. // ==================================================
  97. // 기본 이미지 (Images)
  98. // ==================================================
  99. public sealed class ImagesConfig
  100. {
  101. public string? Favicon { get; set; }
  102. public string? LogoSquare { get; set; }
  103. public string? LogoHorizontal { get; set; }
  104. public string? OgDefault { get; set; }
  105. public string? TwitterImage { get; set; }
  106. public string? AppleTouchIcon { get; set; }
  107. public string? AppIcon_192 { get; set; }
  108. public string? AppIcon_512 { get; set; }
  109. }
  110. // ==================================================
  111. // 메타 태그 (Meta)
  112. // ==================================================
  113. public sealed class MetaConfig
  114. {
  115. public string? Keywords { get; set; }
  116. public string? Description { get; set; }
  117. public string? Author { get; set; }
  118. public string? Viewport { get; set; }
  119. public string? ApplicationName { get; set; }
  120. public string? Generator { get; set; }
  121. public string? Robots { get; set; }
  122. public string? Adds { get; set; }
  123. }
  124. // ==================================================
  125. // 회사 정보 (Company)
  126. // ==================================================
  127. public sealed class CompanyConfig
  128. {
  129. public string? Name { get; set; }
  130. public string? RegNo { get; set; }
  131. public string? Address { get; set; }
  132. public string? ZipCode { get; set; }
  133. public string? Owner { get; set; }
  134. public string? Tel { get; set; }
  135. public string? Fax { get; set; }
  136. public string? RetailSaleNo { get; set; }
  137. public string? AddedSaleNo { get; set; }
  138. public string? Hosting { get; set; }
  139. public string? AdminName { get; set; }
  140. public string? AdminEmail { get; set; }
  141. public string? SiteUrl { get; set; }
  142. public string? BankCode { get; set; }
  143. public string? BankOwner { get; set; }
  144. public string? BankNumber { get; set; }
  145. }
  146. // ==================================================
  147. // 회원가입 설정 (Account)
  148. // ==================================================
  149. public sealed class AccountConfig
  150. {
  151. // 회원 가입 시
  152. public bool IsRegisterBlock { get; set; } = false;
  153. public bool IsRegisterEmailAuth { get; set; } = false;
  154. public ushort? PasswordMinLength { get; set; }
  155. public ushort? PasswordUppercaseLength { get; set; }
  156. public ushort? PasswordNumbersLength { get; set; }
  157. public ushort? PasswordSpecialcharsLength { get; set; }
  158. public string? DeniedEmailList { get; set; }
  159. public string? DeniedNameList { get; set; }
  160. // 회원 수정 시 — 프로필(닉네임·한마디·이미지) 기본 90일 쿨다운 (변경권 아이템으로 우회 — Wave 3 P3)
  161. public ushort? ChangeEmailDay { get; set; }
  162. public ushort? ChangeNameDay { get; set; } = 90;
  163. public ushort? ChangeSummaryDay { get; set; }
  164. public ushort? ChangeIntroDay { get; set; } = 90;
  165. public ushort? ChangeThumbDay { get; set; } = 90;
  166. public ushort? ChangePasswordDay { get; set; }
  167. // 로그인 시
  168. public bool IsLoginEmailVerifiedOnly { get; set; } = false;
  169. public ushort? MaxLoginTryCount { get; set; }
  170. public ushort? MaxLoginTryLimitSecond { get; set; }
  171. }
  172. // ==================================================
  173. // 알림 발송 양식 - 이메일 (EmailTemplate)
  174. // ==================================================
  175. public sealed class EmailTemplateConfig
  176. {
  177. public string? RegisterEmailFormTitle { get; set; }
  178. public string? RegisterEmailFormContent { get; set; }
  179. public string? RegistrationEmailFormTitle { get; set; }
  180. public string? RegistrationEmailFormContent { get; set; }
  181. public string? ResetPasswordEmailFormTitle { get; set; }
  182. public string? ResetPasswordEmailFormContent { get; set; }
  183. public string? ChangedPasswordEmailFormTitle { get; set; }
  184. public string? ChangedPasswordEmailFormContent { get; set; }
  185. public string? WithdrawEmailFormTitle { get; set; }
  186. public string? WithdrawEmailFormContent { get; set; }
  187. public string? WithdrawVerifyEmailFormTitle { get; set; }
  188. public string? WithdrawVerifyEmailFormContent { get; set; }
  189. public string? EmailVerifyFormTitle { get; set; }
  190. public string? EmailVerifyFormContent { get; set; }
  191. public string? ChangedEmailFormTitle { get; set; }
  192. public string? ChangedEmailFormContent { get; set; }
  193. }
  194. // ==================================================
  195. // 외부 API 설정 (External)
  196. // ==================================================
  197. public sealed class ExternalApiConfig
  198. {
  199. /** YouTube **/
  200. public string? YouTubeApiKeyEnc { get; set; }
  201. public string? YouTubeApiName { get; set; }
  202. /** 구글 **/
  203. public string? GoogleClientId { get; set; }
  204. public string? GoogleClientSecretEnc { get; set; }
  205. public string? GoogleAppId { get; set; }
  206. /** 토스페이먼츠 **/
  207. /// <summary>Toss 결제 환경 (test / live)</summary>
  208. public string? TossPayMode { get; set; }
  209. /// <summary>Toss Test Client Key (암호화 저장 권장)</summary>
  210. public string? TossTestClientKeyEnc { get; set; }
  211. /// <summary>Toss Test Secret Key (암호화 저장 권장)</summary>
  212. public string? TossTestSecretKeyEnc { get; set; }
  213. /// <summary>Toss Live Client Key (암호화 저장 권장)</summary>
  214. public string? TossLiveClientKeyEnc { get; set; }
  215. /// <summary>Toss Live Secret Key (암호화 저장 권장)</summary>
  216. public string? TossLiveSecretKeyEnc { get; set; }
  217. /** 소셜 로그인 on/off (Admin /Config/External 체크박스). 키가 있어도 false 면 해당 로그인 비활성 **/
  218. public bool NaverLoginEnabled { get; set; } = true;
  219. public bool KakaoLoginEnabled { get; set; } = true;
  220. public bool GoogleLoginEnabled { get; set; } = true;
  221. /** 네이버 로그인 **/
  222. public string? NaverClientId { get; set; }
  223. public string? NaverClientSecretEnc { get; set; }
  224. /** 카카오 로그인 (ClientId = REST API 키) **/
  225. public string? KakaoRestApiKeyEnc { get; set; }
  226. public string? KakaoJavascriptKey { get; set; }
  227. public string? KakaoAdminKeyEnc { get; set; }
  228. /** 네이버 검색(뉴스) API **/
  229. public string? NaverSearchClientId { get; set; }
  230. public string? NaverSearchClientSecretEnc { get; set; }
  231. }
  232. // ==================================================
  233. // 코인/시세 설정 (Crypto)
  234. // ==================================================
  235. public sealed class CryptoConfig
  236. {
  237. public int TickerRefreshSeconds { get; set; } = 5;
  238. public decimal SurgeThreshold { get; set; } = 5.0m;
  239. public decimal PlungeThreshold { get; set; } = -5.0m;
  240. public int MainPageCoinCount { get; set; } = 10;
  241. }
  242. // ==================================================
  243. // 채팅 경험치/리더보드 설정 (ChatExp)
  244. // 관리자: /Channel/Exp 페이지에서 편집
  245. // ==================================================
  246. public sealed class ChatExpConfig
  247. {
  248. /// <summary>채팅 1건당 지급 XP</summary>
  249. public int ChatXpPerMessage { get; set; } = 1;
  250. /// <summary>후원 N POINT당 1 XP (기본 1000 = 1,000원당 1XP)</summary>
  251. public int DonationXpPerAmount { get; set; } = 1000;
  252. /// <summary>방송 세션당 채팅 XP 상한 (후원 XP는 무제한)</summary>
  253. public int ChatXpSessionLimit { get; set; } = 50;
  254. /// <summary>XP 적립 최소 글자수</summary>
  255. public int MinContentLength { get; set; } = 2;
  256. /// <summary>채팅 쿨다운(초) — 기존 RateLimit 재정의</summary>
  257. public int RateLimitSec { get; set; } = 2;
  258. /// <summary>리더보드 표시 인원 (Top N)</summary>
  259. public int LeaderboardSize { get; set; } = 50;
  260. /// <summary>크라운 뱃지 부여 Top N</summary>
  261. public int CrownTopN { get; set; } = 3;
  262. /// <summary>watch 페이지에서 리더보드 기능 노출</summary>
  263. public bool UxShowLeaderboard { get; set; } = true;
  264. /// <summary>watch 페이지 채팅창 상단에 "내 XP" 뱃지 노출</summary>
  265. public bool UxShowMyXpBadge { get; set; } = true;
  266. }
  267. // ==================================================
  268. // 출석 설정 (Attendance)
  269. // ==================================================
  270. public sealed class AttendanceConfig
  271. {
  272. /// <summary>출석 기능 활성화</summary>
  273. public bool IsEnabled { get; set; } = false;
  274. /// <summary>기본 경험치</summary>
  275. public int BaseExp { get; set; } = 0;
  276. /// <summary>기본 포인트</summary>
  277. public int BasePoint { get; set; } = 0;
  278. /// <summary>연속 출석 가중치 사용</summary>
  279. public bool UseStreakBonus { get; set; } = false;
  280. /// <summary>연속 출석 1일당 추가 경험치</summary>
  281. public int StreakBonusPerDay { get; set; } = 0;
  282. /// <summary>연속 출석 1일당 추가 포인트</summary>
  283. public int StreakBonusPointPerDay { get; set; } = 0;
  284. /// <summary>가중치 최대 적용 일수</summary>
  285. public int StreakBonusMaxDays { get; set; } = 0;
  286. /// <summary>순위 보상 사용</summary>
  287. public bool UseRankBonus { get; set; } = false;
  288. /// <summary>순위별 보상 설정 (JSON) [{"rank":1,"exp":100,"point":50},...]</summary>
  289. public string? RankBonusConfig { get; set; }
  290. }
  291. // ==================================================
  292. // 가입 축하 보상 설정 (SignupReward)
  293. // 신규 회원 최초 가입 시 1회 지급. 멱등: WalletTransaction RefID "signup:{memberID}"
  294. // ==================================================
  295. public sealed class SignupRewardConfig
  296. {
  297. /// <summary>가입 축하 보상 활성화</summary>
  298. public bool Enabled { get; set; } = false;
  299. /// <summary>지급 코인(무상, Airdrop 파티션)</summary>
  300. public int CoinAmount { get; set; } = 0;
  301. /// <summary>지급 캐시(유상 취급, Adjusted 파티션). 기본 0</summary>
  302. public int CashAmount { get; set; } = 0;
  303. /// <summary>지급 경험치(XP)</summary>
  304. public int ExpAmount { get; set; } = 0;
  305. }
  306. // ==================================================
  307. // 보상 엔진 설정 (Reward) — d3 §③ / M2. ActivityTokenConfig 를 대체·통합.
  308. // RewardService 가 단일 지급 관문에서 참조하는 XP/토큰 수치 + 액션별 일일 캡.
  309. // 캡 필드는 0 = 무제한. XP=경험치(MemberStats.Exp), Point=토큰(Wallet Reward 파티션).
  310. // ==================================================
  311. public sealed class RewardConfig
  312. {
  313. /// <summary>게시글 1건 작성 시 지급 경험치 (0 = 미지급)</summary>
  314. public int PostExp { get; set; } = 0;
  315. /// <summary>게시글 1건 작성 시 지급 토큰 (0 = 미지급)</summary>
  316. public int PostPoint { get; set; } = 0;
  317. /// <summary>댓글 1건 작성 시 지급 경험치 (0 = 미지급)</summary>
  318. public int CommentExp { get; set; } = 0;
  319. /// <summary>댓글 1건 작성 시 지급 토큰 (0 = 미지급)</summary>
  320. public int CommentPoint { get; set; } = 0;
  321. /// <summary>추천(좋아요)을 누른 회원에게 지급 경험치 (0 = 미지급)</summary>
  322. public int LikeGivenExp { get; set; } = 0;
  323. /// <summary>추천(좋아요)을 받은 글 작성자에게 지급 토큰 (0 = 미지급)</summary>
  324. public int LikeReceivedPoint { get; set; } = 0;
  325. /// <summary>보상 지급 최소 게시글 길이 (미만이면 미지급, 0 = 제한 없음)</summary>
  326. public int MinPostLength { get; set; } = 0;
  327. /// <summary>보상 지급 최소 댓글 길이 (미만이면 미지급, 0 = 제한 없음)</summary>
  328. public int MinCommentLength { get; set; } = 0;
  329. /// <summary>신규 가입 후 보상 유예 기간(일) — 가입 N일 이내 회원은 활동 보상 미지급 (어뷰징 방지, 0 = 유예 없음)</summary>
  330. public int NewMemberHoldDays { get; set; } = 0;
  331. // ---- 액션별 일일 캡 (0 = 무제한) ----
  332. /// <summary>게시글 보상 일일 횟수 상한</summary>
  333. public int PostDailyCount { get; set; } = 0;
  334. /// <summary>게시글 보상 일일 경험치 상한</summary>
  335. public int PostDailyExp { get; set; } = 0;
  336. /// <summary>게시글 보상 일일 토큰 상한</summary>
  337. public int PostDailyPoint { get; set; } = 0;
  338. /// <summary>댓글 보상 일일 횟수 상한</summary>
  339. public int CommentDailyCount { get; set; } = 0;
  340. /// <summary>댓글 보상 일일 경험치 상한</summary>
  341. public int CommentDailyExp { get; set; } = 0;
  342. /// <summary>댓글 보상 일일 토큰 상한</summary>
  343. public int CommentDailyPoint { get; set; } = 0;
  344. /// <summary>추천(누른 쪽) 보상 일일 횟수 상한</summary>
  345. public int LikeGivenDailyCount { get; set; } = 0;
  346. /// <summary>추천(누른 쪽) 보상 일일 경험치 상한</summary>
  347. public int LikeGivenDailyExp { get; set; } = 0;
  348. /// <summary>추천(받은 쪽) 보상 일일 횟수 상한</summary>
  349. public int LikeReceivedDailyCount { get; set; } = 0;
  350. /// <summary>추천(받은 쪽) 보상 일일 토큰 상한</summary>
  351. public int LikeReceivedDailyPoint { get; set; } = 0;
  352. /// <summary>채팅 보상 일일 횟수 상한</summary>
  353. public int ChatDailyCount { get; set; } = 0;
  354. /// <summary>채팅 보상 일일 경험치 상한</summary>
  355. public int ChatDailyExp { get; set; } = 0;
  356. // ---- 응원(Cheer) 설정 (D3 M4) ----
  357. /// <summary>응원 플랫폼 수수료율(%) — fee = floor(amount × CheerFeePercent/100). 기본 20 (Twitch Bits 참고)</summary>
  358. public int CheerFeePercent { get; set; } = 20;
  359. /// <summary>1회 응원 최소 금액 (미만이면 거부). 기본 100</summary>
  360. public int CheerMinAmount { get; set; } = 100;
  361. /// <summary>한 회원이 하루에 보낼 수 있는 응원 총액 상한 (0 = 무제한). 자전 응원 어뷰징 방지</summary>
  362. public int CheerDailyMax { get; set; } = 0;
  363. }
  364. // ==================================================
  365. // 모의투자 설정 (Paper) — Admin /Config, d4 §④
  366. // ==================================================
  367. public sealed class PaperConfig
  368. {
  369. /// <summary>모의투자 노출/주문 토글</summary>
  370. public bool Enabled { get; set; } = true;
  371. /// <summary>매매 수수료 Bp (기본 15 = 0.15%; 토큰 sink)</summary>
  372. public int FeeRateBp { get; set; } = 15;
  373. /// <summary>매도 거래세 Bp (기본 18; 토큰 sink)</summary>
  374. public int TaxRateBp { get; set; } = 18;
  375. /// <summary>최소 입금 토큰</summary>
  376. public int MinDeposit { get; set; } = 10000;
  377. /// <summary>계좌 최대 보유 토큰 (0 = 무제한)</summary>
  378. public int MaxHolding { get; set; } = 0;
  379. /// <summary>출금 시 수익분 소각 Bp (0 = 꺼둠, 인플레 밸브)</summary>
  380. public int WithdrawProfitBurnBp { get; set; } = 0;
  381. /// <summary>1주문 상한 Bp (기본 3000 = Equity 30%)</summary>
  382. public int OrderMaxPctBp { get; set; } = 3000;
  383. /// <summary>리더보드 등재 최소 체결 수</summary>
  384. public int MinFillsForRank { get; set; } = 3;
  385. }
  386. // ==================================================
  387. // 데이터 수집 API 키 + 수집기 활성화 (DataCollection) — Admin /Config/External 하단에서 편집
  388. // 키는 AES-GCM 암호화 저장(enc:v{n}:), 비면 수집기는 appsettings 폴백. 플래그는 수집기 on/off 의 단일 권위(런타임).
  389. // ==================================================
  390. public sealed class DataCollectionConfig
  391. {
  392. // ---- 키 (암호화 저장) ----
  393. /// <summary>공공데이터포털 금융위(data.go.kr) ServiceKey</summary>
  394. public string? DataGoKrServiceKeyEnc { get; set; }
  395. /// <summary>KRX(data-dbg.krx.co.kr) AUTH_KEY</summary>
  396. public string? KrxApiKeyEnc { get; set; }
  397. /// <summary>OpenDART(공시) crtfc_key</summary>
  398. public string? OpenDartApiKeyEnc { get; set; }
  399. /// <summary>수출입은행 현재환율(AP01) authkey</summary>
  400. public string? KoreaEximExchangeKeyEnc { get; set; }
  401. /// <summary>수출입은행 대출금리(AP02) authkey</summary>
  402. public string? KoreaEximLoanRateKeyEnc { get; set; }
  403. /// <summary>수출입은행 국제금리(AP03) authkey</summary>
  404. public string? KoreaEximIntlRateKeyEnc { get; set; }
  405. /// <summary>SEIBro OpenPlatform key</summary>
  406. public string? SeibroApiKeyEnc { get; set; }
  407. /// <summary>KOSIS apiKey</summary>
  408. public string? KosisApiKeyEnc { get; set; }
  409. // ---- 수집기 활성화 플래그 (appsettings *Sync/Enabled 와 1:1, DB 가 런타임 권위) ----
  410. public bool StockDataMasterSync { get; set; } = false;
  411. public bool StockDataDailyPriceSync { get; set; } = false;
  412. public bool KrxIndexSync { get; set; } = false;
  413. public bool KrxBondIndexSync { get; set; } = false;
  414. public bool KrxStockSync { get; set; } = false;
  415. public bool KrxEtpSync { get; set; } = false;
  416. public bool KrxWarrantSync { get; set; } = false;
  417. public bool KrxBondSync { get; set; } = false;
  418. public bool KrxDerivativeSync { get; set; } = false;
  419. public bool KrxCommoditySync { get; set; } = false;
  420. public bool KrxEsgSync { get; set; } = false;
  421. public bool OpenDartDisclosureSync { get; set; } = false;
  422. public bool KoreaEximMacroSync { get; set; } = false;
  423. public bool KosisSync { get; set; } = false;
  424. public bool WorldIndexEnabled { get; set; } = false;
  425. public bool MarketQuoteEnabled { get; set; } = false;
  426. public bool SeibroIssuerSync { get; set; } = false;
  427. public bool SeibroDividendSync { get; set; } = false;
  428. public bool SeibroSupplySync { get; set; } = false;
  429. public bool SeibroCorpActionSync { get; set; } = false;
  430. public bool SeibroBondSync { get; set; } = false;
  431. public bool SeibroDerivSync { get; set; } = false;
  432. public bool SeibroForeignSync { get; set; } = false;
  433. }
  434. #endregion