| 1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- using CouponEntity = Domain.Entities.Store.Coupon;
- namespace Application.Features.Admin.Store.Coupon.Create;
- public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<int>>
- {
- public async Task<Result<int>> Handle(Command request, CancellationToken ct)
- {
- // Product 존재 + GameID 일치 검증 (사용자 정책: 게임 필수, 상품 필수)
- var product = await db.Product.AsNoTracking()
- .Where(p => p.ID == request.ProductID)
- .Select(p => new { p.ID, p.GameID })
- .FirstOrDefaultAsync(ct);
- if (product is null)
- {
- return Result.Failure<int>(Error.NotFound("Coupon.ProductNotFound", "선택한 상품이 없습니다."));
- }
- // GameID 가 Product 의 GameID 와 일치하지 않으면 경고 (UI 에서 자동 맞춰주지만 안전망)
- if (product.GameID != request.GameID)
- {
- return Result.Failure<int>(Error.Problem("Coupon.GameMismatch", "선택한 게임이 상품의 게임과 일치하지 않습니다."));
- }
- var coupon = CouponEntity.Create(
- productID: request.ProductID,
- gameID: request.GameID,
- name: request.Name,
- usagePolicy: request.UsagePolicy,
- expiresAt: request.ExpiresAt,
- lowStockThreshold: request.LowStockThreshold
- );
- db.Coupon.Add(coupon);
- await db.SaveChangesAsync(ct);
- return Result.Success(coupon.ID);
- }
- }
|