MemberDailyRewardCounter.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. using Domain.Entities.Members.ValueObject;
  2. namespace Domain.Entities.Members;
  3. /// <summary>
  4. /// 일일 보상 캡 원장 (d3 §③). 복합 PK (MemberID, RewardDate[KST 기준일], ActionType).
  5. /// 액션별 오늘 지급된 횟수/경험치/포인트를 누적하며 RewardService 가 UPSERT(원자적 UPDATE 우선)로 갱신한다.
  6. /// Redis 아닌 DB 로 두어 감사 가능·재시작 안전을 확보한다.
  7. /// </summary>
  8. public class MemberDailyRewardCounter
  9. {
  10. public int MemberID { get; private set; }
  11. /// <summary>KST 기준 일자 (date). 일 경계로 캡을 리셋한다.</summary>
  12. public DateOnly RewardDate { get; private set; }
  13. public RewardActionType ActionType { get; private set; }
  14. /// <summary>오늘 이 액션으로 지급된 횟수</summary>
  15. public int Count { get; private set; }
  16. /// <summary>오늘 이 액션으로 지급된 경험치 합계</summary>
  17. public int ExpTotal { get; private set; }
  18. /// <summary>오늘 이 액션으로 지급된 포인트(토큰) 합계</summary>
  19. public int PointTotal { get; private set; }
  20. private MemberDailyRewardCounter() { }
  21. private MemberDailyRewardCounter(int memberID, DateOnly rewardDate, RewardActionType actionType)
  22. {
  23. if (memberID <= 0)
  24. {
  25. throw new ArgumentOutOfRangeException(nameof(memberID));
  26. }
  27. MemberID = memberID;
  28. RewardDate = rewardDate;
  29. ActionType = actionType;
  30. }
  31. public static MemberDailyRewardCounter Create(int memberID, DateOnly rewardDate, RewardActionType actionType)
  32. {
  33. return new(memberID, rewardDate, actionType);
  34. }
  35. /// <summary>지급분을 누적한다 (신규 row 생성 후 첫 지급 반영용).</summary>
  36. public void Add(int expDelta, int pointDelta)
  37. {
  38. Count++;
  39. ExpTotal += expDelta;
  40. PointTotal += pointDelta;
  41. }
  42. }