using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Domain.Entities.Paper.ValueObject; namespace Domain.Entities.Paper; /// /// 모의투자 계좌 입출금 감사 원장 — 지갑 토큰 ↔ 계좌 토큰 이동 이력 (d4 §③). /// WalletTxRefID 로 지갑 거래(WalletTransaction.RefID)와 연결. /// public class PaperLedger { [ForeignKey(nameof(AccountID))] public virtual PaperAccount Account { get; private set; } = null!; [Key] public int ID { get; private set; } public int AccountID { get; private set; } public PaperLedgerType Type { get; private set; } /// 이동 토큰 (18,0) public decimal TokenAmount { get; private set; } /// 좌수 변화 (입금 +발행 / 출금 -소각, 18,8) public decimal UnitsDelta { get; private set; } /// 연결된 지갑 거래 RefID public string? WalletTxRefID { get; private set; } /// 이동 후 계좌 자유 토큰 잔액 public decimal BalanceAfter { get; private set; } public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; private PaperLedger() { } public static PaperLedger Create( int accountID, PaperLedgerType type, decimal tokenAmount, decimal unitsDelta, string? walletTxRefID, decimal balanceAfter ) { if (accountID <= 0) { throw new ArgumentOutOfRangeException(nameof(accountID)); } if (tokenAmount <= 0) { throw new ArgumentOutOfRangeException(nameof(tokenAmount)); } return new PaperLedger { AccountID = accountID, Type = type, TokenAmount = tokenAmount, UnitsDelta = unitsDelta, WalletTxRefID = walletTxRefID, BalanceAfter = balanceAfter }; } /// /// 신규 계좌(ID 미확정) 케이스 — Account 내비게이션으로 생성해 EF 가 저장 시 FK 를 자동 채우게 한다. /// public static PaperLedger CreateFor( PaperAccount account, PaperLedgerType type, decimal tokenAmount, decimal unitsDelta, string? walletTxRefID, decimal balanceAfter ) { ArgumentNullException.ThrowIfNull(account); if (tokenAmount <= 0) { throw new ArgumentOutOfRangeException(nameof(tokenAmount)); } return new PaperLedger { Account = account, Type = type, TokenAmount = tokenAmount, UnitsDelta = unitsDelta, WalletTxRefID = walletTxRefID, BalanceAfter = balanceAfter }; } }