using Application.Abstractions.Data; using Application.Abstractions.Hub; using Application.Abstractions.Messaging; using Application.Abstractions.YouTube; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Admin.Channel.YouTubePubSub.ForceOffline; internal sealed class Handler( IAppDbContext db, IYouTubeLiveStateStore liveStateStore, IChannelStatusBroadcaster broadcaster ) : ICommandHandler { public async Task Handle(Command request, CancellationToken ct) { if (string.IsNullOrWhiteSpace(request.YouTubeChannelID)) { return Result.Failure(Error.Problem("ForceOffline.Invalid", "YouTube Channel ID 가 필요합니다.")); } var channel = await db.Channel.AsNoTracking() .FirstOrDefaultAsync(c => c.YouTubeChannelID == request.YouTubeChannelID, ct); if (channel is null) { return Result.Failure(Error.NotFound("ForceOffline.ChannelNotFound", "내부 Channel 을 찾을 수 없습니다.")); } await liveStateStore.ClearLiveAsync(request.YouTubeChannelID); await broadcaster.BroadcastAsync(channel.SID, isLive: false, viewerCount: 0, videoId: null, ct); return Result.Success(); } }