using Application.Abstractions.Data; using Domain.Entities.Members.Logs; using Domain.Entities.Members.ValueObject; using Domain.Entities.Store.ValueObject; using Microsoft.EntityFrameworkCore; namespace Application.Helpers; /// /// 소모품 아이템을 컨텍스트(쪽지 발송·프로필 변경) 안에서 소모하는 공용 헬퍼. /// SaveChanges 는 호출측 트랜잭션에 위임 (원자성 보장). /// public static class MemberItemConsumer { public static Task HasAvailableAsync(IAppDbContext db, int memberID, ItemKind kind, CancellationToken ct) { return db.MemberItem.AnyAsync(x => x.MemberID == memberID && x.Kind == kind && x.UsedAt == null && x.RevokedAt == null, ct); } /// 사용 가능한 해당 종류 아이템 1개를 소모하고 로그를 남긴다. 성공 시 true (SaveChanges 미호출). public static async Task TryConsumeAsync(IAppDbContext db, int memberID, ItemKind kind, DateTime nowUtc, string? detail, CancellationToken ct) { var item = await db.MemberItem .Where(x => x.MemberID == memberID && x.Kind == kind && x.UsedAt == null && x.RevokedAt == null) .OrderBy(x => x.ID) .FirstOrDefaultAsync(ct); if (item is null) { return false; } item.MarkUsed(nowUtc); db.MemberItemUsageLog.Add(MemberItemUsageLog.Create(item.MemberID, item.ID, item.ProductID, item.Kind, MemberItemUsageAction.Used, detail)); return true; } }