Handler.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using SharedKernel.Results;
  4. using Domain.Entities.Donations;
  5. using Domain.Entities.Donations.ValueObject;
  6. using Microsoft.EntityFrameworkCore;
  7. namespace Application.Features.Api.DonationRemote.PlayNow;
  8. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<Response>>
  9. {
  10. public async Task<Result<Response>> Handle(Command r, CancellationToken ct)
  11. {
  12. var alert = await db.DonationAlert.Include(a => a.Donation).ThenInclude(d => d!.Channel).Include(a => a.Donation).ThenInclude(d => d!.CrewMember).FirstOrDefaultAsync(a => a.ID == r.AlertID, ct);
  13. if (alert is null || alert.Donation is null || alert.Donation.Channel is null)
  14. {
  15. return Result.Failure<Response>(Error.NotFound("DonationAlert.NotFound", "알림을 찾을 수 없습니다."));
  16. }
  17. if (alert.Donation.Channel.MemberID != r.RequesterMemberID)
  18. {
  19. return Result.Failure<Response>(Error.Forbidden("Remote.Forbidden", "권한이 없습니다."));
  20. }
  21. // Failed/Skipped/Ignored/Delivered → Queued 로 되돌림 (재생을 위해)
  22. if (alert.Status is AlertStatus.Failed or AlertStatus.Skipped)
  23. {
  24. alert.Resend();
  25. }
  26. else if (alert.Status is AlertStatus.Ignored or AlertStatus.Delivered)
  27. {
  28. // 도메인 메서드 없음 → Resend가 두 케이스만 허용. 새 Attempt 생성으로 우회.
  29. // Alert 새로 생성하지 않고 단순 SignalR broadcast로 재생 트리거
  30. }
  31. var attempt = DonationAlertAttempt.Create(alert.DonationID, alert.ID);
  32. await db.DonationAlertAttempt.AddAsync(attempt, ct);
  33. await db.SaveChangesAsync(ct);
  34. return Result.Success(new Response(
  35. alert.ID,
  36. alert.DonationID,
  37. alert.CorrelationID,
  38. alert.Donation.SendName,
  39. alert.Donation.Amount,
  40. alert.Donation.NetAmount,
  41. alert.Donation.Message,
  42. alert.Donation.ChannelID,
  43. alert.Donation.Channel.Name,
  44. alert.Donation.Channel.WidgetToken!,
  45. alert.Donation.CrewMemberID,
  46. alert.Donation.CrewMember?.Nickname,
  47. alert.Donation.IsTest
  48. ));
  49. }
  50. }