Coin.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System.ComponentModel.DataAnnotations;
  2. namespace Domain.Entities.Crypto
  3. {
  4. public class Coin
  5. {
  6. public virtual List<CoinCategoryMap> CoinCategoryMap { get; private set; } = [];
  7. public virtual List<CoinMarket> CoinMarket { get; private set; } = [];
  8. [Key]
  9. public int ID { get; private set; }
  10. public string Symbol { get; private set; } = default!;
  11. public string KorName { get; private set; } = default!;
  12. public string EngName { get; private set; } = default!;
  13. public string? LogoImage { get; private set; }
  14. public string? Description { get; private set; }
  15. public string? ContractAddress { get; private set; }
  16. public string? WebsiteUrl { get; private set; }
  17. public string? WhitepaperUrl { get; private set; }
  18. public string? TwitterUrl { get; private set; }
  19. public string? TelegramUrl { get; private set; }
  20. public bool IsActive { get; private set; } = false;
  21. public bool IsWarning { get; private set; } = false;
  22. public bool IsNew { get; private set; } = false;
  23. public bool IsDelisted { get; private set; } = false;
  24. public bool IsFeatured { get; private set; } = false;
  25. public short DisplayOrder { get; private set; } = 0;
  26. public DateTime? UpdatedAt { get; private set; }
  27. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  28. private Coin() { }
  29. private Coin(
  30. string symbol,
  31. string korName,
  32. string engName,
  33. string? description,
  34. string? contractAddress,
  35. string? websiteUrl,
  36. string? whitepaperUrl,
  37. string? twitterUrl,
  38. string? telegramUrl,
  39. bool isActive,
  40. bool isWarning,
  41. bool isNew,
  42. bool isDelisted
  43. ) {
  44. if (string.IsNullOrWhiteSpace(symbol))
  45. {
  46. throw new ArgumentException("Symbol is required.", nameof(symbol));
  47. }
  48. if (symbol.Length > 30)
  49. {
  50. throw new ArgumentOutOfRangeException(nameof(symbol));
  51. }
  52. if (string.IsNullOrWhiteSpace(korName))
  53. {
  54. throw new ArgumentException("KorName is required.", nameof(korName));
  55. }
  56. if (korName.Length > 200)
  57. {
  58. throw new ArgumentOutOfRangeException(nameof(korName));
  59. }
  60. if (string.IsNullOrWhiteSpace(engName))
  61. {
  62. throw new ArgumentException("EngName is required.", nameof(engName));
  63. }
  64. if (engName.Length > 200)
  65. {
  66. throw new ArgumentOutOfRangeException(nameof(engName));
  67. }
  68. Symbol = symbol.ToUpper();
  69. KorName = korName;
  70. EngName = engName;
  71. Description = description;
  72. ContractAddress = contractAddress;
  73. WebsiteUrl = websiteUrl;
  74. WhitepaperUrl = whitepaperUrl;
  75. TwitterUrl = twitterUrl;
  76. TelegramUrl = telegramUrl;
  77. IsActive = isActive;
  78. IsWarning = isWarning;
  79. IsNew = isNew;
  80. IsDelisted = isDelisted;
  81. }
  82. public static Coin Create(
  83. string symbol,
  84. string korName,
  85. string engName,
  86. string? description = null,
  87. string? contractAddress = null,
  88. string? websiteUrl = null,
  89. string? whitepaperUrl = null,
  90. string? twitterUrl = null,
  91. string? telegramUrl = null,
  92. bool isActive = false,
  93. bool isWarning = false,
  94. bool isNew = false,
  95. bool isDelisted = false
  96. ) => new(symbol, korName, engName, description, contractAddress, websiteUrl, whitepaperUrl, twitterUrl, telegramUrl, isActive, isWarning, isNew, isDelisted);
  97. public void Update(
  98. string symbol,
  99. string korName,
  100. string engName,
  101. string? description,
  102. string? contractAddress,
  103. string? websiteUrl,
  104. string? whitepaperUrl,
  105. string? twitterUrl,
  106. string? telegramUrl,
  107. bool isActive,
  108. bool isWarning,
  109. bool isNew,
  110. bool isDelisted
  111. ) {
  112. if (string.IsNullOrWhiteSpace(symbol))
  113. {
  114. throw new ArgumentException("Symbol is required.", nameof(symbol));
  115. }
  116. if (symbol.Length > 30)
  117. {
  118. throw new ArgumentOutOfRangeException(nameof(symbol));
  119. }
  120. if (string.IsNullOrWhiteSpace(korName))
  121. {
  122. throw new ArgumentException("KorName is required.", nameof(korName));
  123. }
  124. if (korName.Length > 200)
  125. {
  126. throw new ArgumentOutOfRangeException(nameof(korName));
  127. }
  128. if (string.IsNullOrWhiteSpace(engName))
  129. {
  130. throw new ArgumentException("EngName is required.", nameof(engName));
  131. }
  132. if (engName.Length > 200)
  133. {
  134. throw new ArgumentOutOfRangeException(nameof(engName));
  135. }
  136. Symbol = symbol.ToUpper();
  137. KorName = korName;
  138. EngName = engName;
  139. Description = description;
  140. ContractAddress = contractAddress;
  141. WebsiteUrl = websiteUrl;
  142. WhitepaperUrl = whitepaperUrl;
  143. TwitterUrl = twitterUrl;
  144. TelegramUrl = telegramUrl;
  145. IsActive = isActive;
  146. IsWarning = isWarning;
  147. IsNew = isNew;
  148. IsDelisted = isDelisted;
  149. UpdatedAt = DateTime.UtcNow;
  150. }
  151. public void SetLogoImage(string? logoImage)
  152. {
  153. LogoImage = logoImage;
  154. UpdatedAt = DateTime.UtcNow;
  155. }
  156. public void SetCuration(bool isFeatured, short displayOrder)
  157. {
  158. IsFeatured = isFeatured;
  159. DisplayOrder = displayOrder;
  160. UpdatedAt = DateTime.UtcNow;
  161. }
  162. // Upbit 마켓 데이터로 동기화 (신규 생성용)
  163. public static Coin SyncFromUpbit(string symbol, string korName, string engName, bool isWarning)
  164. {
  165. return new(symbol, korName, engName, null, null, null, null, null, null, isActive: true, isWarning, isNew: false, isDelisted: false);
  166. }
  167. // 상장폐지 처리
  168. public void MarkDelisted()
  169. {
  170. IsDelisted = true;
  171. IsActive = false;
  172. UpdatedAt = DateTime.UtcNow;
  173. }
  174. // 동기화 (이름/경고 상태 갱신, 상폐 해제)
  175. public void SyncUpdate(string korName, string engName, bool isWarning)
  176. {
  177. KorName = korName;
  178. EngName = engName;
  179. IsWarning = isWarning;
  180. if (IsDelisted)
  181. {
  182. IsDelisted = false;
  183. IsActive = true;
  184. }
  185. UpdatedAt = DateTime.UtcNow;
  186. }
  187. }
  188. }