Handler.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using Application.Abstractions.Channels;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Messaging;
  4. using Domain.Entities.Donations.ValueObject;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.Crew.GetActiveCrewForChannel;
  7. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response?>
  8. {
  9. public async Task<Response?> Handle(Query request, CancellationToken ct)
  10. {
  11. var resolved = await ChannelIdentifierResolver.ResolveAsync(db, request.Identifier, ct);
  12. if (resolved.ChannelSID is null) return null;
  13. var channel = await db.Channel.AsNoTracking()
  14. .FirstOrDefaultAsync(c => c.SID == resolved.ChannelSID, ct);
  15. if (channel is null) return null;
  16. // 채널에 연결된 크루 중 Active 세션이 있는지 확인
  17. var session = await db.CrewSession.AsNoTracking()
  18. .Where(s => s.Status == CrewSessionStatus.Active)
  19. .Join(db.Crew.Where(c => c.ChannelID == channel.ID), s => s.CrewID, c => c.ID, (s, c) => new { Session = s, Crew = c })
  20. .FirstOrDefaultAsync(ct);
  21. if (session is null) return null;
  22. var members = await db.CrewDonationSummary.AsNoTracking()
  23. .Where(s => s.CrewSessionID == session.Session.ID)
  24. .Join(db.CrewMember, s => s.CrewMemberID, m => m.ID, (s, m) => new { Summary = s, Member = m })
  25. .OrderBy(x => x.Summary.Rank)
  26. .Select(x => new CrewMemberInfo(
  27. x.Member.ID,
  28. x.Member.Nickname,
  29. x.Member.Member != null ? x.Member.Member.Thumb : null,
  30. x.Member.Channel != null ? x.Member.Channel.Name : null
  31. ))
  32. .ToListAsync(ct);
  33. return new Response(
  34. session.Session.ID,
  35. session.Session.Title,
  36. session.Crew.Name,
  37. members
  38. );
  39. }
  40. }