Skip to content

Conversation

@kon28289
Copy link
Contributor

@kon28289 kon28289 commented Sep 17, 2025

What is this PR?🔍

  • 이미지 업로드 시 일관성 유지를 위해 이미지 롤백 메서드를 추가합니다.

Changes💻

  • 컨트롤러에서 ImageServiceuploadImage 호출 시 기존에는 MultipartFile로 받은 이미지를 uploadImage의 인자로 넘겨주었지만, 현재는 MultipartFile 타입의 배열을 생성하고, 이 배열을 uploadImage의 인자로 넘겨줍니다.
  • 위와 같이 변경함으로써 여러 장의 이미지를 업로드 시, uploadImage 내에서 cloudinary에 저장한 이미지의 publicId를 저장하고 업로드 실패 시 rollbackImage를 호출하여 이미 업로드된 이미지를 cloudinary에서 삭제합니다.
  • rollbackImage가 실행되고 이미지 삭제 실패가 발생하더라도 최대한 많은 이미지를 삭제하도록 try catch를 이중으로 사용했습니다.

ScreenShot📷

Summary by CodeRabbit

  • New Features

    • 제품 이미지 다중 업로드를 정식 지원하여 여러 이미지를 한 번에 업로드하고 일괄 결과를 받을 수 있습니다.
  • Bug Fixes

    • 프로필·채팅·리뷰의 단일 이미지 업로드 동작을 유지하면서 응답 일관성을 개선했습니다.
    • 업로드 중 오류 발생 시 이미 업로드된 이미지를 자동으로 되돌려 불완전한 상태를 방지합니다.
    • 허용 파일 형식 및 최대 파일 크기(5MB) 검사 추가로 잘못된 파일에 대해 명확한 오류를 제공합니다.

@kon28289 kon28289 self-assigned this Sep 17, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 17, 2025

Walkthrough

이미지 업로드가 단일 파일 처리에서 다중 파일(batch) 처리로 전환되었습니다. 컨트롤러는 단일 엔드포인트에서도 파일을 1요소 배열로 감싸 서비스에 위임하고, 서비스는 배열을 순회해 업로드 결과 리스트를 반환하며 오류 시 업로드된 항목을 롤백합니다.

Changes

Cohort / File(s) Summary
Controller: 단일 호출을 배열 호출로 변경
src/main/java/com/uhdyl/backend/image/controller/ImageController.java
기존 단일 MultipartFile 처리 지점에서 요청 파일을 1요소 MultipartFile[]로 감싸 imageService.uploadImage(...).get(0) 호출. 제품 업로드는 List<MultipartFile>MultipartFile[] 변환 후 서비스 호출하고 반환된 리스트를 그대로 응답.
Service: 배치 업로드, 유효성 검사, 롤백 도입
src/main/java/com/uhdyl/backend/image/service/ImageService.java
시그니처 변경: uploadImage(MultipartFile[] images, String folderPath)List<ImageSavedSuccessResponse> 반환. 각 이미지에 대해 null/empty, 크기(>5MB), 컨텐트타입(허용된 이미지 타입) 검증, Cloudinary 업로드, public_id 축적. 예외 발생 시 rollbackImage(List<String>) 호출로 업로드된 항목 삭제. @Slf4j 로깅 추가.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Controller as ImageController
  participant Service as ImageService
  participant CDN as Cloudinary

  Client->>Controller: 업로드 요청 (단일/다중)
  Controller->>Service: uploadImage(MultipartFile[])
  rect rgba(230,245,255,0.6)
    loop 각 이미지
      Service->>Service: 유효성 검사(null/empty/size/type)
      Service->>CDN: 업로드(folder, public_id)
      CDN-->>Service: 업로드 결과(secure_url, public_id)
      Service->>Service: 응답 리스트에 추가 및 public_id 저장
    end
  end
  alt 성공
    Service-->>Controller: List<ImageSavedSuccessResponse>
    note over Controller: 단일 엔드포인트는 .get(0)으로 첫 요소 반환
    Controller-->>Client: 성공 응답
  else 예외 발생
    Service->>Service: rollbackImage(publicIds)
    Service-->>Controller: 예외 전파
    Controller-->>Client: 오류 응답
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

새벽 들판에 파일들 폴짝폴짝, 🥕
한 움큼 묶어 보낸 나의 배치 업로드,
혹시 헛발질하면 다시 끌어안아 롤백,
컨트롤러는 한 알만 건네고, 서비스는 모두 지켜,
클라우드 둥지에 안전히 눕혔네.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 'refactor: 이미지 롤백 메서드 추가'는 변경의 핵심인 이미지 롤백 메서드 추가를 명확히 요약하고 있으며 불필요한 잡음 없이 간결하게 목적을 전달합니다. 업로드 흐름 리팩터링(배치 업로드 지원 및 롤백 도입)을 대표하는 적절한 제목으로 판단합니다.
Description Check ✅ Passed PR 설명은 레포지토리 템플릿의 섹션(What is this PR?, Changes, ScreenShot)을 따르고 있으며 컨트롤러의 MultipartFile 배열 전환, uploadImage에서의 publicId 축적 및 실패 시 rollback 호출 등 핵심 변경사항을 명확히 기술하고 있습니다. 스크린샷 항목은 비어 있으나 필수 정보는 대체로 충족되어 있어 설명 체크는 통과로 판단합니다.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/image

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
src/main/java/com/uhdyl/backend/image/controller/ImageController.java (1)

67-68: 더 간결한 배열 변환을 사용하세요.

List<MultipartFile>을 배열로 변환하는 더 간결한 방법이 있습니다.

다음과 같이 수정하세요:

-    MultipartFile[] imageArray = new MultipartFile[images.size()];
-    images.toArray(imageArray);
+    MultipartFile[] imageArray = images.toArray(new MultipartFile[0]);
src/main/java/com/uhdyl/backend/image/service/ImageService.java (4)

168-181: 외부 try-catch 블록이 불필요합니다.

내부 try-catch 블록이 이미 모든 예외를 처리하고 있으므로 외부 try-catch 블록은 실제로 동작하지 않습니다.

다음과 같이 수정하세요:

 public void rollbackImage(List<String> publicIds){
-    try{
-        for (String publicId : publicIds) {
-            try {
-                cloudinary.uploader().destroy(publicId, ObjectUtils.emptyMap());
-            } catch (IOException e) {
-                log.warn("이미지 롤백에 실패했습니다. publicId : {}", publicId);
-            }
+    for (String publicId : publicIds) {
+        try {
+            cloudinary.uploader().destroy(publicId, ObjectUtils.emptyMap());
+        } catch (IOException e) {
+            log.warn("이미지 롤백에 실패했습니다. publicId : {}", publicId);
         }
     }
-    catch (Exception e){
-        log.warn("이미지 롤백이 일부 실패했습니다.");
-    }
 }

45-84: 트랜잭션 관리가 필요합니다.

이미지 업로드는 외부 시스템(Cloudinary)과 상호작용하지만 트랜잭션 어노테이션이 없습니다. 데이터베이스 작업이 포함될 경우를 대비해 명시적으로 트랜잭션을 관리하는 것이 좋습니다.

다음과 같이 수정하세요:

+@Transactional
 public List<ImageSavedSuccessResponse> uploadImage(MultipartFile[] images, String folderPath){

174-174: 로그 레벨과 메시지를 개선하세요.

롤백 실패는 데이터 일관성에 영향을 줄 수 있으므로 ERROR 레벨이 더 적절하며, 예외 정보도 로그에 포함해야 합니다.

다음과 같이 수정하세요:

-    log.warn("이미지 롤백에 실패했습니다. publicId : {}", publicId);
+    log.error("이미지 롤백에 실패했습니다. publicId : {}", publicId, e);

51-73: 병렬 처리로 성능을 개선할 수 있습니다.

여러 이미지를 순차적으로 업로드하면 시간이 오래 걸릴 수 있습니다. CompletableFuture를 사용한 병렬 처리를 고려해보세요.

대량의 이미지 업로드가 예상된다면, 다음과 같은 병렬 처리 구현을 고려하세요:

  • CompletableFuture를 사용한 비동기 업로드
  • 업로드 제한 시간(timeout) 설정
  • 진행 상황 추적을 위한 이벤트 발행
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bec3488 and 3d471e5.

📒 Files selected for processing (2)
  • src/main/java/com/uhdyl/backend/image/controller/ImageController.java (4 hunks)
  • src/main/java/com/uhdyl/backend/image/service/ImageService.java (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (1)

148-152: PRODUCT_IMAGE 권한 검증 누락 — userId 기반 검증으로 통일 필요

ImageService의 PRODUCT_IMAGE 분기에서 imageRepository.findByImageUrl(imageUrl)로 사용자 검증이 빠져 있습니다. 레포지토리에는 이미 사용자 기반 검증 메서드 existsByUserIdAndPublicId(Long, String)가 정의·구현되어 있으므로(src/main/java/com/uhdyl/backend/image/repository/CustomImageRepository.java, src/main/java/com/uhdyl/backend/image/repository/CustomImageRepositoryImpl.java) 해당 분기에서 imageRepository.existsByUserIdAndPublicId(userId, publicId)로 권한을 확인한 뒤 publicId를 반환하거나, 대안으로 ImageRepository에 findByUser_IdAndImageUrl(Long, String) 메서드를 추가해 검증을 일관화하세요. 문제 위치: src/main/java/com/uhdyl/backend/image/service/ImageService.java (PRODUCT_IMAGE 분기).

♻️ Duplicate comments (1)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (1)

68-73: 이전 NPE 지적 건(secure_url/public_id null) 선조치 확인

null 체크가 선행되도록 수정되어 NPE 위험이 해소되었습니다. 좋습니다.

🧹 Nitpick comments (5)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (5)

45-49: 배열 null/빈값 및 folderPath 선검증 추가 권고

images가 null/빈 배열이면 for-each에서 NPE가 나고, folderPath가 null/blank면 Map.of에서 NPE가 납니다. 업로드 시작 전에 빠르게 검증해 실패 원인을 명확히 해주세요.

적용 예시:

-        try {
-            for (MultipartFile image : images) {
+        try {
+            if (images == null || images.length == 0)
+                throw new BusinessException(ExceptionType.INVALID_IMAGE_FILE);
+            if (folderPath == null || folderPath.isBlank()) {
+                log.warn("folderPath가 비어있습니다.");
+                throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
+            }
+            for (MultipartFile image : images) {

59-66: Cloudinary 응답 Map 제네릭 명시 및 중복 접근 제거

로컬 변수로 꺼내어 null 체크와 사용을 일관화하면 가독성과 타입 안정성이 개선됩니다.

적용 예시:

-                Map<?, ?> result = cloudinary.uploader().upload(
+                Map<String, Object> result = cloudinary.uploader().upload(
                         image.getBytes(),
                         Map.of(
                                 "folder", folderPath,
                                 "public_id", UUID.randomUUID().toString()
                         )
                 );
 
-                if (result.get("secure_url") == null || result.get("public_id") == null)
+                String secureUrl = (String) result.get("secure_url");
+                String publicId  = (String) result.get("public_id");
+                if (secureUrl == null || publicId == null)
                     throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
 
-                uploadedImagesPublicId.add(result.get("public_id").toString());
-                responses.add(ImageSavedSuccessResponse.to(result.get("secure_url").toString(), result.get("public_id").toString()));
+                uploadedImagesPublicId.add(publicId);
+                responses.add(ImageSavedSuccessResponse.to(secureUrl, publicId));

Also applies to: 68-73


62-63: folderPath 입력 위생 처리 권고

임의 입력이 그대로 Cloudinary 폴더에 반영되므로, .. 등 비정상 경로/문자 차단을 권장합니다(허용 문자 정규식).

적용 스니펫(검증 위치는 선검증 구간):

// 예: 영문/숫자/슬래시/언더스코어/하이픈만 허용
if (!folderPath.matches("^[A-Za-z0-9/_-]+$")) {
    log.warn("허용되지 않은 folderPath: {}", folderPath);
    throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
}

76-83: 예외 로깅 보강: 원인 파악 위해 스택트레이스 기록

롤백만 하고 예외 원인이 로그에 남지 않습니다. 운영 문제 분석을 위해 로깅을 추가하세요.

적용 예시:

         catch (BusinessException e) {
             rollbackImage(uploadedImagesPublicId);
-            throw e;
+            log.warn("이미지 업로드 중 비즈니스 예외 발생, 롤백 수행: {}", e.getMessage(), e);
+            throw e;
         }
         catch (Exception e) {
             rollbackImage(uploadedImagesPublicId);
-            throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
+            log.error("이미지 업로드 실패. 롤백 수행.", e);
+            throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
         }

169-182: 롤백 로깅에 예외 객체 포함

현재는 publicId만 남겨 원인 추적이 어렵습니다. 예외 객체를 함께 로그로 남겨주세요.

적용 예시:

-                } catch (IOException e) {
-                    log.warn("이미지 롤백에 실패했습니다. publicId : {}", publicId);
+                } catch (IOException e) {
+                    log.warn("이미지 롤백에 실패했습니다. publicId: {}", publicId, e);
                 }
             }
-        }
-        catch (Exception e){
-            log.warn("이미지 롤백이 일부 실패했습니다.");
+        } catch (Exception e){
+            log.warn("이미지 롤백이 일부 실패했습니다.", e);
         }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d471e5 and d0fc043.

📒 Files selected for processing (1)
  • src/main/java/com/uhdyl/backend/image/service/ImageService.java (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T04:12:43.638Z
Learnt from: kon28289
PR: UhDyL/UhDyL-Backend#43
File: src/main/java/com/uhdyl/backend/image/repository/ImageRepository.java:12-12
Timestamp: 2025-08-20T04:12:43.638Z
Learning: ImageService의 getPublicId 메서드에서 PRODUCT_IMAGE 케이스는 findByImageUrl만 사용하여 권한 검증이 누락되어 있지만, CHAT_IMAGE와 REVIEW_IMAGE는 findByUser_IdAndImageUrl을 사용하여 올바르게 권한 검증을 수행하고 있음. 일관성과 보안을 위해 모든 이미지 타입에서 사용자 ID 기반 검증이 필요함.

Applied to files:

  • src/main/java/com/uhdyl/backend/image/service/ImageService.java
🔇 Additional comments (1)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (1)

45-45: 컨트롤러 호출부 및 빈 리스트 안전성 확인 필요

  • uploadImage 시그니처는 MultipartFile[]로 변경되어 호출부들이 업데이트된 것이 확인됨 (확인된 호출: src/main/java/com/uhdyl/backend/image/controller/ImageController.java — profile:40, chat:55, product:69, review:81).
  • profile/chat/review 엔드포인트에서 imageService.uploadImage(...).get(0) 사용 확인. uploadImage가 빈 리스트를 반환할 경우 IndexOutOfBoundsException 가능성 있음 — 서비스가 최소 1개 반환을 보장하거나 호출부에서 리스트 비어있음 검사 추가.
    public List<ImageSavedSuccessResponse> uploadImage(MultipartFile[] images, String folderPath){

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (1)

152-156: PRODUCT_IMAGE 권한 검증 누락 — 사용자 ID 기반 검증 필요

이전 리뷰에서도 동일 지적이 있었습니다. imageUrl만으로 조회하면 타 사용자의 이미지에 접근/조회가 가능합니다. 사용자 ID를 포함한 조회로 교체하세요.

아래처럼 수정 권장(레포지토리 메서드 존재 시):

-                Image image = imageRepository.findByImageUrl(imageUrl)
-                        .orElseThrow(() -> new BusinessException(ExceptionType.IMAGE_ACCESS_DENIED));
+                Image image = imageRepository.findByUserIdAndImageUrl(userId, imageUrl)
+                        .orElseThrow(() -> new BusinessException(ExceptionType.IMAGE_ACCESS_DENIED));
                 return ImagePublicIdResponse.to(image.getPublicId());

레포지토리에 메서드가 없다면 추가가 필요합니다.

🧹 Nitpick comments (8)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (8)

42-44: MIME 허용 리스트 도입 👍 + 업로드 최대 크기 상수화 권장

하드코딩된 바이트 수를 상수로 추출해 재사용성을 높이세요.

아래처럼 상수를 선언하고 사용해 주세요:

 private static final Set<String> ALLOWED_CONTENT_TYPES =
         Set.of("image/jpeg", "image/png", "image/webp", "image/gif");
+
+private static final long MAX_IMAGE_BYTES = 5L * 1024 * 1024;

45-55: 배열 null/빈 배열 및 폴더 경로 검증 추가 필요

images가 null/빈 배열이면 현재 for-each에서 NPE/무효 동작 위험. folderPath도 null/빈 문자열 방지하세요.

아래처럼 초기에 방어 코드를 추가하세요:

 public List<ImageSavedSuccessResponse> uploadImage(MultipartFile[] images, String folderPath){
 
     List<String> uploadedImagesPublicId = new ArrayList<>();
     List<ImageSavedSuccessResponse> responses = new ArrayList<>();
 
     try {
+        if (images == null || images.length == 0)
+            throw new BusinessException(ExceptionType.INVALID_IMAGE_FILE);
+        if (folderPath == null || folderPath.isBlank())
+            throw new BusinessException(ExceptionType.INVALID_IMAGE_FILE);
         for (MultipartFile image : images) {
 
             if (image == null || image.isEmpty())
                 throw new BusinessException(ExceptionType.INVALID_IMAGE_FILE);

56-57: 하드코딩된 크기 비교를 상수로 교체

위에서 제안한 MAX_IMAGE_BYTES 사용으로 가독성/일관성 개선.

-                if (image.getSize() > 1024 * 1024 * 5)
+                if (image.getSize() > MAX_IMAGE_BYTES)
                     throw new BusinessException(ExceptionType.IMAGE_SIZE_EXCEEDED);

59-62: 콘텐츠 타입 검증 OK — 범위 확장은 선택

contains(null)이 false이므로 null도 차단됨. 필요 시 image/jpg, image/heic 등 지원 포맷을 정책에 맞춰 추가 고려.


80-87: 예외 원인 로깅 추가로 트러블슈팅 용이성 향상

롤백만 하고 원인은 로그에 남지 않습니다. 스택트레이스를 로그에 포함하세요.

-        catch (BusinessException e) {
-            rollbackImage(uploadedImagesPublicId);
-            throw e;
-        }
-        catch (Exception e) {
-            rollbackImage(uploadedImagesPublicId);
-            throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
-        }
+        catch (BusinessException e) {
+            log.warn("이미지 업로드 중 비즈니스 예외 발생 — 롤백 수행", e);
+            rollbackImage(uploadedImagesPublicId);
+            throw e;
+        }
+        catch (Exception e) {
+            log.error("이미지 업로드 실패 — 롤백 수행", e);
+            rollbackImage(uploadedImagesPublicId);
+            throw new BusinessException(ExceptionType.IMAGE_UPLOAD_FAILED);
+        }

94-137: 배치 삭제의 원자성 문제 — 일부 실패 시 DB/클라우드 상태 불일치 가능

한 항목에서 예외가 나면 전체 트랜잭션이 롤백되어 이전 DB 삭제도 되돌려지지만, 이미 실행된 Cloudinary 삭제는 복구 불가여서 불일치가 발생할 수 있습니다. 항목별로 독립 처리(예: 항목별 try/catch, 결과 집계 반환), 혹은 비동기 보상(아웃박스/재시도 큐)을 검토하세요.

원한다면 항목별 결과를 반환하는 시그니처/DTO로의 개편안을 제안하겠습니다.


170-171: 도달 불가능한 반환 제거 권장

switch는 모든 enum 케이스를 처리합니다. 마지막 return "이미지가 존재하지 않습니다."는 실행되지 않습니다.

-        return ImagePublicIdResponse.to("이미지가 존재하지 않습니다.");
+        // 모든 케이스 처리됨

173-186: 롤백 보강: 빈 입력 처리, 예외 로그에 원인 포함, CDN 무효화 옵션

안전성과 가시성을 높이세요.

 public void rollbackImage(List<String> publicIds){
-        try{
+        try{
+            if (publicIds == null || publicIds.isEmpty()) return;
             for (String publicId : publicIds) {
                 try {
-                    cloudinary.uploader().destroy(publicId, ObjectUtils.emptyMap());
-                } catch (IOException e) {
-                    log.warn("이미지 롤백에 실패했습니다. publicId : {}", publicId);
+                    cloudinary.uploader().destroy(publicId, Map.of("invalidate", true));
+                } catch (IOException e) {
+                    log.warn("이미지 롤백에 실패했습니다. publicId: {}", publicId, e);
                 }
             }
         }
-        catch (Exception e){
-            log.warn("이미지 롤백이 일부 실패했습니다.");
+        catch (Exception e){
+            log.warn("이미지 롤백이 일부 실패했습니다.", e);
         }
     }

추가로, 대량 삭제가 잦다면 Admin API의 batch 삭제(api().deleteResources) 도입을 검토하세요.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0fc043 and 503de77.

📒 Files selected for processing (1)
  • src/main/java/com/uhdyl/backend/image/service/ImageService.java (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T04:12:43.638Z
Learnt from: kon28289
PR: UhDyL/UhDyL-Backend#43
File: src/main/java/com/uhdyl/backend/image/repository/ImageRepository.java:12-12
Timestamp: 2025-08-20T04:12:43.638Z
Learning: ImageService의 getPublicId 메서드에서 PRODUCT_IMAGE 케이스는 findByImageUrl만 사용하여 권한 검증이 누락되어 있지만, CHAT_IMAGE와 REVIEW_IMAGE는 findByUser_IdAndImageUrl을 사용하여 올바르게 권한 검증을 수행하고 있음. 일관성과 보안을 위해 모든 이미지 타입에서 사용자 ID 기반 검증이 필요함.

Applied to files:

  • src/main/java/com/uhdyl/backend/image/service/ImageService.java
🔇 Additional comments (2)
src/main/java/com/uhdyl/backend/image/service/ImageService.java (2)

21-31: Slf4j 추가 적절

롤백 경고 로그에 활용되고 있어 타당합니다.


45-45: 해결 — 호출부 전수 확인 완료 (문제 없음)

ImageService 시그니처 변경에 대해 컨트롤러/API 호출부가 배열/리스트 변환 및 반환 처리로 모두 일치함을 확인했습니다.

  • src/main/java/com/uhdyl/backend/image/service/ImageService.java:45
  • src/main/java/com/uhdyl/backend/image/controller/ImageController.java:40, 55, 69, 81 (단건 업로드는 배열로 래핑 후 .get(0) 사용)
  • src/main/java/com/uhdyl/backend/image/controller/ImageController.java:64 (uploadProductImage — List 파라미터 → 내부에서 배열로 변환)
  • src/main/java/com/uhdyl/backend/image/api/ImageApi.java:118, 120

@kon28289 kon28289 merged commit d64ffb1 into dev Sep 17, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants