using Domain.Entities.Members.ValueObject; namespace Domain.Entities.Members; /// /// 일일 보상 캡 원장 (d3 §③). 복합 PK (MemberID, RewardDate[KST 기준일], ActionType). /// 액션별 오늘 지급된 횟수/경험치/포인트를 누적하며 RewardService 가 UPSERT(원자적 UPDATE 우선)로 갱신한다. /// Redis 아닌 DB 로 두어 감사 가능·재시작 안전을 확보한다. /// public class MemberDailyRewardCounter { public int MemberID { get; private set; } /// KST 기준 일자 (date). 일 경계로 캡을 리셋한다. public DateOnly RewardDate { get; private set; } public RewardActionType ActionType { get; private set; } /// 오늘 이 액션으로 지급된 횟수 public int Count { get; private set; } /// 오늘 이 액션으로 지급된 경험치 합계 public int ExpTotal { get; private set; } /// 오늘 이 액션으로 지급된 포인트(토큰) 합계 public int PointTotal { get; private set; } private MemberDailyRewardCounter() { } private MemberDailyRewardCounter(int memberID, DateOnly rewardDate, RewardActionType actionType) { if (memberID <= 0) { throw new ArgumentOutOfRangeException(nameof(memberID)); } MemberID = memberID; RewardDate = rewardDate; ActionType = actionType; } public static MemberDailyRewardCounter Create(int memberID, DateOnly rewardDate, RewardActionType actionType) { return new(memberID, rewardDate, actionType); } /// 지급분을 누적한다 (신규 row 생성 후 첫 지급 반영용). public void Add(int expDelta, int pointDelta) { Count++; ExpTotal += expDelta; PointTotal += pointDelta; } }