diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index c888162b..dde59a5f 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -7,7 +7,7 @@ on: - dev jobs: - deploy: + code_review: runs-on: ubuntu-latest steps: diff --git a/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentResponseDTO.java b/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentResponseDTO.java index 4912a875..5d53de04 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentResponseDTO.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentResponseDTO.java @@ -14,6 +14,7 @@ public record CommentResponseDTO( boolean deleted, String createdDate, String createdAt, + int depth, List childComments ) { public static CommentResponseDTO from(Comment comment) { @@ -24,6 +25,7 @@ public static CommentResponseDTO from(Comment comment) { comment.isDeleted(), comment.getCreatedAt().format(DateTimeFormatter.ofPattern("yy년 MM월 dd일")), comment.getCreatedAt().format(DateTimeFormatter.ofPattern("HH:mm")), + comment.getDepth(), comment.getChildComments().stream().map(CommentResponseDTO::from).collect(Collectors.toList()) ); } @@ -36,6 +38,7 @@ public static CommentResponseDTO fromDeleted(Comment comment) { true, null, null, + comment.getDepth(), comment.getChildComments().stream().map(CommentResponseDTO::from).collect(Collectors.toList()) ); } diff --git a/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentSaveRequestDTO.java b/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentSaveRequestDTO.java index fe590d34..f3314d5b 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentSaveRequestDTO.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/dto/CommentSaveRequestDTO.java @@ -10,12 +10,13 @@ public record CommentSaveRequestDTO( String content, Long parentCommentId ) { - public Comment toEntity(Member member, Diary diary, Comment parentComment) { + public Comment toEntity(Member member, Diary diary, Comment parentComment, int depth) { return Comment.builder() .member(member) .diary(diary) .content(content) .parentComment(parentComment) + .depth(depth) .build(); } } diff --git a/src/main/java/chzzk/grassdiary/domain/comment/entity/Comment.java b/src/main/java/chzzk/grassdiary/domain/comment/entity/Comment.java index 97221884..fead9088 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/entity/Comment.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/entity/Comment.java @@ -54,13 +54,17 @@ public class Comment extends BaseTimeEntity { private boolean deleted; + @Column(nullable = false) + private int depth; + @Builder - protected Comment(Member member, Diary diary, String content, Comment parentComment) { + protected Comment(Member member, Diary diary, String content, Comment parentComment, int depth) { this.member = member; this.diary = diary; this.content = content; this.parentComment = parentComment; this.deleted = false; + this.depth = depth; } public void update(String content) { diff --git a/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java b/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java index e902d9f1..e38abe44 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java @@ -35,7 +35,10 @@ public CommentResponseDTO save(Long diaryId, CommentSaveRequestDTO requestDTO, L Member member = getMemberById(logInMemberId); Diary diary = getDiaryById(diaryId); Comment parentComment = getParentCommentById(requestDTO.parentCommentId()); - Comment comment = requestDTO.toEntity(member, diary, parentComment); + + int commentDepth = calculateCommentDepth(parentComment); + validateCommentDepth(commentDepth); + Comment comment = requestDTO.toEntity(member, diary, parentComment, commentDepth); commentDAO.save(comment); return CommentResponseDTO.from(comment); @@ -125,6 +128,13 @@ private Comment getCommentById(Long id) { .orElseThrow(() -> new SystemException(ClientErrorCode.COMMENT_NOT_FOUND_ERR)); } + private int calculateCommentDepth(Comment parentComment) { + if (parentComment == null) { + return 0; + } + return parentComment.getDepth() + 1; + } + private void validateCommentAuthor(Member member, Comment comment) { if (!member.equals(comment.getMember())) { throw new SystemException(ClientErrorCode.AUTHOR_MISMATCH_ERR); @@ -136,4 +146,10 @@ private void validateNotDeleted(Comment comment) { throw new SystemException(ClientErrorCode.COMMENT_ALREADY_DELETED_ERR); } } + + private void validateCommentDepth(int depth) { + if (depth > 1) { + throw new SystemException(ClientErrorCode.COMMENT_DEPTH_EXCEEDED_ERR); + } + } } diff --git a/src/main/java/chzzk/grassdiary/domain/diary/dto/DiaryDetailDTO.java b/src/main/java/chzzk/grassdiary/domain/diary/dto/DiaryDetailDTO.java index 8c6a611a..27a78a94 100644 --- a/src/main/java/chzzk/grassdiary/domain/diary/dto/DiaryDetailDTO.java +++ b/src/main/java/chzzk/grassdiary/domain/diary/dto/DiaryDetailDTO.java @@ -16,6 +16,7 @@ public record DiaryDetailDTO( Boolean isPrivate, Integer likeCount, Boolean isLikedByLogInMember, + int commentCount, String createdDate, String createdAt, List image @@ -30,6 +31,7 @@ public static DiaryDetailDTO from(Diary diary, List tags, boolean isLik diary.getIsPrivate(), diary.getDiaryLikes().size(), isLikedByLogInMember, + diary.getComments().size(), diary.getCreatedAt().format(DateTimeFormatter.ofPattern("yy년 MM월 dd일")), diary.getCreatedAt().format(DateTimeFormatter.ofPattern("HH:mm")), image diff --git a/src/main/java/chzzk/grassdiary/domain/diary/service/DiaryService.java b/src/main/java/chzzk/grassdiary/domain/diary/service/DiaryService.java index 2a62b4b8..579efedc 100644 --- a/src/main/java/chzzk/grassdiary/domain/diary/service/DiaryService.java +++ b/src/main/java/chzzk/grassdiary/domain/diary/service/DiaryService.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -75,10 +76,7 @@ public DiarySaveResponseDTO update(Long id, DiaryUpdateRequestDTO requestDto) { } /** - * diaryId를 이용해서 diaryTag, MemberTag 를 찾아내기 - * diaryTag 삭제 -> deleteAllInBatch 고려해보기 - * MemberTag 삭제 - * 해당 일기의 좋아요 찾기 및 삭제 + * diaryId를 이용해서 diaryTag, MemberTag 를 찾아내기 diaryTag 삭제 -> deleteAllInBatch 고려해보기 MemberTag 삭제 해당 일기의 좋아요 찾기 및 삭제 * 이미지 삭제 */ @Transactional @@ -216,9 +214,7 @@ private void updateTags(Diary diary, List newHashtags) { } private int makeRewardPoint() { - long seed = System.currentTimeMillis(); - Random random = new Random(seed); - return random.nextInt(10) + 1; + return 50 + (ThreadLocalRandom.current().nextInt(6) * 10); } private void saveRewardPointAndHistory(Member member, int rewardPoint) { @@ -276,6 +272,7 @@ private void decrementTagsCount(List tags) { } } } + private void removeDiaryLikes(Long diaryId) { List diaryLikes = diaryLikeDAO.findAllByDiaryId(diaryId); diaryLikeDAO.deleteAll(diaryLikes); diff --git a/src/main/java/chzzk/grassdiary/domain/image/controller/ImageController.java b/src/main/java/chzzk/grassdiary/domain/image/controller/ImageController.java index ebe2abd5..c2f625bc 100644 --- a/src/main/java/chzzk/grassdiary/domain/image/controller/ImageController.java +++ b/src/main/java/chzzk/grassdiary/domain/image/controller/ImageController.java @@ -10,9 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; @@ -40,14 +38,6 @@ public ResponseEntity uploadDiaryImage( .body(imageService.uploadImage(image, FileFolder.PERSONAL_DIARY)); } - @DeleteMapping("/diary/{diaryId}") - public ResponseEntity deleteDiaryImage( - @PathVariable Long diaryId - ) { - imageService.deleteImage(diaryId); - return ResponseEntity.ok().build(); - } - private ResponseEntity sendImage(String mainBannerUrl) throws IOException { Resource resource = new ClassPathResource(mainBannerUrl); if (!resource.exists()) { diff --git a/src/main/java/chzzk/grassdiary/domain/image/service/DiaryImageService.java b/src/main/java/chzzk/grassdiary/domain/image/service/DiaryImageService.java index ad562b6d..a3c8eaca 100644 --- a/src/main/java/chzzk/grassdiary/domain/image/service/DiaryImageService.java +++ b/src/main/java/chzzk/grassdiary/domain/image/service/DiaryImageService.java @@ -37,7 +37,7 @@ public void mappingImageToDiary(Diary diary, Long imageId) { public void deleteImageAndMapping(Diary diary) { diaryToImageDAO.findByDiaryId(diary.getId()).ifPresent(diaryImage -> { - imageService.deleteImage(diaryImage.getId()); + imageService.deleteImage(diaryImage.getImage().getId()); diaryToImageDAO.delete(diaryImage); }); } diff --git a/src/main/java/chzzk/grassdiary/global/common/response/ClientErrorCode.java b/src/main/java/chzzk/grassdiary/global/common/response/ClientErrorCode.java index a9704398..41990a92 100644 --- a/src/main/java/chzzk/grassdiary/global/common/response/ClientErrorCode.java +++ b/src/main/java/chzzk/grassdiary/global/common/response/ClientErrorCode.java @@ -23,6 +23,7 @@ public enum ClientErrorCode implements ErrorCodeModel { IMAGE_MAPPING_NOT_FOUND_ERR(400, "IMAGE_MAPPING_NOT_FOUND_ERR", "해당 이미지를 찾을 수 없습니다.(이미지 등록 값 없음)"), AUTHOR_MISMATCH_ERR(403, "AUTHOR_MISMATCH_ERR", "작성자가 아닙니다."), COMMENT_ALREADY_DELETED_ERR(400, "COMMENT_ALREADY_DELETED_ERR", "이미 삭제된 댓글입니다."), + COMMENT_DEPTH_EXCEEDED_ERR(400, "COMMENT_DEPTH_EXCEEDED_ERR", "댓글은 대댓글까지만 허용합니다."), VALIDATION_ERR(400, "VALIDATION_ERR", "잘못된 입력입니다. 올바른 값을 입력해주세요."), PERMISSION_ERR(403, "PERMISSION_ERR", "접근 권한이 없습니다. 관리자에게 문의하세요."),