using Application.Abstractions.Channels; using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Application.Abstractions.YouTube; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Channel.Get; public sealed class Handler(IAppDbContext db, IYouTubeLiveStateStore liveStateStore, IYouTubeChannelCache channelCache) : IQueryHandler> { public async Task> Handle(Query request, CancellationToken ct) { var resolved = await ChannelIdentifierResolver.ResolveAsync(db, request.Identifier, ct); if (resolved.ChannelSID is null) { return Result.Failure(Error.NotFound("Channel.NotFound", "채널을 찾을 수 없습니다.")); } var channel = await db.Channel.AsNoTracking() .Where(c => c.SID == resolved.ChannelSID && c.IsActive) .Select(c => new { c.MemberID, c.SID, MemberSID = c.Member.SID, c.Name, c.Handle, c.YouTubeUrl, c.IsVerified }) .FirstOrDefaultAsync(ct); if (channel is null) { return Result.Failure(Error.NotFound("Channel.NotFound", "채널을 찾을 수 없습니다.")); } var liveInfo = await liveStateStore.GetLiveAsync(channel.SID); var ytInfo = await channelCache.GetAsync(channel.SID); return new Response( channel.MemberID, channel.SID, channel.MemberSID, channel.Name, channel.Handle, channel.YouTubeUrl, ytInfo?.ThumbnailUrl, ytInfo?.BannerUrl, ytInfo?.Description, ytInfo?.SubscriberCount ?? 0, ytInfo?.VideoCount ?? 0, channel.IsVerified, liveInfo is not null, liveInfo?.VideoId, liveInfo?.Title, liveInfo?.ViewerCount ?? 0 ); } }