Skip to content

[Feat]#111 커뮤니티 댓글 isMine 응답 및 게시글 수정 API 추가 - #112

Merged
Lee-Jungwoo merged 1 commit into
developfrom
feat/#111-community-api
Aug 4, 2026
Merged

[Feat]#111 커뮤니티 댓글 isMine 응답 및 게시글 수정 API 추가#112
Lee-Jungwoo merged 1 commit into
developfrom
feat/#111-community-api

Conversation

@Lee-Jungwoo

@Lee-Jungwoo Lee-Jungwoo commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
  • 댓글 목록 조회 응답에 isMine 추가 (GET /api/community/{communityId}/comments)
  • 게시글 수정 API 추가 (POST /api/community/{communityId}, multipart)
  • deleteImageIds 로 기존 이미지 부분 삭제, images 로 새 이미지 추가
  • PUT/PATCH 대신 POST 사용
  • 첨부 이미지만 바뀐 경우에도 updatedAt 갱신
  • 상세 조회 응답에 images(imageId + imageUrl) 추가, 기존 imageUrls 는 유지

#️⃣연관된 이슈

#111

📝작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요.(이미지 첨부 가능)

스크린샷 (선택)

💬리뷰 요구사항(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요.

PR 전 필수 체크리스트

  • 관련 이슈를 연결했습니다.
  • 로컬에서 정상 동작을 확인했습니다.
  • 필요한 테스트를 수행했습니다.
  • Swagger/API 명세를 업데이트했습니다.
  • 불필요한 로그 또는 주석을 제거했습니다.

테스트 결과

  • 단위 테스트
  • 통합 테스트
  • Swagger 테스트
  • Postman 테스트
  • 직접 실행 확인

Summary by CodeRabbit

  • 새 기능

    • 커뮤니티 게시글 수정 기능을 추가했습니다.
    • 게시글 수정 시 이미지 삭제 및 새 이미지 추가를 지원합니다.
    • 게시글 이미지 응답에 이미지 ID와 URL을 함께 제공합니다.
    • 댓글 목록에 본인 댓글 여부가 표시됩니다.
  • 개선 사항

    • 게시글 상세 정보에서 기존 이미지 URL과 이미지 정보를 함께 확인할 수 있습니다.
    • 존재하지 않는 게시글 이미지에 대한 오류 안내를 추가했습니다.

- 댓글 목록 조회 응답에 isMine 추가 (GET /api/community/{communityId}/comments)
- 게시글 수정 API 추가 (POST /api/community/{communityId}, multipart)
  - deleteImageIds 로 기존 이미지 부분 삭제, images 로 새 이미지 추가
  - 톰캣이 multipart 본문을 POST 에서만 파싱해 PUT/PATCH 대신 POST 사용
  - 첨부 이미지만 바뀐 경우에도 updatedAt 갱신
- 상세 조회 응답에 images(imageId + imageUrl) 추가, 기존 imageUrls 는 유지

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Lee-Jungwoo Lee-Jungwoo self-assigned this Aug 4, 2026
Copilot AI lite review requested due to automatic review settings August 4, 2026 06:50
@Lee-Jungwoo Lee-Jungwoo added the ✨ feat 새로운 기능 구현 label Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

커뮤니티 게시글 수정 API가 추가되었습니다. 기존 이미지 삭제와 새 이미지 추가를 지원합니다. 상세 이미지 응답에 이미지 ID가 포함됩니다. 댓글 응답에는 isMine이 추가됩니다.

Changes

커뮤니티 게시글 수정 기능

Layer / File(s) Summary
수정 요청·응답 계약
src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java, src/main/java/com/redo/domain/community/dto/res/CommunityImageResponseDTO.java, src/main/java/com/redo/domain/community/dto/res/CommunityUpdateResponseDTO.java, src/main/java/com/redo/domain/community/dto/res/CommunityDetailResponseDTO.java, src/main/java/com/redo/domain/community/exception/code/*
수정 요청은 카테고리, 제목, 본문, 삭제 이미지 ID, 새 이미지 파일을 받습니다. 수정 및 상세 응답은 이미지 ID와 URL을 제공합니다. 수정 성공 및 이미지 미존재 코드가 추가되었습니다.
수정 API 및 응답 변환
src/main/java/com/redo/domain/community/controller/CommunityController.java, src/main/java/com/redo/domain/community/converter/CommunityConverter.java, src/main/java/com/redo/domain/community/dto/res/CommunityCommentResponseDTO.java
멀티파트 POST /{communityId} 수정 API가 서비스와 연결되었습니다. 상세·수정 응답의 이미지 변환이 변경되었습니다. 댓글 응답은 인증 사용자 기준의 isMine을 포함합니다.
게시글 수정 및 이미지 처리
src/main/java/com/redo/domain/community/service/CommunityService.java, src/main/java/com/redo/domain/community/entity/Community.java
서비스가 작성자 권한을 확인하고 게시글과 이미지를 수정합니다. 삭제 대상 이미지를 검증하고 DB에서 삭제한 뒤 S3 객체를 정리합니다. 새 이미지는 기존 순서 다음에 저장합니다. 이미지 변경 시 수정 시각을 갱신합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

  • REDO-Team/Back#34Community 엔티티와 커뮤니티 이미지 모델을 확장합니다.
  • REDO-Team/Back#62 — 동일한 커뮤니티 컨트롤러, 서비스, 변환기 및 DTO 흐름을 확장합니다.
  • REDO-Team/Back#109 — 댓글 응답의 작성자 메타데이터 변경과 연결됩니다.

Suggested reviewers: copilot

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CommunityController
  participant CommunityService
  participant Database
  participant S3
  Client->>CommunityController: 멀티파트 게시글 수정 요청
  CommunityController->>CommunityService: updateCommunityPost(userId, communityId, request)
  CommunityService->>Database: 게시글 및 이미지 수정
  CommunityService->>S3: 삭제 이미지 객체 정리
  CommunityService->>CommunityController: CommunityUpdateResponseDTO
  CommunityController->>Client: 수정 성공 응답
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 댓글 응답의 isMine 필드 추가와 커뮤니티 게시글 수정 API 구현이라는 주요 변경 사항을 명확하게 요약합니다.
Docstring Coverage ✅ Passed Docstring coverage is 81.48% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

커뮤니티 도메인에서 댓글 목록 조회 응답에 isMine 플래그를 추가하고, 게시글 수정 API(멀티파트 기반) 및 이미지 부분 수정(delete/add) 기능을 도입해 클라이언트가 수정 화면을 구성/갱신할 수 있도록 확장한 PR입니다.

Changes:

  • 댓글 목록 조회 응답에 isMine 추가 및 컨트롤러/서비스 시그니처 확장
  • 커뮤니티 게시글 수정 API 추가 + 수정 응답 DTO 신설
  • 상세 조회 응답에 images(imageId + imageUrl) 추가(기존 imageUrls 유지) 및 이미지 편집 로직 추가

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/main/java/com/redo/domain/community/service/CommunityService.java 댓글 isMine 계산 추가, 게시글 수정 및 이미지 부분 수정 로직 추가, 상세 이미지 응답 구조 변경
src/main/java/com/redo/domain/community/exception/code/CommunitySuccessCode.java 게시글 수정 성공 코드 추가
src/main/java/com/redo/domain/community/exception/code/CommunityErrorCode.java 게시글 이미지 NOT_FOUND 에러 코드 추가
src/main/java/com/redo/domain/community/entity/Community.java 게시글 update/touch 메서드 추가
src/main/java/com/redo/domain/community/dto/res/CommunityUpdateResponseDTO.java 게시글 수정 응답 DTO 추가
src/main/java/com/redo/domain/community/dto/res/CommunityImageResponseDTO.java 이미지 id + presigned url 응답 DTO 추가
src/main/java/com/redo/domain/community/dto/res/CommunityDetailResponseDTO.java 상세 응답에 images 필드 추가(기존 imageUrls 유지)
src/main/java/com/redo/domain/community/dto/res/CommunityCommentResponseDTO.java 댓글 응답에 isMine 추가 및 직렬화 이름 고정
src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java 게시글 수정(삭제 이미지 id + 추가 이미지) 요청 DTO 추가
src/main/java/com/redo/domain/community/converter/CommunityConverter.java 상세/수정/댓글 응답 변환 로직 확장(images/isMine/updateResponse)
src/main/java/com/redo/domain/community/controller/CommunityController.java 게시글 수정 API 추가 및 댓글 목록 조회에 userId 전달

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +344 to +348
List<CommunityImg> currentImages = communityImgRepository.findByCommunityOrderByDisplayOrderAsc(community);

List<String> deletedImageKeys = deleteImages(currentImages, deleteImageIds);
// 남은 이미지와 순서가 겹치지 않도록 기존 display_order 최댓값 다음부터 이어서 저장한다.
List<String> addedImageKeys = saveImages(community, images, nextDisplayOrder(currentImages));
Comment on lines 202 to +206
comment,
getNickname(profile),
getProfileImageUrl(profile),
getCharacterCode(profile)
getCharacterCode(profile),
isMine(userId, comment)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java`:
- Line 13: CommunityUpdateRequestDTO의 title에 `@Size`(max = 100)을 추가하고,
CommunityService의 validatePostRequest()에서 editImages()가 실행되기 전에 동일한 최대 길이 검증을
수행하도록 수정하십시오. Community.title의 100자 제한과 일치시키고, 초과 요청은 S3 작업이나 영속화 전에 거부되도록 기존 검증
흐름을 유지하십시오.

In `@src/main/java/com/redo/domain/community/service/CommunityService.java`:
- Around line 346-356: Separate upload-failure cleanup from transaction rollback
in the image update flow around saveImages and S3Service.uploadAll. Ensure
rollbackUploadedObjects failures do not propagate or interfere with database
restoration; instead, reliably record failed object keys for retry or persist
them for asynchronous cleanup, while preserving the existing post-commit
deletion behavior.
- Around line 162-175: Apply concurrency control to updateCommunityPost and the
Community retrieval path so simultaneous edits cannot calculate duplicate image
displayOrder values from the same state. Add optimistic versioning with a
conflict response, or use a pessimistic write lock for this update flow; ensure
the selected mechanism covers editImages and maps conflicts to the established
error handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 13d55ae3-1dcc-48af-96a3-9e590281965a

📥 Commits

Reviewing files that changed from the base of the PR and between ded28bb and 5520bcc.

📒 Files selected for processing (11)
  • src/main/java/com/redo/domain/community/controller/CommunityController.java
  • src/main/java/com/redo/domain/community/converter/CommunityConverter.java
  • src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java
  • src/main/java/com/redo/domain/community/dto/res/CommunityCommentResponseDTO.java
  • src/main/java/com/redo/domain/community/dto/res/CommunityDetailResponseDTO.java
  • src/main/java/com/redo/domain/community/dto/res/CommunityImageResponseDTO.java
  • src/main/java/com/redo/domain/community/dto/res/CommunityUpdateResponseDTO.java
  • src/main/java/com/redo/domain/community/entity/Community.java
  • src/main/java/com/redo/domain/community/exception/code/CommunityErrorCode.java
  • src/main/java/com/redo/domain/community/exception/code/CommunitySuccessCode.java
  • src/main/java/com/redo/domain/community/service/CommunityService.java

// (둘 다 보내지 않으면 기존 이미지는 그대로 유지된다.)
public record CommunityUpdateRequestDTO(
@NotNull Integer category,
@NotBlank String title,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate relevant files"
fd -a 'CommunityUpdateRequestDTO.java|Community.java|CommunityService.java' src/main/java || true

echo
echo "Files with validation annotations around community DTOs"
rg -n "class CommunityUpdateRequest|record CommunityUpdateRequest|`@NotBlank`|`@Size`|CommunityUpdateRequestDTO" src/main/java || true

echo
echo "CommunityUpdateRequestDTO.java"
cat -n src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java

echo
echo "Community.java relevant fields"
sed -n '1,90p' src/main/java/com/redo/domain/community/entity/Community.java | cat -n

echo
echo "CommunityService.java relevant update/image lines"
sed -n '260,350p' src/main/java/com/redo/domain/community/service/CommunityService.java | cat -n

echo
echo "CommunityService.java validation methods containing CommunityUpdateRequest"
rg -n "CommunityUpdateRequest|`@NotBlank`|`@Size`|editImages|updateCommunity|save|saveAndFlush|validation" src/main/java/com/redo/domain/community/service src/main/java/com/redo/domain/community -g '*.java' || true

Repository: REDO-Team/Back

Length of output: 19062


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "CommunityService.java updateCommunityPost and validation helper"
sed -n '70,190p' src/main/java/com/redo/domain/community/service/CommunityService.java | cat -n

echo
echo "CommunityService.java editImages and deleteImages"
sed -n '334,390p' src/main/java/com/redo/domain/community/service/CommunityService.java | cat -n

echo
echo "CommunityController.java updateCommunityPost annotations"
sed -n '95,120p' src/main/java/com/redo/domain/community/controller/CommunityController.java | cat -n

echo
echo "CommunityException and CODE definitions related to title/content"
rg -n "TITLE_REQUIRED|CONTENT_REQUIRED|COMMUNITY_NOT_FOUND|GeneralExceptionAdvice|ErrorCode|`@RestControllerAdvice`|ExceptionHandler" src/main/java -g '*.java' || true

Repository: REDO-Team/Back

Length of output: 50370


수정 API에서 title 길이를 영속화 전에 제한하십시오.

Community.titlelength = 100으로 제한되지만, CommunityUpdateRequestDTO.title은 공백만 검증합니다. 101자 제목 요청은 editImages()의 S3 업로드/삭제 작업 이후 flush에서 실패할 수 있습니다. DTO에 @Size(max = 100)을 적용하고, editImages()CommunityService.validatePostRequest()에도 같은 길이 검증을 추가하십시오.

수정 예시
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;

-        `@NotBlank` String title,
+        `@NotBlank` `@Size`(max = 100) String title,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/redo/domain/community/dto/req/CommunityUpdateRequestDTO.java`
at line 13, CommunityUpdateRequestDTO의 title에 `@Size`(max = 100)을 추가하고,
CommunityService의 validatePostRequest()에서 editImages()가 실행되기 전에 동일한 최대 길이 검증을
수행하도록 수정하십시오. Community.title의 100자 제한과 일치시키고, 초과 요청은 S3 작업이나 영속화 전에 거부되도록 기존 검증
흐름을 유지하십시오.

Comment on lines +162 to +175
Community community = getActiveCommunity(communityId);
if (!community.getUser().getId().equals(userId)) {
throw new CommunityException(CommunityErrorCode.NOT_POST_OWNER);
}

community.update(toCategory(request.category()), request.title(), request.content());

// 제목/본문 변경 없이 첨부 이미지만 바뀌면 게시글 컬럼이 그대로라 UPDATE 가 나가지 않으므로 수정 시각을 직접 갱신한다.
if (editImages(community, request.deleteImageIds(), request.images())) {
community.touch();
}

// 응답에 갱신된 updatedAt(@PreUpdate 로 채워진다)을 담기 위해 변경 내용을 먼저 반영한다.
communityRepository.flush();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 빌드나 테스트를 실행하지 않고 잠금 구성을 확인한다.
ast-grep outline src/main/java/com/redo/domain/community/entity/Community.java --items all
rg -n -C 4 '`@Version`|`@Lock`|LockModeType|PESSIMISTIC|OPTIMISTIC|findByIdAndDeletedAtIsNull' \
  src/main/java/com/redo/domain/community/entity/Community.java \
  src/main/java/com/redo/domain/community/repository/CommunityRepository.java

Repository: REDO-Team/Back

Length of output: 2140


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant Community methods =="
sed -n '1,120p' src/main/java/com/redo/domain/community/entity/Community.java
sed -n '130,210p' src/main/java/com/redo/domain/community/entity/Community.java
sed -n '320,410p' src/main/java/com/redo/domain/community/service/CommunityService.java

echo "== repository methods =="
sed -n '1,80p' src/main/java/com/redo/domain/community/repository/CommunityRepository.java

echo "== transaction annotations for update methods =="
rg -n -C 4 '`@Transactional`|editImages|findByIdAndDeletedAtIsNull\(' \
  src/main/java/com/redo/domain/community/service/CommunityService.java \
  src/main/java/com/redo/domain/community/repository/CommunityRepository.java

Repository: REDO-Team/Back

Length of output: 23129


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== getActiveCommunity declarations/usages =="
rg -n -C 3 'getActiveCommunity\(Long communityId\)|getActiveCommunity\(' src/main/java/com/redo/domain/community/service/CommunityService.java

echo "== CommunityImg entity/repository relevant lock/version annotations =="
rg -n -C 3 '`@Entity`|`@Id`|`@Version`|`@Lock`|LockModeType|PESSIMISTIC|OPTIMISTIC|findByCommunityOrderByDisplayOrderAsc|deleteAll' \
  src/main/java/com/redo/domain/community/entity src/main/java/com/redo/domain/community/repository

Repository: REDO-Team/Back

Length of output: 8131


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
paths = [
    Path("src/main/java/com/redo/domain/community/entity/Community.java"),
    Path("src/main/java/com/redo/domain/community/repository/CommunityRepository.java"),
    Path("src/main/java/com/redo/domain/community/service/CommunityService.java"),
    Path("src/main/java/com/redo/domain/community/repository/CommunityImgRepository.java"),
    Path("src/main/java/com/redo/domain/community/entity/CommunityImg.java"),
]
terms = ["`@Version`", "`@Lock`", "LockModeType", "PESSIMISTIC", "OPTIMISTIC", "`@Entity`", "`@Id`", "findByCommunityOrderByDisplayOrderAsc", "deleteAll"]
for path in paths:
    print(f"\n== {path} ==")
    text = path.read_text()
    relevant = any(term in text for term in terms)
    print(f"contains lock/version/entity-query terms: {relevant}")
    if relevant:
        for lineno, line in enumerate(text.splitlines(), 1):
            if any(term in line for term in terms):
                print(f"{lineno}: {line}")
PY

Repository: REDO-Team/Back

Length of output: 1244


동시 수정의 충돌 제어를 적용하십시오.

Community는 낙관적 버전을 두고 있지 않고, findByIdAndDeletedAtIsNull도 잠금을 하지 않습니다. 이 때 updateCommunityPost가 실행되면 같은 게시글의 두 요청이 같은 상태를 읽을 수 있고, editImages()는 같은 이미지 목록에서 nextDisplayOrder를 계산해 새 이미지에 중복된 displayOrder를 지정할 수 있습니다. 수정 대상에 낙관적 잠금과 충돌 응답, 또는 이 경로의 비관적 쓰기 잠금을 적용하십시오.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/redo/domain/community/service/CommunityService.java` around
lines 162 - 175, Apply concurrency control to updateCommunityPost and the
Community retrieval path so simultaneous edits cannot calculate duplicate image
displayOrder values from the same state. Add optimistic versioning with a
conflict response, or use a pessimistic write lock for this update flow; ensure
the selected mechanism covers editImages and maps conflicts to the established
error handling.

Source: Coding guidelines

Comment on lines +346 to +356
List<String> deletedImageKeys = deleteImages(currentImages, deleteImageIds);
// 남은 이미지와 순서가 겹치지 않도록 기존 display_order 최댓값 다음부터 이어서 저장한다.
List<String> addedImageKeys = saveImages(community, images, nextDisplayOrder(currentImages));

// S3 객체 정리는 DB 반영 이후에 수행하고, 실패하더라도 수정 자체는 성공으로 처리한다(고아 객체는 로그로 남긴다).
try {
s3Service.deleteAll(deletedImageKeys);
} catch (S3Exception exception) {
log.error("Failed to delete removed community images from S3. communityId={}, keys={}",
community.getId(), deletedImageKeys, exception);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
fd -a 'CommunityService\.java|S3Service\.java' . | sed 's#^\./##'

echo
echo "CommunityService outline:"
FILE=$(fd 'CommunityService\.java' . | head -n1)
if [ -n "${FILE:-}" ]; then
  wc -l "$FILE"
  ast-grep outline "$FILE" || true
  echo
  echo "Relevant CommunityService sections:"
  sed -n '300,410p' "$FILE" | cat -n -v
fi

echo
echo "S3Service outline:"
S3FILE=$(fd 'S3Service\.java' . | head -n1)
if [ -n "${S3FILE:-}" ]; then
  wc -l "$S3FILE"
  ast-grep outline "$S3FILE" || true
  echo
  echo "Relevant S3Service sections:"
  sed -n '1,170p' "$S3FILE" | cat -n -v
fi

echo
echo "Search transactional and publish after commit patterns:"
rg -n '`@Transactional`|AfterCommit|TransactionSynchronization|TransactionSynchronizationManager|AfterTransaction|PostTransaction|commit|deleteAll|saveImages|editImages|flush' src/main/java || true

Repository: REDO-Team/Back

Length of output: 26424


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "CommunityService transactional and update sections:"
FILE=$(fd 'CommunityService\.java' . | head -n1)
sed -n '130,285p' "$FILE" | cat -n -v

echo
echo "S3Service remaining rollback section:"
S3FILE=$(fd 'S3Service\.java' . | head -n1)
sed -n '180,240p' "$S3FILE" | cat -n -v

echo
echo "Search for after-commit/transaction-synchronization implementation:"
rg -n 'TransactionSynchronization|AfterCommit|afterCommit|commitFailed|prepareCommit|TransactionSynchronizationRegistry|ApplicationEventPublisher|`@TransactionalEventListener`|EventPublisher|TransactionStatus|afterRollback' src/main/java || true

Repository: REDO-Team/Back

Length of output: 13098


업로드 실패 처리를 롤백 전 고아 객체 제거와 분리하십시오.

S3Service.uploadAll()rollbackUploadedObjects()가 삭제 실패를 로그만 남긴 뒤 throw하므로, 업로드 중 실패하면 임시 S3 객체가 삭제되지 않고 보존될 수 있습니다. 트랜잭션 롤백 시 S3 실패가 DB 복원을 방해하지 않도록 별도 보상/정리 경로로 분리하고, 실패한 키의 재시도 또는 영속화된 후처리 기록을 저장하십시오.

🧰 Tools
🪛 PMD (7.26.0)

[Low] 354-355: InvalidLogMessageFormat (Error Prone): Too many arguments, expected 2 arguments but found 3

(InvalidLogMessageFormat (Error Prone))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/redo/domain/community/service/CommunityService.java` around
lines 346 - 356, Separate upload-failure cleanup from transaction rollback in
the image update flow around saveImages and S3Service.uploadAll. Ensure
rollbackUploadedObjects failures do not propagate or interfere with database
restoration; instead, reliably record failed object keys for retry or persist
them for asynchronous cleanup, while preserving the existing post-commit
deletion behavior.

Source: Coding guidelines

@Lee-Jungwoo
Lee-Jungwoo merged commit 66eeb2d into develop Aug 4, 2026
2 checks passed
@woo6629058
woo6629058 deleted the feat/#111-community-api branch August 17, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 새로운 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants