Handler.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. using Application.Abstractions.Messaging;
  2. using Domain.Entities.Donations.ValueObject;
  3. using SharedKernel.Results;
  4. using SharedKernel.Storage;
  5. namespace Application.Features.Api.DonationAlert.UploadMedia;
  6. internal sealed class Handler(IFileStorage fileStorage) : ICommandHandler<Command, Result<string>>
  7. {
  8. private static readonly string[] ImageExtensions = [".jpg", ".jpeg", ".png", ".gif"];
  9. private static readonly string[] SoundExtensions = [".mp3", ".ogg", ".wav", ".m4a"];
  10. public async Task<Result<string>> Handle(Command r, CancellationToken ct)
  11. {
  12. var (extensions, maxSizeMB) = r.Type switch
  13. {
  14. "image" => (ImageExtensions, DonationConstants.Alert.MaxImageFileSizeMB),
  15. "sound" => (SoundExtensions, DonationConstants.Alert.MaxSoundFileSizeMB),
  16. _ => throw new ArgumentException("유효하지 않은 파일 타입입니다.")
  17. };
  18. if (r.File.Length > maxSizeMB * 1024 * 1024)
  19. {
  20. return Result.Failure<string>(Error.Problem("UploadMedia.FileTooLarge", $"파일 크기는 {maxSizeMB}MB 이하여야 합니다."));
  21. }
  22. var path = new FileStoragePath(UploadTarget.Upload, UploadFolder.DonationAlert, r.ChannelID);
  23. var result = await fileStorage.SaveFileAsync(r.File, path, extensions, ct);
  24. if (result is null)
  25. {
  26. return Result.Failure<string>(Error.Problem("UploadMedia.Failed", "파일 업로드에 실패했습니다. 허용된 확장자를 확인하세요."));
  27. }
  28. return Result.Success(result.Url);
  29. }
  30. }