Skip to content

Conversation

@ggok0265
Copy link
Contributor

📝 PR 설명

이번 PR에서 변경된 내용 또는 추가된 기능을 간단히 설명해주세요.

프젝갤 패키지 내에 중복으로 저장되어있던 파일을 삭제했습니다.
프젝갤 내의 프로젝트를 수정하도록 하는 기능을 구현했습니다.
생성과 수정에 필요한 바디가 일치함에 따라 네이밍을 SaveRequestDto로 수정했습니다.

🔍 관련 이슈

기타

리뷰어가 알아야 할 추가 사항을 작성해주세요.

@ggok0265 ggok0265 self-assigned this Nov 19, 2025
@ggok0265 ggok0265 added the ✨ feat Extra attention is needed label Nov 19, 2025
@ggok0265 ggok0265 linked an issue Nov 19, 2025 that may be closed by this pull request
Copy link
Contributor

@kjoon418 kjoon418 left a comment

Choose a reason for hiding this comment

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

코멘트 남겼습니다. 확인 후 답변 달아주세요 😉

@RequiredArgsConstructor
public class GalleryProjectAccessChecker {

private final GalleryProjectMemberRepository _galleryProjectMemberRepository;
Copy link
Contributor

Choose a reason for hiding this comment

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

필드명이 _로 시작하는 이유가 궁금해요. 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

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

엨 뭐지 지울게요..

Comment on lines 84 to 87
@Override
public Long updateGalleryProjectByProjectId(Long projectId, GalleryProjectSaveRequestDto requestDto) {
GalleryProject galleryProject = findGalleryProjectById(projectId);
galleryProject.update(
Copy link
Contributor

Choose a reason for hiding this comment

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

@Transactional이 누락된 것 같은데, 맞는지 확인 부탁드립니다. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

항상 @Transactional을 빼먹고 이후에야 빼먹은걸 깨닫는데, 고쳐야 할 습관이라고 생각합니다😅

Copy link
Contributor

@kjoon418 kjoon418 Nov 20, 2025

Choose a reason for hiding this comment

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

클래스 단위에 @Transactional을 붙이고, 읽기 전용 메서드에 @Transactional(readOnly = true)를 붙이는 것도 괜찮은 방법이라 생각해요.
저도 자주 까먹어서 공감합니다 😅

Comment on lines 105 to 126
@PatchMapping("/{projectId}")
@Operation(
summary = "프로젝트 갤러리에 존재하는 프로젝트의 정보 수정",
description =
"""
프로젝트 갤러리에 전시되어있는 프로젝트를 수정합니다.
생성 때와 같이, 멤버 목록과 fileId 리스트를 body로 받습니다.
요청 데이터가 유효하지 않거나 필요한 필드를 입력하지 않을 경우 400 응답을 반환합니다.
leaderId에 해당하는 유저가 없거나, fileId에 해당하는 파일이 없으면 404 응답을 반환합니다.
ServiceStatus: IN_SERVICE(운영 중), NOT_IN_SERVICE(미운영 중)
MemberRole: LEADER(팀장), MEMBER(팀원)
PART: PM, DESIGN, WEB, MOBILE, BACKEND, AI
"""
)
@PreAuthorize("@galleryProjectAccessChecker.checkLeaderOrAdminPermission(#projectId, authentication)")
private ResponseEntity<Long> updateProject(@PathVariable Long projectId, @RequestBody GalleryProjectSaveRequestDto requestDto) {
Copy link
Contributor

Choose a reason for hiding this comment

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

구현이나 명세서 설명을 보면 PUT의 성격에 가깝다는 생각이 드네요. PATCH로 명시한 이유가 무엇인가요? 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

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

다시 보니 PATCH보단 PUT이 맞다고 생각이 되네요! 부분적으로 수정하는 것이 아닌, 모든 필드를 수정할 것이기에 PUT이 더 옳다고 생각됩니다.

Comment on lines 95 to 97
saveProjectMembers(galleryProject, requestDto.members());
saveProjectFiles(galleryProject, requestDto.fileIds());
return projectId;
Copy link
Contributor

Choose a reason for hiding this comment

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

이미 멤버로 등록되어 있는 사람이 다시 한번 저장될 우려가 있어 보입니다.
별도의 방어 로직이 존재한다면 공유 부탁드려요 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

이 부분에 대해서도 미처 생각치 못했던 부분이라고 생각됩니다. 수정 후 다시 커밋 하겠습니다!

@ggok0265 ggok0265 requested a review from kjoon418 November 19, 2025 14:18
Copy link
Contributor

@kjoon418 kjoon418 left a comment

Choose a reason for hiding this comment

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

엔티티 삭제 방식에 대해 의논하고 싶은 점이 있어 코멘트 남깁니다.
제가 잘못 알고 있는 것일 수 있으니, 확인 후 정정 혹은 반영해주세요 😄

Comment on lines 184 to 203
private void updateProjectMembers(GalleryProject project, List<GalleryProjectMemberInfoDto> members) {
galleryProjectMemberRepository.deleteAllByProjectId(project.getId());
Long leaderId = project.getUser().getId();
divideMemberAndSave(project, members, leaderId);
}

private void updateProjectFiles(GalleryProject project, List<Long> fileIds) {
galleryProjectFileRepository.deleteAllByProjectId(project.getId());
for (Long fileId : fileIds) {
File file = getFile(fileId);

GalleryProjectFile galleryProjectFile = GalleryProjectFile.builder()
.file(file)
.project(project)
.build();

galleryProjectFileRepository.save(galleryProjectFile);
project.getFiles().add(galleryProjectFile);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
private void updateProjectMembers(GalleryProject project, List<GalleryProjectMemberInfoDto> members) {
galleryProjectMemberRepository.deleteAllByProjectId(project.getId());
Long leaderId = project.getUser().getId();
divideMemberAndSave(project, members, leaderId);
}
private void updateProjectFiles(GalleryProject project, List<Long> fileIds) {
galleryProjectFileRepository.deleteAllByProjectId(project.getId());
for (Long fileId : fileIds) {
File file = getFile(fileId);
GalleryProjectFile galleryProjectFile = GalleryProjectFile.builder()
.file(file)
.project(project)
.build();
galleryProjectFileRepository.save(galleryProjectFile);
project.getFiles().add(galleryProjectFile);
}
}
private void updateProjectMembers(GalleryProject project, List<GalleryProjectMemberInfoDto> members) {
project.clearMembers();
Long leaderId = project.getUser().getId();
divideMemberAndSave(project, members, leaderId);
}
private void updateProjectFiles(GalleryProject project, List<Long> fileIds) {
project.clearFiles();
for (Long fileId : fileIds) {
File file = getFile(fileId);
GalleryProjectFile galleryProjectFile = GalleryProjectFile.builder()
.file(file)
.project(project)
.build();
galleryProjectFileRepository.save(galleryProjectFile);
project.getFiles().add(galleryProjectFile);
}
}

JpaRepository.delete...를 사용해 제거하면 GalleryProjectmembersfiles 컬렉션에는 반영되지 않는 것으로 알고 있습니다.
이미 연관관계에 orphanRemoval이 적용되어 있으니, 고아 객체로 만들어 삭제하는 것은 어떨까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

위 메서드는 DB만 건드리고 영속성 컨텍스트를 건드리지 않는 듯 보이네요.
현재 적용되어 있는 orphanRemoval을 활용해보도록 하겠습니다!

Copy link
Contributor

@jihoo2002 jihoo2002 left a comment

Choose a reason for hiding this comment

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

준님이 리뷰 해주신거 같아서 저는 approve 하겠습니다
고생하셨습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat Extra attention is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

프로젝트 수정(프젝갤)

3 participants