WalletBalance.cs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using System.ComponentModel.DataAnnotations;
  2. using Domain.Entities.Common.ValueObject;
  3. using Domain.Entities.Wallets.ValueObject;
  4. namespace Domain.Entities.Wallets;
  5. public class WalletBalance
  6. {
  7. [Key]
  8. public int ID { get; private set; }
  9. public Guid WalletKey { get; private set; }
  10. public WalletBalanceType Type { get; private set; }
  11. public Money Amount { get; private set; } = Money.KRW(0);
  12. /// <summary>동시 갱신 감지용 rowversion — 이중 지출 방지 (last-write-wins 차단)</summary>
  13. public byte[] RowVersion { get; private set; } = [];
  14. private WalletBalance() { }
  15. private WalletBalance(Guid walletKey, WalletBalanceType type, Money initial)
  16. {
  17. if (walletKey == Guid.Empty)
  18. {
  19. throw new ArgumentException("WalletKey is required.", nameof(walletKey));
  20. }
  21. WalletKey = walletKey;
  22. Type = type;
  23. Amount = initial;
  24. }
  25. public static WalletBalance Create(Guid walletKey, WalletBalanceType type, string currency = "KRW")
  26. {
  27. return new(walletKey, type, Money.Zero(currency));
  28. }
  29. public void Increase(Money amount)
  30. {
  31. EnsurePositive(amount);
  32. Amount = Amount + amount;
  33. }
  34. public void Decrease(Money amount)
  35. {
  36. EnsurePositive(amount);
  37. if (Amount.Value < amount.Value)
  38. {
  39. throw new InvalidOperationException("Insufficient balance.");
  40. }
  41. Amount = Amount - amount;
  42. }
  43. private static void EnsurePositive(Money amount)
  44. {
  45. if (amount.IsZero || amount.Value <= 0)
  46. {
  47. throw new ArgumentException("Amount must be positive.", nameof(amount));
  48. }
  49. }
  50. }