Handler.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using Application.Abstractions.Channels;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Messaging;
  4. using Application.Abstractions.YouTube;
  5. using Microsoft.EntityFrameworkCore;
  6. using SharedKernel.Results;
  7. namespace Application.Features.Api.Channel.Get;
  8. public sealed class Handler(IAppDbContext db, IYouTubeLiveStateStore liveStateStore, IYouTubeChannelCache channelCache) : IQueryHandler<Query, Result<Response>>
  9. {
  10. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  11. {
  12. var resolved = await ChannelIdentifierResolver.ResolveAsync(db, request.Identifier, ct);
  13. if (resolved.ChannelSID is null)
  14. {
  15. return Result.Failure<Response>(Error.NotFound("Channel.NotFound", "채널을 찾을 수 없습니다."));
  16. }
  17. var channel = await db.Channel.AsNoTracking()
  18. .Where(c => c.SID == resolved.ChannelSID && c.IsActive)
  19. .Select(c => new
  20. {
  21. c.MemberID,
  22. c.SID,
  23. MemberSID = c.Member.SID,
  24. c.Name,
  25. c.Handle,
  26. c.YouTubeUrl,
  27. c.IsVerified
  28. })
  29. .FirstOrDefaultAsync(ct);
  30. if (channel is null)
  31. {
  32. return Result.Failure<Response>(Error.NotFound("Channel.NotFound", "채널을 찾을 수 없습니다."));
  33. }
  34. var liveInfo = await liveStateStore.GetLiveAsync(channel.SID);
  35. var ytInfo = await channelCache.GetAsync(channel.SID);
  36. return new Response(
  37. channel.MemberID,
  38. channel.SID,
  39. channel.MemberSID,
  40. channel.Name,
  41. channel.Handle,
  42. channel.YouTubeUrl,
  43. ytInfo?.ThumbnailUrl,
  44. ytInfo?.BannerUrl,
  45. ytInfo?.Description,
  46. ytInfo?.SubscriberCount ?? 0,
  47. ytInfo?.VideoCount ?? 0,
  48. channel.IsVerified,
  49. liveInfo is not null,
  50. liveInfo?.VideoId,
  51. liveInfo?.Title,
  52. liveInfo?.ViewerCount ?? 0
  53. );
  54. }
  55. }