Handler.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Donations;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Api.Crew.StartSession;
  6. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Response>
  7. {
  8. public async Task<Response> Handle(Command request, CancellationToken ct)
  9. {
  10. var crew = await db.Crew
  11. .Include(c => c.Members.Where(m => m.IsActive))
  12. .FirstOrDefaultAsync(c => c.ID == request.CrewID && c.IsActive, ct);
  13. if (crew is null)
  14. {
  15. throw new KeyNotFoundException("크루를 찾을 수 없습니다.");
  16. }
  17. if (!crew.Members.Any())
  18. {
  19. throw new InvalidOperationException("크루원이 없습니다.");
  20. }
  21. // 이미 진행 중인 세션이 있는지 확인
  22. var activeSession = await db.CrewSession
  23. .AnyAsync(s => s.CrewID == request.CrewID && s.Status != Domain.Entities.Donations.ValueObject.CrewSessionStatus.Ended, ct);
  24. if (activeSession)
  25. {
  26. throw new InvalidOperationException("이미 진행 중인 크루 방송이 있습니다.");
  27. }
  28. // 세션 생성 (Inviting)
  29. var session = CrewSession.Create(request.CrewID, request.Title);
  30. db.CrewSession.Add(session);
  31. await db.SaveChangesAsync(ct);
  32. // 각 크루원에 대해 동의 레코드 생성
  33. foreach (var member in crew.Members)
  34. {
  35. var consent = CrewSessionConsent.Create(session.ID, member.ID);
  36. db.CrewSessionConsent.Add(consent);
  37. // 크루원별 집계 초기화
  38. var summary = CrewDonationSummary.Create(session.ID, member.ID);
  39. db.CrewDonationSummary.Add(summary);
  40. }
  41. await db.SaveChangesAsync(ct);
  42. // 알림/쪽지 발송은 Endpoint에서 SignalR + NotificationService로 처리
  43. return new Response(session.ID);
  44. }
  45. }