Config.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. namespace Domain.Entities.Common
  2. {
  3. public sealed class Config
  4. {
  5. public int ID { get; private set; }
  6. public DateTime LastUpdatedAt { get; private set; } = DateTime.UtcNow;
  7. public byte[] RowVersion { get; private set; } = [];
  8. public BasicConfig Basic { get; private set; } = new();
  9. public ImagesConfig Images { get; private set; } = new();
  10. public MetaConfig Meta { get; private set; } = new();
  11. public CompanyConfig Company { get; private set; } = new();
  12. public AccountConfig Account { get; private set; } = new();
  13. public EmailTemplateConfig EmailTemplate { get; private set; } = new();
  14. public ExternalApiConfig External { get; private set; } = new();
  15. public PaymentConfig Payment { get; private set; } = new();
  16. public CryptoConfig Crypto { get; private set; } = new();
  17. public AttendanceConfig Attendance { get; private set; } = new();
  18. public SignupRewardConfig SignupReward { get; private set; } = new();
  19. public RewardConfig Reward { get; private set; } = new();
  20. private Config() { }
  21. public static Config Create()
  22. {
  23. return new();
  24. }
  25. public void Update(
  26. BasicConfig basic,
  27. ImagesConfig images,
  28. MetaConfig meta,
  29. CompanyConfig company,
  30. AccountConfig account,
  31. EmailTemplateConfig emailTemplate,
  32. ExternalApiConfig external,
  33. PaymentConfig payment,
  34. CryptoConfig crypto
  35. ) {
  36. Basic = basic ?? throw new ArgumentNullException(nameof(basic));
  37. Images = images ?? throw new ArgumentNullException(nameof(images));
  38. Meta = meta ?? throw new ArgumentNullException(nameof(meta));
  39. Company = company ?? throw new ArgumentNullException(nameof(company));
  40. Account = account ?? throw new ArgumentNullException(nameof(account));
  41. EmailTemplate = emailTemplate ?? throw new ArgumentNullException(nameof(emailTemplate));
  42. External = external ?? throw new ArgumentNullException(nameof(external));
  43. Payment = payment ?? throw new ArgumentNullException(nameof(payment));
  44. Crypto = crypto ?? throw new ArgumentNullException(nameof(crypto));
  45. LastUpdatedAt = DateTime.UtcNow;
  46. }
  47. // 보상/출석/가입보상은 모듈러 Update — 기존 Update(9-param) 시그니처를 건드리지 않기 위해 분리.
  48. public void UpdateAttendance(AttendanceConfig attendance)
  49. {
  50. Attendance = attendance ?? throw new ArgumentNullException(nameof(attendance));
  51. LastUpdatedAt = DateTime.UtcNow;
  52. }
  53. public void UpdateSignupReward(SignupRewardConfig signupReward)
  54. {
  55. SignupReward = signupReward ?? throw new ArgumentNullException(nameof(signupReward));
  56. LastUpdatedAt = DateTime.UtcNow;
  57. }
  58. public void UpdateReward(RewardConfig reward)
  59. {
  60. Reward = reward ?? throw new ArgumentNullException(nameof(reward));
  61. LastUpdatedAt = DateTime.UtcNow;
  62. }
  63. }
  64. #region Owned Groups
  65. // ==================================================
  66. // 기본 정보 (Basic)
  67. // ==================================================
  68. public sealed class BasicConfig
  69. {
  70. public string? SiteName { get; set; }
  71. public string? SiteURL { get; set; }
  72. public string? RootID { get; set; }
  73. public string? FromEmail { get; set; }
  74. public string? FromName { get; set; }
  75. public string? SmtpServer { get; set; }
  76. public int? SmtpPort { get; set; }
  77. public bool SmtpEnableSSL { get; set; }
  78. public string? SmtpUsername { get; set; }
  79. public string? SmtpPassword { get; set; }
  80. public string? AdminWhiteIPList { get; set; }
  81. public string? FrontWhiteIPList { get; set; }
  82. public string? BlockAlertTitle { get; set; }
  83. public string? BlockAlertContent { get; set; }
  84. public bool IsMaintenance { get; set; } = false;
  85. public string? MaintenanceContent { get; set; }
  86. }
  87. // ==================================================
  88. // 기본 이미지 (Images)
  89. // ==================================================
  90. public sealed class ImagesConfig
  91. {
  92. public string? Favicon { get; set; }
  93. public string? LogoSquare { get; set; }
  94. public string? LogoHorizontal { get; set; }
  95. public string? OgDefault { get; set; }
  96. public string? TwitterImage { get; set; }
  97. public string? AppleTouchIcon { get; set; }
  98. public string? AppIcon_192 { get; set; }
  99. public string? AppIcon_512 { get; set; }
  100. }
  101. // ==================================================
  102. // 메타 태그 (Meta)
  103. // ==================================================
  104. public sealed class MetaConfig
  105. {
  106. public string? Keywords { get; set; }
  107. public string? Description { get; set; }
  108. public string? Author { get; set; }
  109. public string? Viewport { get; set; }
  110. public string? ApplicationName { get; set; }
  111. public string? Generator { get; set; }
  112. public string? Robots { get; set; }
  113. public string? Adds { get; set; }
  114. }
  115. // ==================================================
  116. // 회사 정보 (Company)
  117. // ==================================================
  118. public sealed class CompanyConfig
  119. {
  120. public string? Name { get; set; }
  121. public string? RegNo { get; set; }
  122. public string? Address { get; set; }
  123. public string? ZipCode { get; set; }
  124. public string? Owner { get; set; }
  125. public string? Tel { get; set; }
  126. public string? Fax { get; set; }
  127. public string? RetailSaleNo { get; set; }
  128. public string? AddedSaleNo { get; set; }
  129. public string? Hosting { get; set; }
  130. public string? AdminName { get; set; }
  131. public string? AdminEmail { get; set; }
  132. public string? SiteUrl { get; set; }
  133. public string? BankCode { get; set; }
  134. public string? BankOwner { get; set; }
  135. public string? BankNumber { get; set; }
  136. }
  137. // ==================================================
  138. // 회원가입 설정 (Account)
  139. // ==================================================
  140. public sealed class AccountConfig
  141. {
  142. // 회원 가입 시
  143. public bool IsRegisterBlock { get; set; } = false;
  144. public bool IsRegisterEmailAuth { get; set; } = false;
  145. public ushort? PasswordMinLength { get; set; }
  146. public ushort? PasswordUppercaseLength { get; set; }
  147. public ushort? PasswordNumbersLength { get; set; }
  148. public ushort? PasswordSpecialcharsLength { get; set; }
  149. public string? DeniedEmailList { get; set; }
  150. public string? DeniedNameList { get; set; }
  151. // 회원 수정 시
  152. public ushort? ChangeEmailDay { get; set; }
  153. public ushort? ChangeNameDay { get; set; }
  154. public ushort? ChangeSummaryDay { get; set; }
  155. public ushort? ChangeIntroDay { get; set; }
  156. public ushort? ChangePasswordDay { get; set; }
  157. // 로그인 시
  158. public bool IsLoginEmailVerifiedOnly { get; set; } = false;
  159. public ushort? MaxLoginTryCount { get; set; }
  160. public ushort? MaxLoginTryLimitSecond { get; set; }
  161. }
  162. // ==================================================
  163. // 알림 발송 양식 - 이메일 (EmailTemplate)
  164. // ==================================================
  165. public sealed class EmailTemplateConfig
  166. {
  167. public string? RegisterEmailFormTitle { get; set; }
  168. public string? RegisterEmailFormContent { get; set; }
  169. public string? RegistrationEmailFormTitle { get; set; }
  170. public string? RegistrationEmailFormContent { get; set; }
  171. public string? ResetPasswordEmailFormTitle { get; set; }
  172. public string? ResetPasswordEmailFormContent { get; set; }
  173. public string? ChangedPasswordEmailFormTitle { get; set; }
  174. public string? ChangedPasswordEmailFormContent { get; set; }
  175. public string? WithdrawEmailFormTitle { get; set; }
  176. public string? WithdrawEmailFormContent { get; set; }
  177. public string? EmailVerifyFormTitle { get; set; }
  178. public string? EmailVerifyFormContent { get; set; }
  179. public string? ChangedEmailFormTitle { get; set; }
  180. public string? ChangedEmailFormContent { get; set; }
  181. }
  182. // ==================================================
  183. // 외부 API 설정 (External)
  184. // ==================================================
  185. public sealed class ExternalApiConfig
  186. {
  187. /** YouTube **/
  188. public string? YouTubeApiKeyEnc { get; set; }
  189. public string? YouTubeApiName { get; set; }
  190. /** 구글 **/
  191. public string? GoogleClientId { get; set; }
  192. public string? GoogleClientSecretEnc { get; set; }
  193. public string? GoogleAppId { get; set; }
  194. /** 다날 페이 **/
  195. //[Comment("Danal 결제 환경")]
  196. //public string? DanalPayMode { get; set; }
  197. //[Comment("Danal Test CPID")]
  198. //public string? DanalTestCpid { get; set; }
  199. //[Comment("Danal Test Client Key (암호화 저장 권장)")]
  200. //public string? DanalTestClientKeyEnc { get; set; }
  201. //[Comment("Danal Test Secret Key (암호화 저장 권장)")]
  202. //public string? DanalTestSecretKeyEnc { get; set; }
  203. //[Comment("Danal Live CPID")]
  204. //public string? DanalLiveCpid { get; set; }
  205. //[Comment("Danal Live Client Key (암호화 저장 권장)")]
  206. //public string? DanalLiveClientKeyEnc { get; set; }
  207. //[Comment("Danal Live Secret Key (암호화 저장 권장)")]
  208. //public string? DanalLiveSecretKeyEnc { get; set; }
  209. }
  210. // ==================================================
  211. // 결제 설정 (Payment)
  212. // ==================================================
  213. public sealed class PaymentConfig
  214. {
  215. /** 다날 페이 **/
  216. //[Range(0, 100)]
  217. //[Comment("다날 신용카드 수수료(%)")]
  218. //public decimal? DanalCardFeeRate { get; set; }
  219. //[Range(0, 999_999_999)]
  220. //[Comment("다날 신용카드 수수료(원)")]
  221. //public decimal? DanalCardFeeAmount { get; set; }
  222. //[Range(0, 100)]
  223. //[Comment("다날 계좌이체 수수료(%)")]
  224. //public decimal? DanalTransferFeeRate { get; set; }
  225. //[Range(0, 999_999_999)]
  226. //[Comment("다날 계좌이체 수수료(원)")]
  227. //public decimal? DanalTransferFeeAmount { get; set; }
  228. //[Range(0, 100)]
  229. //[Comment("다날 가상계좌 수수료(%)")]
  230. //public decimal? DanalVbankFeeRate { get; set; }
  231. //[Range(0, 999_999_999)]
  232. //[Comment("다날 가상계좌 수수료(원)")]
  233. //public decimal? DanalVbankFeeAmount { get; set; }
  234. //[Range(0, 100)]
  235. //[Comment("다날 간편결제 수수료(%)")]
  236. //public decimal? DanalSimpleFeeRate { get; set; }
  237. //[Range(0, 999_999_999)]
  238. //[Comment("다날 간편결제 수수료(원)")]
  239. //public decimal? DanalSimpleFeeAmount { get; set; }
  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. // 출석 설정 (Attendance)
  253. // ==================================================
  254. public sealed class AttendanceConfig
  255. {
  256. /// <summary>출석 기능 활성화</summary>
  257. public bool IsEnabled { get; set; } = false;
  258. /// <summary>기본 경험치</summary>
  259. public int BaseExp { get; set; } = 0;
  260. /// <summary>기본 포인트</summary>
  261. public int BasePoint { get; set; } = 0;
  262. /// <summary>연속 출석 가중치 사용</summary>
  263. public bool UseStreakBonus { get; set; } = false;
  264. /// <summary>연속 출석 1일당 추가 경험치</summary>
  265. public int StreakBonusPerDay { get; set; } = 0;
  266. /// <summary>연속 출석 1일당 추가 포인트</summary>
  267. public int StreakBonusPointPerDay { get; set; } = 0;
  268. /// <summary>가중치 최대 적용 일수</summary>
  269. public int StreakBonusMaxDays { get; set; } = 0;
  270. /// <summary>순위 보상 사용</summary>
  271. public bool UseRankBonus { get; set; } = false;
  272. /// <summary>순위별 보상 설정 (JSON) [{"rank":1,"exp":100,"point":50},...]</summary>
  273. public string? RankBonusConfig { get; set; }
  274. }
  275. // ==================================================
  276. // 가입 축하 보상 설정 (SignupReward)
  277. // 신규 회원 최초 가입 시 1회 지급. 멱등: WalletTransaction RefID "signup:{memberID}"
  278. // ==================================================
  279. public sealed class SignupRewardConfig
  280. {
  281. /// <summary>가입 축하 보상 활성화</summary>
  282. public bool Enabled { get; set; } = false;
  283. /// <summary>지급 코인(무상, Airdrop 파티션)</summary>
  284. public int CoinAmount { get; set; } = 0;
  285. /// <summary>지급 캐시(유상 취급, Adjusted 파티션). 기본 0</summary>
  286. public int CashAmount { get; set; } = 0;
  287. /// <summary>지급 경험치(XP)</summary>
  288. public int ExpAmount { get; set; } = 0;
  289. }
  290. // ==================================================
  291. // 보상 엔진 설정 (Reward) — RewardService 가 단일 지급 관문에서 참조하는 XP/토큰 수치 + 액션별 일일 캡.
  292. // 캡 필드는 0 = 무제한. XP=경험치(MemberStats.Exp), Point=토큰(Wallet Reward 파티션).
  293. // (채팅/응원(Cheer) 보상은 미포팅 — 게시글/댓글/추천만)
  294. // ==================================================
  295. public sealed class RewardConfig
  296. {
  297. /// <summary>게시글 1건 작성 시 지급 경험치 (0 = 미지급)</summary>
  298. public int PostExp { get; set; } = 0;
  299. /// <summary>게시글 1건 작성 시 지급 토큰 (0 = 미지급)</summary>
  300. public int PostPoint { get; set; } = 0;
  301. /// <summary>댓글 1건 작성 시 지급 경험치 (0 = 미지급)</summary>
  302. public int CommentExp { get; set; } = 0;
  303. /// <summary>댓글 1건 작성 시 지급 토큰 (0 = 미지급)</summary>
  304. public int CommentPoint { get; set; } = 0;
  305. /// <summary>추천(좋아요)을 누른 회원에게 지급 경험치 (0 = 미지급)</summary>
  306. public int LikeGivenExp { get; set; } = 0;
  307. /// <summary>추천(좋아요)을 받은 글 작성자에게 지급 토큰 (0 = 미지급)</summary>
  308. public int LikeReceivedPoint { get; set; } = 0;
  309. /// <summary>보상 지급 최소 게시글 길이 (미만이면 미지급, 0 = 제한 없음)</summary>
  310. public int MinPostLength { get; set; } = 0;
  311. /// <summary>보상 지급 최소 댓글 길이 (미만이면 미지급, 0 = 제한 없음)</summary>
  312. public int MinCommentLength { get; set; } = 0;
  313. /// <summary>신규 가입 후 보상 유예 기간(일) — 가입 N일 이내 회원은 활동 보상 미지급 (어뷰징 방지, 0 = 유예 없음)</summary>
  314. public int NewMemberHoldDays { get; set; } = 0;
  315. // ---- 액션별 일일 캡 (0 = 무제한) ----
  316. /// <summary>게시글 보상 일일 횟수 상한</summary>
  317. public int PostDailyCount { get; set; } = 0;
  318. /// <summary>게시글 보상 일일 경험치 상한</summary>
  319. public int PostDailyExp { get; set; } = 0;
  320. /// <summary>게시글 보상 일일 토큰 상한</summary>
  321. public int PostDailyPoint { get; set; } = 0;
  322. /// <summary>댓글 보상 일일 횟수 상한</summary>
  323. public int CommentDailyCount { get; set; } = 0;
  324. /// <summary>댓글 보상 일일 경험치 상한</summary>
  325. public int CommentDailyExp { get; set; } = 0;
  326. /// <summary>댓글 보상 일일 토큰 상한</summary>
  327. public int CommentDailyPoint { get; set; } = 0;
  328. /// <summary>추천(누른 쪽) 보상 일일 횟수 상한</summary>
  329. public int LikeGivenDailyCount { get; set; } = 0;
  330. /// <summary>추천(누른 쪽) 보상 일일 경험치 상한</summary>
  331. public int LikeGivenDailyExp { get; set; } = 0;
  332. /// <summary>추천(받은 쪽) 보상 일일 횟수 상한</summary>
  333. public int LikeReceivedDailyCount { get; set; } = 0;
  334. /// <summary>추천(받은 쪽) 보상 일일 토큰 상한</summary>
  335. public int LikeReceivedDailyPoint { get; set; } = 0;
  336. }
  337. #endregion
  338. }