Handler.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Abstractions.YouTube;
  4. using Microsoft.EntityFrameworkCore;
  5. using Microsoft.Extensions.Options;
  6. using SharedKernel;
  7. namespace Application.Features.Admin.Channel.YouTubePubSub.Get;
  8. internal sealed class Handler(
  9. IAppDbContext db,
  10. IYouTubePubSubService pubSubService,
  11. IOptions<AppSettings> settings
  12. ) : IQueryHandler<Query, Response>
  13. {
  14. public async Task<Response> Handle(Query request, CancellationToken ct)
  15. {
  16. var subscribedIds = (await pubSubService.GetSubscribedChannelIdsAsync(ct)).ToHashSet();
  17. // DB의 YouTube 연동 채널 전체 (활성/비활성 모두)
  18. var channels = await db.Channel.AsNoTracking()
  19. .Where(c => c.YouTubeChannelID != null && c.YouTubeChannelID != "")
  20. .OrderByDescending(c => c.IsActive)
  21. .ThenBy(c => c.Name)
  22. .Select(c => new
  23. {
  24. c.ID,
  25. c.YouTubeChannelID,
  26. c.Name,
  27. c.Handle,
  28. c.ThumbnailUrl,
  29. c.IsActive
  30. })
  31. .ToListAsync(ct);
  32. var items = new List<SubscriptionItem>(channels.Count + subscribedIds.Count);
  33. var coveredIds = new HashSet<string>();
  34. // DB 채널 기준 표시 (구독 여부 표시)
  35. foreach (var c in channels)
  36. {
  37. var ytId = c.YouTubeChannelID!;
  38. items.Add(new SubscriptionItem(
  39. ytId,
  40. c.ID,
  41. c.Name,
  42. c.Handle,
  43. c.ThumbnailUrl,
  44. true,
  45. c.IsActive,
  46. subscribedIds.Contains(ytId)
  47. ));
  48. coveredIds.Add(ytId);
  49. }
  50. // DB에 없는데 Redis Set에 남아있는 "고아 구독" 표시
  51. foreach (var ytId in subscribedIds.Where(id => !coveredIds.Contains(id)))
  52. {
  53. items.Add(new SubscriptionItem(ytId, null, null, null, null, false, false, true));
  54. }
  55. var subscribedCount = items.Count(x => x.IsSubscribed);
  56. return new Response(items, items.Count, subscribedCount, settings.Value.YouTube.CallbackUrl);
  57. }
  58. }