MemberItemConsumer.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. using Application.Abstractions.Data;
  2. using Domain.Entities.Members.Logs;
  3. using Domain.Entities.Members.ValueObject;
  4. using Domain.Entities.Store.ValueObject;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Helpers;
  7. /// <summary>
  8. /// 소모품 아이템을 컨텍스트(쪽지 발송·프로필 변경) 안에서 소모하는 공용 헬퍼.
  9. /// SaveChanges 는 호출측 트랜잭션에 위임 (원자성 보장).
  10. /// </summary>
  11. public static class MemberItemConsumer
  12. {
  13. public static Task<bool> HasAvailableAsync(IAppDbContext db, int memberID, ItemKind kind, CancellationToken ct)
  14. {
  15. return db.MemberItem.AnyAsync(x => x.MemberID == memberID && x.Kind == kind && x.UsedAt == null && x.RevokedAt == null, ct);
  16. }
  17. /// <summary>사용 가능한 해당 종류 아이템 1개를 소모하고 로그를 남긴다. 성공 시 true (SaveChanges 미호출).</summary>
  18. public static async Task<bool> TryConsumeAsync(IAppDbContext db, int memberID, ItemKind kind, DateTime nowUtc, string? detail, CancellationToken ct)
  19. {
  20. var item = await db.MemberItem
  21. .Where(x => x.MemberID == memberID && x.Kind == kind && x.UsedAt == null && x.RevokedAt == null)
  22. .OrderBy(x => x.ID)
  23. .FirstOrDefaultAsync(ct);
  24. if (item is null)
  25. {
  26. return false;
  27. }
  28. item.MarkUsed(nowUtc);
  29. db.MemberItemUsageLog.Add(MemberItemUsageLog.Create(item.MemberID, item.ID, item.ProductID, item.Kind, MemberItemUsageAction.Used, detail));
  30. return true;
  31. }
  32. }