Config.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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 PaymentConfig Payment { get; private set; } = new();
  15. public CryptoConfig Crypto { get; private set; } = new();
  16. public AttendanceConfig Attendance { get; private set; } = new();
  17. public ChatExpConfig ChatExp { get; private set; } = new();
  18. private Config() { }
  19. public static Config Create()
  20. {
  21. return new();
  22. }
  23. public void Update(
  24. BasicConfig basic,
  25. ImagesConfig images,
  26. MetaConfig meta,
  27. CompanyConfig company,
  28. AccountConfig account,
  29. EmailTemplateConfig emailTemplate,
  30. ExternalApiConfig external,
  31. PaymentConfig payment,
  32. CryptoConfig crypto,
  33. AttendanceConfig attendance
  34. ) {
  35. Basic = basic ?? throw new ArgumentNullException(nameof(basic));
  36. Images = images ?? throw new ArgumentNullException(nameof(images));
  37. Meta = meta ?? throw new ArgumentNullException(nameof(meta));
  38. Company = company ?? throw new ArgumentNullException(nameof(company));
  39. Account = account ?? throw new ArgumentNullException(nameof(account));
  40. EmailTemplate = emailTemplate ?? throw new ArgumentNullException(nameof(emailTemplate));
  41. External = external ?? throw new ArgumentNullException(nameof(external));
  42. Payment = payment ?? throw new ArgumentNullException(nameof(payment));
  43. Crypto = crypto ?? throw new ArgumentNullException(nameof(crypto));
  44. Attendance = attendance ?? throw new ArgumentNullException(nameof(attendance));
  45. LastUpdatedAt = DateTime.UtcNow;
  46. }
  47. public void UpdateChatExp(ChatExpConfig chatExp)
  48. {
  49. ChatExp = chatExp ?? throw new ArgumentNullException(nameof(chatExp));
  50. LastUpdatedAt = DateTime.UtcNow;
  51. }
  52. }
  53. #region Owned Groups
  54. // ==================================================
  55. // 기본 정보 (Basic)
  56. // ==================================================
  57. public sealed class BasicConfig
  58. {
  59. public string? SiteName { get; set; }
  60. public string? SiteURL { get; set; }
  61. public string? RootID { get; set; }
  62. public string? FromEmail { get; set; }
  63. public string? FromName { get; set; }
  64. public string? SmtpServer { get; set; }
  65. public int? SmtpPort { get; set; }
  66. public bool SmtpEnableSSL { get; set; }
  67. public string? SmtpUsername { get; set; }
  68. public string? SmtpPassword { get; set; }
  69. public string? AdminWhiteIPList { get; set; }
  70. public string? FrontWhiteIPList { get; set; }
  71. public string? BlockAlertTitle { get; set; }
  72. public string? BlockAlertContent { get; set; }
  73. public bool IsMaintenance { get; set; } = false;
  74. public string? MaintenanceContent { get; set; }
  75. /// <summary>쪽지 일일 발송 제한 (사용자 1인당 / 시스템 쪽지 제외). 0 = 발송 차단</summary>
  76. public int NoteDailySendLimit { get; set; } = 3;
  77. }
  78. // ==================================================
  79. // 기본 이미지 (Images)
  80. // ==================================================
  81. public sealed class ImagesConfig
  82. {
  83. public string? Favicon { get; set; }
  84. public string? LogoSquare { get; set; }
  85. public string? LogoHorizontal { get; set; }
  86. public string? OgDefault { get; set; }
  87. public string? TwitterImage { get; set; }
  88. public string? AppleTouchIcon { get; set; }
  89. public string? AppIcon_192 { get; set; }
  90. public string? AppIcon_512 { get; set; }
  91. }
  92. // ==================================================
  93. // 메타 태그 (Meta)
  94. // ==================================================
  95. public sealed class MetaConfig
  96. {
  97. public string? Keywords { get; set; }
  98. public string? Description { get; set; }
  99. public string? Author { get; set; }
  100. public string? Viewport { get; set; }
  101. public string? ApplicationName { get; set; }
  102. public string? Generator { get; set; }
  103. public string? Robots { get; set; }
  104. public string? Adds { get; set; }
  105. }
  106. // ==================================================
  107. // 회사 정보 (Company)
  108. // ==================================================
  109. public sealed class CompanyConfig
  110. {
  111. public string? Name { get; set; }
  112. public string? RegNo { get; set; }
  113. public string? Address { get; set; }
  114. public string? ZipCode { get; set; }
  115. public string? Owner { get; set; }
  116. public string? Tel { get; set; }
  117. public string? Fax { get; set; }
  118. public string? RetailSaleNo { get; set; }
  119. public string? AddedSaleNo { get; set; }
  120. public string? Hosting { get; set; }
  121. public string? AdminName { get; set; }
  122. public string? AdminEmail { get; set; }
  123. public string? SiteUrl { get; set; }
  124. public string? BankCode { get; set; }
  125. public string? BankOwner { get; set; }
  126. public string? BankNumber { get; set; }
  127. }
  128. // ==================================================
  129. // 회원가입 설정 (Account)
  130. // ==================================================
  131. public sealed class AccountConfig
  132. {
  133. // 회원 가입 시
  134. public bool IsRegisterBlock { get; set; } = false;
  135. public bool IsRegisterEmailAuth { get; set; } = false;
  136. public ushort? PasswordMinLength { get; set; }
  137. public ushort? PasswordUppercaseLength { get; set; }
  138. public ushort? PasswordNumbersLength { get; set; }
  139. public ushort? PasswordSpecialcharsLength { get; set; }
  140. public string? DeniedEmailList { get; set; }
  141. public string? DeniedNameList { get; set; }
  142. // 회원 수정 시
  143. public ushort? ChangeEmailDay { get; set; }
  144. public ushort? ChangeNameDay { get; set; }
  145. public ushort? ChangeSummaryDay { get; set; }
  146. public ushort? ChangeIntroDay { get; set; }
  147. public ushort? ChangePasswordDay { get; set; }
  148. // 로그인 시
  149. public bool IsLoginEmailVerifiedOnly { get; set; } = false;
  150. public ushort? MaxLoginTryCount { get; set; }
  151. public ushort? MaxLoginTryLimitSecond { get; set; }
  152. }
  153. // ==================================================
  154. // 알림 발송 양식 - 이메일 (EmailTemplate)
  155. // ==================================================
  156. public sealed class EmailTemplateConfig
  157. {
  158. public string? RegisterEmailFormTitle { get; set; }
  159. public string? RegisterEmailFormContent { get; set; }
  160. public string? RegistrationEmailFormTitle { get; set; }
  161. public string? RegistrationEmailFormContent { get; set; }
  162. public string? ResetPasswordEmailFormTitle { get; set; }
  163. public string? ResetPasswordEmailFormContent { get; set; }
  164. public string? ChangedPasswordEmailFormTitle { get; set; }
  165. public string? ChangedPasswordEmailFormContent { get; set; }
  166. public string? WithdrawEmailFormTitle { get; set; }
  167. public string? WithdrawEmailFormContent { get; set; }
  168. public string? WithdrawVerifyEmailFormTitle { get; set; }
  169. public string? WithdrawVerifyEmailFormContent { get; set; }
  170. public string? EmailVerifyFormTitle { get; set; }
  171. public string? EmailVerifyFormContent { get; set; }
  172. public string? ChangedEmailFormTitle { get; set; }
  173. public string? ChangedEmailFormContent { get; set; }
  174. }
  175. // ==================================================
  176. // 외부 API 설정 (External)
  177. // ==================================================
  178. public sealed class ExternalApiConfig
  179. {
  180. /** YouTube **/
  181. public string? YouTubeApiKeyEnc { get; set; }
  182. public string? YouTubeApiName { get; set; }
  183. /** 구글 **/
  184. public string? GoogleClientId { get; set; }
  185. public string? GoogleClientSecretEnc { get; set; }
  186. public string? GoogleAppId { get; set; }
  187. /** 다날 페이 **/
  188. /// <summary>Danal 결제 환경 (test / live)</summary>
  189. public string? DanalPayMode { get; set; }
  190. /// <summary>Danal Test CPID</summary>
  191. public string? DanalTestCpid { get; set; }
  192. /// <summary>Danal Test Client Key (암호화 저장 권장)</summary>
  193. public string? DanalTestClientKeyEnc { get; set; }
  194. /// <summary>Danal Test Secret Key (암호화 저장 권장)</summary>
  195. public string? DanalTestSecretKeyEnc { get; set; }
  196. /// <summary>Danal Live CPID</summary>
  197. public string? DanalLiveCpid { get; set; }
  198. /// <summary>Danal Live Client Key (암호화 저장 권장)</summary>
  199. public string? DanalLiveClientKeyEnc { get; set; }
  200. /// <summary>Danal Live Secret Key (암호화 저장 권장)</summary>
  201. public string? DanalLiveSecretKeyEnc { get; set; }
  202. }
  203. // ==================================================
  204. // 결제 설정 (Payment)
  205. // ==================================================
  206. public sealed class PaymentConfig
  207. {
  208. /** 다날 페이 수수료 (% 우선 적용 후 원 가산) **/
  209. /// <summary>신용카드 수수료(%)</summary>
  210. public decimal? DanalCardFeeRate { get; set; }
  211. /// <summary>신용카드 수수료(원)</summary>
  212. public decimal? DanalCardFeeAmount { get; set; }
  213. /// <summary>카카오페이 수수료(%)</summary>
  214. public decimal? DanalKakaoPayFeeRate { get; set; }
  215. /// <summary>카카오페이 수수료(원)</summary>
  216. public decimal? DanalKakaoPayFeeAmount { get; set; }
  217. /// <summary>네이버페이 수수료(%)</summary>
  218. public decimal? DanalNaverPayFeeRate { get; set; }
  219. /// <summary>네이버페이 수수료(원)</summary>
  220. public decimal? DanalNaverPayFeeAmount { get; set; }
  221. /// <summary>계좌이체 수수료(%)</summary>
  222. public decimal? DanalTransferFeeRate { get; set; }
  223. /// <summary>계좌이체 수수료(원)</summary>
  224. public decimal? DanalTransferFeeAmount { get; set; }
  225. /// <summary>휴대폰 수수료(%)</summary>
  226. public decimal? DanalMobileFeeRate { get; set; }
  227. /// <summary>휴대폰 수수료(원)</summary>
  228. public decimal? DanalMobileFeeAmount { get; set; }
  229. /// <summary>가상계좌 수수료(%)</summary>
  230. public decimal? DanalVbankFeeRate { get; set; }
  231. /// <summary>가상계좌 수수료(원)</summary>
  232. public decimal? DanalVbankFeeAmount { get; set; }
  233. /** 결제수단 사용 여부 (기본 false — 관리자가 명시적으로 활성화) **/
  234. public bool IsCardEnabled { get; set; } = false;
  235. public bool IsKakaoPayEnabled { get; set; } = false;
  236. public bool IsNaverPayEnabled { get; set; } = false;
  237. public bool IsTransferEnabled { get; set; } = false;
  238. public bool IsMobileEnabled { get; set; } = false;
  239. public bool IsVirtualAccountEnabled { get; set; } = false;
  240. }
  241. // ==================================================
  242. // 코인/시세 설정 (Crypto)
  243. // ==================================================
  244. public sealed class CryptoConfig
  245. {
  246. public int TickerRefreshSeconds { get; set; } = 5;
  247. public decimal SurgeThreshold { get; set; } = 5.0m;
  248. public decimal PlungeThreshold { get; set; } = -5.0m;
  249. public int MainPageCoinCount { get; set; } = 10;
  250. }
  251. // ==================================================
  252. // 채팅 경험치/리더보드 설정 (ChatExp)
  253. // 관리자: /Channel/Exp 페이지에서 편집
  254. // ==================================================
  255. public sealed class ChatExpConfig
  256. {
  257. /// <summary>채팅 1건당 지급 XP</summary>
  258. public int ChatXpPerMessage { get; set; } = 1;
  259. /// <summary>후원 N POINT당 1 XP (기본 1000 = 1,000원당 1XP)</summary>
  260. public int DonationXpPerAmount { get; set; } = 1000;
  261. /// <summary>방송 세션당 채팅 XP 상한 (후원 XP는 무제한)</summary>
  262. public int ChatXpSessionLimit { get; set; } = 50;
  263. /// <summary>XP 적립 최소 글자수</summary>
  264. public int MinContentLength { get; set; } = 2;
  265. /// <summary>채팅 쿨다운(초) — 기존 RateLimit 재정의</summary>
  266. public int RateLimitSec { get; set; } = 2;
  267. /// <summary>리더보드 표시 인원 (Top N)</summary>
  268. public int LeaderboardSize { get; set; } = 50;
  269. /// <summary>크라운 뱃지 부여 Top N</summary>
  270. public int CrownTopN { get; set; } = 3;
  271. /// <summary>watch 페이지에서 리더보드 기능 노출</summary>
  272. public bool UxShowLeaderboard { get; set; } = true;
  273. /// <summary>watch 페이지 채팅창 상단에 "내 XP" 뱃지 노출</summary>
  274. public bool UxShowMyXpBadge { get; set; } = true;
  275. }
  276. // ==================================================
  277. // 출석 설정 (Attendance)
  278. // ==================================================
  279. public sealed class AttendanceConfig
  280. {
  281. /// <summary>출석 기능 활성화</summary>
  282. public bool IsEnabled { get; set; } = false;
  283. /// <summary>기본 경험치</summary>
  284. public int BaseExp { get; set; } = 0;
  285. /// <summary>기본 포인트</summary>
  286. public int BasePoint { get; set; } = 0;
  287. /// <summary>연속 출석 가중치 사용</summary>
  288. public bool UseStreakBonus { get; set; } = false;
  289. /// <summary>연속 출석 1일당 추가 경험치</summary>
  290. public int StreakBonusPerDay { get; set; } = 0;
  291. /// <summary>연속 출석 1일당 추가 포인트</summary>
  292. public int StreakBonusPointPerDay { get; set; } = 0;
  293. /// <summary>가중치 최대 적용 일수</summary>
  294. public int StreakBonusMaxDays { get; set; } = 0;
  295. /// <summary>순위 보상 사용</summary>
  296. public bool UseRankBonus { get; set; } = false;
  297. /// <summary>순위별 보상 설정 (JSON) [{"rank":1,"exp":100,"point":50},...]</summary>
  298. public string? RankBonusConfig { get; set; }
  299. }
  300. #endregion