using Application.Abstractions.Cache; using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Application.Helpers; using Domain.Entities.Members.Logs; using Domain.Entities.Store.ValueObject; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; using SharedKernel.Storage; namespace Application.Features.Api.MyPage.ChangeThumb; internal sealed class Handler( IAppDbContext db, IFileStorage fileStorage, ICacheService cache ) : ICommandHandler> { public async Task> Handle(Command request, CancellationToken ct) { var member = await db.Member.FirstOrDefaultAsync(m => m.ID == request.MemberID, ct); if (member is null) { return Result.Failure(Error.NotFound("MyPage.MemberNotFound", "회원 정보를 찾을 수 없습니다.")); } // 프로필 이미지 변경 주기 확인 (프로필 이미지 변경권으로 즉시 우회) var now = DateTime.UtcNow; var accountConfig = await AccountConfigLoader.GetAccountConfigAsync(cache, db, ct); if (accountConfig.ChangeThumbDay is > 0 && member.LastThumbChangedAt.HasValue) { var nextChangeDate = member.LastThumbChangedAt.Value.AddDays(accountConfig.ChangeThumbDay.Value); if (now < nextChangeDate) { if (!await MemberItemConsumer.TryConsumeAsync(db, request.MemberID, ItemKind.ProfileImageChange, now, "프로필 이미지 변경권 사용", ct)) { return Result.Failure(Error.Problem("MyPage.ThumbChangeTooSoon", $"프로필 이미지는 {accountConfig.ChangeThumbDay}일마다 변경 가능합니다. (변경권으로 즉시 변경 가능)")); } } } var beforeThumb = member.Thumb; // 기존 사진 삭제 if (!string.IsNullOrEmpty(member.Thumb)) { fileStorage.DeleteByUrl(member.Thumb); } string? thumbUrl = null; if (request.Thumb is not null && request.Thumb.Length > 0) { FileStoragePath uploadPath = new(UploadTarget.Upload, UploadFolder.MemberThumb, request.MemberID); string[] allowedExtensions = [".jpg", ".jpeg", ".png", ".gif", ".webp"]; var result = await fileStorage.SaveFileAsync(request.Thumb, uploadPath, allowedExtensions, ct); thumbUrl = result?.Url; } member.SetThumb(thumbUrl); db.MemberThumbChangeLog.Add(MemberThumbChangeLog.Create(request.MemberID, beforeThumb, thumbUrl)); await db.SaveChangesAsync(ct); return Result.Success(thumbUrl); } }