using System.ComponentModel.DataAnnotations; using Domain.Entities.Common.ValueObject; using Domain.Entities.Wallets.ValueObject; namespace Domain.Entities.Wallets; public class WalletBalance { [Key] public int ID { get; private set; } public Guid WalletKey { get; private set; } public WalletBalanceType Type { get; private set; } public Money Amount { get; private set; } = Money.KRW(0); /// 동시 갱신 감지용 rowversion — 이중 지출 방지 (last-write-wins 차단) public byte[] RowVersion { get; private set; } = []; private WalletBalance() { } private WalletBalance(Guid walletKey, WalletBalanceType type, Money initial) { if (walletKey == Guid.Empty) { throw new ArgumentException("WalletKey is required.", nameof(walletKey)); } WalletKey = walletKey; Type = type; Amount = initial; } public static WalletBalance Create(Guid walletKey, WalletBalanceType type, string currency = "KRW") { return new(walletKey, type, Money.Zero(currency)); } public void Increase(Money amount) { EnsurePositive(amount); Amount = Amount + amount; } public void Decrease(Money amount) { EnsurePositive(amount); if (Amount.Value < amount.Value) { throw new InvalidOperationException("Insufficient balance."); } Amount = Amount - amount; } private static void EnsurePositive(Money amount) { if (amount.IsZero || amount.Value <= 0) { throw new ArgumentException("Amount must be positive.", nameof(amount)); } } }