Handler.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. using SharedKernel.Results;
  5. namespace Application.Features.Api.V1.Coupons.ListByGame;
  6. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  7. {
  8. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  9. {
  10. if (request.GameID <= 0)
  11. {
  12. return Result.Failure<Response>(Error.Problem("Game.Required", "gameID 는 필수입니다."));
  13. }
  14. var game = await db.Game
  15. .AsNoTracking()
  16. .Where(c => c.ID == request.GameID)
  17. .Select(c => new { c.ID, c.KorName })
  18. .FirstOrDefaultAsync(ct);
  19. if (game is null)
  20. {
  21. return Result.Failure<Response>(Error.NotFound("Game.NotFound", "해당 게임을 찾을 수 없습니다."));
  22. }
  23. var page = Math.Max(1, request.Page);
  24. var limit = Math.Clamp(request.Limit, 1, 500);
  25. var baseQuery = db.CouponCode
  26. .AsNoTracking()
  27. .Where(c => c.Coupon!.GameID == request.GameID);
  28. if (request.CouponID is int couponID && couponID > 0)
  29. {
  30. baseQuery = baseQuery.Where(c => c.CouponID == couponID);
  31. }
  32. var total = await baseQuery.CountAsync(ct);
  33. var items = await baseQuery
  34. .OrderByDescending(c => c.ID)
  35. .Skip((page - 1) * limit)
  36. .Take(limit)
  37. .Select(c => new Response.Row(
  38. c.ID,
  39. c.CouponID,
  40. c.Coupon!.Name,
  41. c.Code,
  42. (int)c.Status,
  43. c.IssuedAt,
  44. c.UsedAt
  45. ))
  46. .ToListAsync(ct);
  47. return Result.Success(new Response(game.ID, game.KorName, total, page, limit, items));
  48. }
  49. }