|
4 | 4 | import com.blockguard.server.domain.guardian.domain.Guardian; |
5 | 5 | import com.blockguard.server.domain.guardian.dto.request.CreateGuardianRequest; |
6 | 6 | import com.blockguard.server.domain.guardian.dto.request.UpdateGuardianPrimaryRequest; |
| 7 | +import com.blockguard.server.domain.guardian.dto.request.UpdateGuardianRequest; |
7 | 8 | import com.blockguard.server.domain.guardian.dto.response.GuardianResponse; |
8 | 9 | import com.blockguard.server.domain.guardian.dto.response.GuardiansListResponse; |
9 | 10 | import com.blockguard.server.domain.user.domain.User; |
@@ -54,31 +55,63 @@ public GuardianResponse createGuardian(User user, CreateGuardianRequest request) |
54 | 55 | } |
55 | 56 |
|
56 | 57 | @Transactional |
57 | | - public GuardianResponse updateGuardian(User user, Long guardianId, CreateGuardianRequest request) { |
| 58 | + public GuardianResponse updateGuardian(User user, Long guardianId, UpdateGuardianRequest request) { |
58 | 59 | Guardian guardian = guardianRepository.findByIdAndUser(guardianId, user) |
59 | 60 | .orElseThrow(() -> new BusinessExceptionHandler(ErrorCode.GUARDIAN_NOT_FOUND)); |
60 | 61 |
|
61 | 62 | if (!guardian.getName().equals(request.getName()) && |
62 | 63 | guardianRepository.existsByUserAndNameAndDeletedAtIsNull(user, request.getName())) { |
63 | 64 | throw new BusinessExceptionHandler(ErrorCode.DUPLICATE_GUARDIAN_NAME); |
64 | 65 | } |
| 66 | + // 입력 플래그/파일 상태 |
| 67 | + final boolean wantDefault = Boolean.TRUE.equals(request.getIsDefaultImage()); |
| 68 | + final boolean hasNewFile = request.getProfileImage() != null && !request.getProfileImage().isEmpty(); |
65 | 69 |
|
66 | | - String key = null; |
67 | | - if (request.getProfileImage() != null && !request.getProfileImage().isEmpty()){ |
68 | | - // 새 이미지 업로드 |
69 | | - key = s3Service.upload(request.getProfileImage(), "guardians"); |
70 | | - // 예전 이미지 삭제 |
71 | | - if (guardian.getProfileImageKey() != null){ |
72 | | - s3Service.delete(guardian.getProfileImageKey()); |
73 | | - } |
| 70 | + // 기본이미지로 변경 + 새 파일 업로드 동시 요청 불가 |
| 71 | + if (wantDefault && hasNewFile) { |
| 72 | + throw new BusinessExceptionHandler(ErrorCode.UPDATE_PROFILE_CONFLICT); |
74 | 73 | } |
75 | | - guardian.updateGuardianInfo(request.getName(), request.getPhoneNumber(), key); |
76 | 74 |
|
77 | | - Guardian updated = guardianRepository.save(guardian); |
| 75 | + String currentKey = guardian.getProfileImageKey(); |
| 76 | + String nextKey = currentKey; |
78 | 77 |
|
| 78 | + // 기본 이미지로 변경하는 경우 |
| 79 | + if (wantDefault) { |
| 80 | + nextKey = null; |
| 81 | + // 커밋 후 기존 파일 삭제, 롤백 시 아무것도 안 함 |
| 82 | + registerAfterCommitDelete(currentKey, null); |
| 83 | + } |
| 84 | + // 새 이미지로 변경하는 경우 |
| 85 | + else if (hasNewFile) { |
| 86 | + // 새 이미지 업로드 |
| 87 | + String uploadedKey = s3Service.upload(request.getProfileImage(), "guardians"); |
| 88 | + nextKey = uploadedKey; |
| 89 | + // 커밋 후 기존 파일 삭제, 롤백 시 방금 올린 파일 삭제 |
| 90 | + registerAfterCommitDelete(currentKey, uploadedKey); |
| 91 | + } |
| 92 | + // 기존 이미지 유지 (nextKey = currentKey) |
| 93 | + guardian.updateGuardianInfo(request.getName(), request.getPhoneNumber(), nextKey); |
| 94 | + Guardian updated = guardianRepository.save(guardian); |
79 | 95 | return GuardianResponse.from(updated, s3Service); |
80 | 96 | } |
81 | 97 |
|
| 98 | + // 트랜잭션 커밋 후 기존 키 삭제, 롤백 시 새로 업로드한 키 삭제 |
| 99 | + private void registerAfterCommitDelete(String oldKey, String uploadedKey) { |
| 100 | + org.springframework.transaction.support.TransactionSynchronizationManager |
| 101 | + .registerSynchronization(new org.springframework.transaction.support.TransactionSynchronization() { |
| 102 | + @Override public void afterCommit() { |
| 103 | + if (oldKey != null && !oldKey.equals(uploadedKey)) { |
| 104 | + s3Service.delete(oldKey); |
| 105 | + } |
| 106 | + } |
| 107 | + @Override public void afterCompletion(int status) { |
| 108 | + if (status == STATUS_ROLLED_BACK && uploadedKey != null) { |
| 109 | + s3Service.delete(uploadedKey); |
| 110 | + } |
| 111 | + } |
| 112 | + }); |
| 113 | + } |
| 114 | + |
82 | 115 | @Transactional |
83 | 116 | public GuardianResponse updatePrimary(User user, Long guardianId, UpdateGuardianPrimaryRequest request) { |
84 | 117 | Guardian guardian = guardianRepository.findByIdAndUser(guardianId, user) |
|
0 commit comments