Handler.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Abstractions.YouTube;
  4. using Microsoft.EntityFrameworkCore;
  5. using Microsoft.Extensions.Logging;
  6. namespace Application.Features.Api.Studio.DisconnectYouTube;
  7. internal sealed class Handler(
  8. IAppDbContext db,
  9. IYouTubeChannelCache channelCache,
  10. IGoogleOAuthService oauthService,
  11. ILogger<Handler> logger
  12. ) : ICommandHandler<Command>
  13. {
  14. public async Task Handle(Command request, CancellationToken ct)
  15. {
  16. var channel = await db.Channel.FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct);
  17. if (channel is null)
  18. {
  19. throw new InvalidOperationException("연동된 채널이 없습니다.");
  20. }
  21. // OAuth 토큰 조회 → revoke → 삭제
  22. var oauthToken = await db.MemberOAuthToken.FirstOrDefaultAsync(t => t.MemberID == request.MemberID && t.Provider == "YouTube", ct);
  23. if (oauthToken is not null)
  24. {
  25. // Google OAuth revoke (실패해도 무시)
  26. await oauthService.RevokeTokenAsync(oauthToken.AccessTokenEnc, ct);
  27. db.MemberOAuthToken.Remove(oauthToken);
  28. }
  29. // 채널 비활성화
  30. channel.Deactivate();
  31. // Redis 캐시 삭제
  32. var cacheKey = channel.YouTubeChannelID ?? channel.SID;
  33. await channelCache.RemoveAsync(cacheKey);
  34. await db.SaveChangesAsync(ct);
  35. logger.LogInformation("YouTube 연동 해지: MemberID={MemberID}, ChannelID={ChannelID}", request.MemberID, channel.ID);
  36. }
  37. }