using Application.Abstractions.Hub; using Infrastructure.Hubs; using Web.Api.Common; using Web.Api.Extensions; using MediatR; using Microsoft.AspNetCore.SignalR; using System.Security.Claims; namespace Web.Api.Endpoints.Donation; /// 리모콘 — 재전송 (종결 상태 알림을 위젯 큐에 다시 push) internal sealed class RemoteResend : IEndpoint { public void MapEndpoint(IEndpointRouteBuilder app) { /// 실패/스킵/무시/완료된 알림을 다시 Queued 로 만들고 위젯에 broadcast. /// PlayNow 와 동일하게 ReceiveAlert 으로 위젯 큐 push. app.MapPost("api/donation/remote/resend/{alertID:int}", async ( int alertID, ClaimsPrincipal user, ISender sender, IHubContext donationHub, CancellationToken ct ) => { var memberID = user.GetRequiredMemberID(); var result = await sender.Send(new Application.Features.Api.DonationRemote.ResendAlert.Command(alertID, memberID), ct); if (result.IsFailure) { return CustomResults.Problem(result); } var data = result.Value; var alertPayload = new { alertID = data.AlertID, donationID = data.DonationID, correlationID = data.CorrelationID, sponsorMemberID = memberID, sendName = data.SendName, amount = data.Amount, netAmount = data.NetAmount, message = data.Message, channelID = data.ChannelID, channelName = data.ChannelName, crewMemberID = data.CrewMemberID, crewMemberNickname = data.CrewMemberNickname, isTest = data.IsTest, createdAt = DateTime.UtcNow }; await donationHub.Clients.Group(data.WidgetToken).ReceiveAlert(alertPayload); // 리모콘 측 status 즉시 동기화 await donationHub.Clients.Group(data.WidgetToken).ReceiveAlertStatusUpdate(new { alertID = data.AlertID, status = "queued" }); return ApiResponse.Ok(data); }) .WithTags("DonationRemote") .RequireAuthorization(); } }