using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.V1.Coupons.ListByGame; internal sealed class Handler(IAppDbContext db) : IQueryHandler> { public async Task> Handle(Query request, CancellationToken ct) { if (request.GameID <= 0) { return Result.Failure(Error.Problem("Game.Required", "gameID 는 필수입니다.")); } var game = await db.Game .AsNoTracking() .Where(c => c.ID == request.GameID) .Select(c => new { c.ID, c.KorName }) .FirstOrDefaultAsync(ct); if (game is null) { return Result.Failure(Error.NotFound("Game.NotFound", "해당 게임을 찾을 수 없습니다.")); } var page = Math.Max(1, request.Page); var limit = Math.Clamp(request.Limit, 1, 500); var baseQuery = db.CouponCode .AsNoTracking() .Where(c => c.Coupon!.GameID == request.GameID); if (request.CouponID is int couponID && couponID > 0) { baseQuery = baseQuery.Where(c => c.CouponID == couponID); } var total = await baseQuery.CountAsync(ct); var items = await baseQuery .OrderByDescending(c => c.ID) .Skip((page - 1) * limit) .Take(limit) .Select(c => new Response.Row( c.ID, c.CouponID, c.Coupon!.Name, c.Code, (int)c.Status, c.IssuedAt, c.UsedAt )) .ToListAsync(ct); return Result.Success(new Response(game.ID, game.KorName, total, page, limit, items)); } }