Handler.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System.Security.Cryptography;
  2. using System.Text;
  3. using Application.Abstractions.Data;
  4. using Application.Abstractions.Messaging;
  5. using Domain.Entities.Store.ValueObject;
  6. using Microsoft.EntityFrameworkCore;
  7. using SharedKernel.Results;
  8. namespace Application.Features.Api.V1.Coupons.GetCode;
  9. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  10. {
  11. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  12. {
  13. if (string.IsNullOrWhiteSpace(request.Code))
  14. {
  15. return Result.Failure<Response>(Error.Problem("Coupon.CodeRequired", "쿠폰 코드는 필수입니다."));
  16. }
  17. var codeHash = ComputeHash(request.Code.Trim());
  18. var row = await db.CouponCode
  19. .AsNoTracking()
  20. .Where(c => c.CodeHash == codeHash)
  21. .Select(c => new
  22. {
  23. c.Code,
  24. c.CouponID,
  25. CouponName = c.Coupon!.Name,
  26. c.Status,
  27. c.IssuedAt,
  28. c.UsedAt
  29. })
  30. .FirstOrDefaultAsync(ct);
  31. if (row is null)
  32. {
  33. return Result.Failure<Response>(Error.NotFound("Coupon.CodeNotFound", "해당 쿠폰 코드를 찾을 수 없습니다."));
  34. }
  35. var label = row.Status switch
  36. {
  37. CouponCodeStatus.Available => "미발급",
  38. CouponCodeStatus.Reserved => "결제 진행 중",
  39. CouponCodeStatus.Issued => "발급됨",
  40. CouponCodeStatus.Used => "사용 완료",
  41. CouponCodeStatus.Expired => "만료",
  42. _ => row.Status.ToString()
  43. };
  44. return Result.Success(new Response(
  45. row.Code, row.CouponID, row.CouponName,
  46. (int)row.Status, label, row.IssuedAt, row.UsedAt
  47. ));
  48. }
  49. private static string ComputeHash(string code)
  50. {
  51. var bytes = Encoding.UTF8.GetBytes(code);
  52. var hash = SHA256.HashData(bytes);
  53. return Convert.ToHexString(hash);
  54. }
  55. }