CrewSessionConsent.cs 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using Application.Abstractions.Hub;
  2. using Infrastructure.Hubs;
  3. using Web.Api.Common;
  4. using MediatR;
  5. using Microsoft.AspNetCore.SignalR;
  6. namespace Web.Api.Endpoints.Donation;
  7. /// <summary>크루원 참여 동의 — 동의 후 전원 동의 시 세션 활성화</summary>
  8. internal sealed class CrewSessionConsent : IEndpoint
  9. {
  10. public void MapEndpoint(IEndpointRouteBuilder app)
  11. {
  12. app.MapPost("api/crew/session/consent", async (
  13. Application.Features.Api.Crew.ConsentSession.Command body,
  14. ISender sender,
  15. IHubContext<AppHub, IAppHubClient> appHub,
  16. Application.Abstractions.Data.IAppDbContext db,
  17. CancellationToken ct
  18. ) => {
  19. var data = await sender.Send(body, ct);
  20. // 세션의 크루 채널SID 조회
  21. var session = await Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  22. .FirstOrDefaultAsync(
  23. Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  24. .AsNoTracking(db.CrewSession)
  25. .Where(s => s.ID == body.CrewSessionID),
  26. ct
  27. );
  28. if (session is not null)
  29. {
  30. var crew = await Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  31. .FirstOrDefaultAsync(
  32. Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  33. .AsNoTracking(db.Crew)
  34. .Where(c => c.ID == session.CrewID),
  35. ct
  36. );
  37. if (crew is not null)
  38. {
  39. var channel = await Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  40. .FirstOrDefaultAsync(
  41. Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  42. .AsNoTracking(db.Channel)
  43. .Where(c => c.ID == crew.ChannelID),
  44. ct
  45. );
  46. var channelSID = channel?.SID ?? "";
  47. // 동의 현황 브로드캐스트 (크루장에게)
  48. var consents = await Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  49. .ToListAsync(
  50. Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
  51. .AsNoTracking(db.CrewSessionConsent)
  52. .Where(c => c.CrewSessionID == body.CrewSessionID)
  53. .Join(db.CrewMember, c => c.CrewMemberID, m => m.ID, (c, m) => new {
  54. c.CrewMemberID, m.Nickname, c.IsConsented, c.ConsentedAt
  55. }),
  56. ct
  57. );
  58. await appHub.Clients.Group($"channel:{channelSID}").ReceiveCrewConsentUpdate(new
  59. {
  60. CrewSessionID = body.CrewSessionID,
  61. Consents = consents,
  62. AllConsented = data.AllConsented
  63. });
  64. // 전원 동의 시 세션 시작 브로드캐스트
  65. if (data.AllConsented)
  66. {
  67. await appHub.Clients.Group($"channel:{channelSID}").ReceiveCrewStarted(new
  68. {
  69. CrewSessionID = body.CrewSessionID,
  70. Title = session.Title,
  71. CrewName = crew.Name
  72. });
  73. }
  74. }
  75. }
  76. return ApiResponse.Ok(data);
  77. })
  78. .WithTags("Crew")
  79. .RequireAuthorization();
  80. }
  81. }