GetCode.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using MediatR;
  2. using Web.Api.Common;
  3. using Web.Api.Extensions;
  4. namespace Web.Api.Endpoints.V1.Coupons;
  5. internal sealed class GetCode : IEndpoint
  6. {
  7. public void MapEndpoint(IEndpointRouteBuilder app)
  8. {
  9. app.MapGet("v1/coupons/codes/{code}", async (
  10. string code,
  11. ISender sender,
  12. CancellationToken ct
  13. ) => {
  14. var query = new Application.Features.Api.V1.Coupons.GetCode.Query(code);
  15. var result = await sender.Send(query, ct);
  16. return result.Match(
  17. data => ApiResponse.Ok(data),
  18. CustomResults.Problem
  19. );
  20. })
  21. .WithTags("쿠폰")
  22. .WithGroupName("public")
  23. .WithName("GetCouponCode")
  24. .WithSummary("쿠폰 코드 상세 조회")
  25. .WithDescription("""
  26. 단일 쿠폰 코드의 **사용 여부 / 상태 / 사용 일시**를 반환합니다.
  27. - **등록일시는 의도적으로 제공하지 않습니다** (보안/사용자 요구).
  28. - 상태(`status`) + 발급일(`issuedAt`) + 사용일(`usedAt`) 만 노출.
  29. ### 필수 scope
  30. - `read:coupons`
  31. ### 경로 변수
  32. - `code` — 쿠폰 코드 평문 (예: `ABCD-1234-EFGH-5678`)
  33. - 서버 측에서 SHA-256 해시 후 검색하므로 평문이 로그에 남지 않습니다.
  34. ### Status 값
  35. | 값 | 라벨 | 의미 |
  36. |---|---|---|
  37. | `1` | 미발급 | Available — 결제 가능 |
  38. | `2` | 결제 진행 중 | Reserved — 점유됨 |
  39. | `3` | 발급됨 | Issued — 회원 보관함 |
  40. | `4` | 사용 완료 | Used — 사용 처리됨 |
  41. | `5` | 만료 | Expired — 관리자 만료 |
  42. ### 에러
  43. - `400` — code 누락
  44. - `404` — 해당 코드 없음
  45. """)
  46. .Produces<ApiResponse>(StatusCodes.Status200OK)
  47. .ProducesProblem(StatusCodes.Status400BadRequest)
  48. .ProducesProblem(StatusCodes.Status401Unauthorized)
  49. .ProducesProblem(StatusCodes.Status403Forbidden)
  50. .ProducesProblem(StatusCodes.Status404NotFound)
  51. .RequireAuthorization(policy => policy
  52. .AddAuthenticationSchemes("ApiKey", "OAuth2Bearer")
  53. .RequireAuthenticatedUser())
  54. .RequireScope("read:coupons");
  55. }
  56. }