Handler.cs 2.2 KB

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