ListByGame.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using MediatR;
  2. using Web.Api.Common;
  3. using Web.Api.Extensions;
  4. namespace Web.Api.Endpoints.V1.Coupons;
  5. internal sealed class ListByGame : IEndpoint
  6. {
  7. public void MapEndpoint(IEndpointRouteBuilder app)
  8. {
  9. app.MapGet("v1/games/{gameID:int}/coupons", async (
  10. int gameID,
  11. ISender sender,
  12. CancellationToken ct,
  13. int? couponID = null,
  14. int page = 1,
  15. int limit = 100
  16. ) => {
  17. var query = new Application.Features.Api.V1.Coupons.ListByGame.Query(gameID, couponID, page, limit);
  18. var result = await sender.Send(query, ct);
  19. return result.Match(
  20. data => ApiResponse.Ok(data),
  21. CustomResults.Problem
  22. );
  23. })
  24. .WithTags("쿠폰")
  25. .WithGroupName("public")
  26. .WithName("ListGameCoupons")
  27. .WithSummary("게임 쿠폰 코드 대량 조회")
  28. .WithDescription("""
  29. 특정 게임에 발급된 **쿠폰 코드를 대량으로** 페이지네이션해 반환합니다.
  30. 각 코드의 사용 여부(`status`) + 발급/사용 일시가 함께 제공됩니다.
  31. ### 필수 scope
  32. - `read:coupons`
  33. ### 경로 변수
  34. - `gameID` — 게임 ID
  35. ### 쿼리 파라미터
  36. | 이름 | 타입 | 기본 | 설명 |
  37. |---|---|---|---|
  38. | `couponID` | int? | null | 특정 쿠폰의 코드만 필터 (생략 시 게임 전체) |
  39. | `page` | int | 1 | 1부터 시작 |
  40. | `limit` | int | 100 | 1~500 |
  41. ### Status 값
  42. | 값 | 의미 |
  43. |---|---|
  44. | `1` | Available (미발급) |
  45. | `2` | Reserved (결제 진행 중) |
  46. | `3` | Issued (발급됨) |
  47. | `4` | Used (사용 완료) |
  48. | `5` | Expired (만료) |
  49. """)
  50. .Produces<ApiResponse>(StatusCodes.Status200OK)
  51. .ProducesProblem(StatusCodes.Status400BadRequest)
  52. .ProducesProblem(StatusCodes.Status401Unauthorized)
  53. .ProducesProblem(StatusCodes.Status403Forbidden)
  54. .ProducesProblem(StatusCodes.Status404NotFound)
  55. .RequireAuthorization(policy => policy
  56. .AddAuthenticationSchemes("ApiKey", "OAuth2Bearer")
  57. .RequireAuthenticatedUser())
  58. .RequireScope("read:coupons");
  59. }
  60. }