From c66af3ab0afe0ae6a4f0b2e5c615235f4687cb6a Mon Sep 17 00:00:00 2001 From: juhyun Date: Fri, 20 Feb 2026 15:20:19 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor=20:=20=EC=BD=94=EB=A9=98=ED=8A=B8?= =?UTF-8?q?=20GET,=20POST=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/MeetingRetrospectiveApi.java | 22 +++++-------------- .../MeetingRetrospectiveController.java | 7 +++--- .../request/MeetingRetrospectiveRequest.java | 5 ----- .../MeetingRetrospectiveResponse.java | 6 ++--- .../entity/MeetingRetrospective.java | 11 +++------- .../repository/RetrospectiveRepository.java | 12 +++++----- .../service/MeetingRetrospectiveService.java | 20 ++++++----------- 7 files changed, 28 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/dokdok/retrospective/api/MeetingRetrospectiveApi.java b/src/main/java/com/dokdok/retrospective/api/MeetingRetrospectiveApi.java index 5932d308..e91fd3ad 100644 --- a/src/main/java/com/dokdok/retrospective/api/MeetingRetrospectiveApi.java +++ b/src/main/java/com/dokdok/retrospective/api/MeetingRetrospectiveApi.java @@ -114,9 +114,9 @@ ResponseEntity> getMeetingRetrospectiv ); @Operation( - summary = "토픽별 코멘트 조회 (developer: 오주현)", + summary = "코멘트 조회 (developer: 오주현)", description = """ - 특정 토픽의 코멘트를 조회합니다. + 약속 회고의 코멘트를 조회합니다. - 커서 기반 무한스크롤을 지원합니다. - 첫 페이지: cursorCreatedAt, cursorCommentId 없이 호출 - 다음 페이지: 응답의 nextCursor 값을 파라미터로 전달 @@ -133,11 +133,11 @@ ResponseEntity> getMeetingRetrospectiv examples = @ExampleObject(value = """ { "code": "SUCCESS", - "message": "토픽 코멘트 조회 성공", + "message": "코멘트 조회 성공", "data": { "items": [ { - "meetingRetrospectiveId": 1, + "commentId": 1, "userId": 1, "nickname": "사용자1", "profileImageUrl": "https://example.com/profile.jpg", @@ -179,21 +179,14 @@ ResponseEntity> getMeetingRetrospectiv ), @io.swagger.v3.oas.annotations.responses.ApiResponse( responseCode = "404", - description = "약속 또는 토픽을 찾을 수 없음", + description = "약속을 찾을 수 없음", content = @Content( mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject( - name = "약속 없음", value = """ {"code": "M001", "message": "약속을 찾을 수 없습니다.", "data": null} """ - ), - @ExampleObject( - name = "토픽 없음", - value = """ - {"code": "T001", "message": "토픽을 찾을 수 없습니다.", "data": null} - """ ) } ) @@ -214,9 +207,6 @@ ResponseEntity> getMeetingRetro @GetMapping("/comments") public ResponseEntity>> getTopicComments( @PathVariable Long meetingId, - @RequestParam Long topicId, @RequestParam(defaultValue = "10") int pageSize, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime cursorCreatedAt, @RequestParam(required = false) Long cursorCommentId ) { CursorResponse response = - meetingRetrospectiveService.getTopicComments( - meetingId, topicId, pageSize, cursorCreatedAt, cursorCommentId + meetingRetrospectiveService.getComments( + meetingId, pageSize, cursorCreatedAt, cursorCommentId ); - return ApiResponse.success(response, "토픽 코멘트 조회 성공"); + return ApiResponse.success(response, "코멘트 조회 성공"); } @Override diff --git a/src/main/java/com/dokdok/retrospective/dto/request/MeetingRetrospectiveRequest.java b/src/main/java/com/dokdok/retrospective/dto/request/MeetingRetrospectiveRequest.java index 9a83f2f8..1ec20d8f 100644 --- a/src/main/java/com/dokdok/retrospective/dto/request/MeetingRetrospectiveRequest.java +++ b/src/main/java/com/dokdok/retrospective/dto/request/MeetingRetrospectiveRequest.java @@ -9,11 +9,6 @@ @Schema(description = "모임 회고 작성 요청") @Builder public record MeetingRetrospectiveRequest( - - @Schema(description = "주제 ID", example = "1", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull - Long topicId, - @Schema(description = "회고 코멘트 (공백 포함 500자 이내)", example = "이번 모임에서 핵심 논의가 잘 정리되었습니다.", requiredMode = Schema.RequiredMode.REQUIRED) @NotBlank @Size(max = 500, message = "회고 코멘트는 500자 이내로 작성해주세요.") diff --git a/src/main/java/com/dokdok/retrospective/dto/response/MeetingRetrospectiveResponse.java b/src/main/java/com/dokdok/retrospective/dto/response/MeetingRetrospectiveResponse.java index 6865eabd..1f6c338a 100644 --- a/src/main/java/com/dokdok/retrospective/dto/response/MeetingRetrospectiveResponse.java +++ b/src/main/java/com/dokdok/retrospective/dto/response/MeetingRetrospectiveResponse.java @@ -96,8 +96,8 @@ public static KeyPointResponse from(TopicRetrospectiveSummary.KeyPoint keyPoint) @Schema(description = "모임 회고 코멘트") @Builder public record CommentResponse( - @Schema(description = "모임 회고 ID", example = "1") - Long meetingRetrospectiveId, + @Schema(description = "코멘트 ID", example = "1") + Long commentId, @Schema(description = "작성자 사용자 ID", example = "1") Long userId, @Schema(description = "닉네임", example = "독서왕") @@ -112,7 +112,7 @@ public record CommentResponse( public static CommentResponse from(MeetingRetrospective retrospective, String presignedProfileImageUrl) { return CommentResponse.builder() - .meetingRetrospectiveId(retrospective.getId()) + .commentId(retrospective.getId()) .userId(retrospective.getCreatedBy().getId()) .nickname(retrospective.getCreatedBy().getNickname()) .profileImageUrl(presignedProfileImageUrl) diff --git a/src/main/java/com/dokdok/retrospective/entity/MeetingRetrospective.java b/src/main/java/com/dokdok/retrospective/entity/MeetingRetrospective.java index 3502a48e..11a85929 100644 --- a/src/main/java/com/dokdok/retrospective/entity/MeetingRetrospective.java +++ b/src/main/java/com/dokdok/retrospective/entity/MeetingRetrospective.java @@ -35,19 +35,14 @@ public class MeetingRetrospective extends BaseTimeEntity { @JoinColumn(name = "created_by", nullable = false) private User createdBy; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "topic_id") - private Topic topic; - @Column(name = "comment", columnDefinition = "TEXT") private String comment; - public static MeetingRetrospective of(Meeting meeting, User user, Topic topic, String comment){ + public static MeetingRetrospective of(Meeting meeting, User user, String comment){ return MeetingRetrospective.builder() .meeting(meeting) .createdBy(user) - .topic(topic) - .comment(comment). - build(); + .comment(comment) + .build(); } } diff --git a/src/main/java/com/dokdok/retrospective/repository/RetrospectiveRepository.java b/src/main/java/com/dokdok/retrospective/repository/RetrospectiveRepository.java index 45ce38c8..e194279a 100644 --- a/src/main/java/com/dokdok/retrospective/repository/RetrospectiveRepository.java +++ b/src/main/java/com/dokdok/retrospective/repository/RetrospectiveRepository.java @@ -18,26 +18,26 @@ public interface RetrospectiveRepository extends JpaRepository findByTopicIdFirstPage( - @Param("topicId") Long topicId, + @Param("meetingId") Long meetingId, Pageable pageable ); @Query("SELECT mr FROM MeetingRetrospective mr " + "JOIN FETCH mr.createdBy " + - "WHERE mr.topic.id = :topicId " + + "WHERE mr.meeting.id = :meetingId " + "AND (mr.createdAt < :cursorCreatedAt " + " OR (mr.createdAt = :cursorCreatedAt AND mr.id < :cursorCommentId)) " + "ORDER BY mr.createdAt DESC, mr.id DESC") List findByTopicIdAfterCursor( - @Param("topicId") Long topicId, + @Param("meetingId") Long meetingId, @Param("cursorCreatedAt") LocalDateTime cursorCreatedAt, @Param("cursorCommentId") Long cursorCommentId, Pageable pageable ); - @Query("SELECT COUNT(mr) FROM MeetingRetrospective mr WHERE mr.topic.id = :topicId") - int countByTopicId(@Param("topicId") Long topicId); + @Query("SELECT COUNT(mr) FROM MeetingRetrospective mr WHERE mr.meeting.id = :meetingId") + int countByTopicId(@Param("meetingId") Long meetingId); } diff --git a/src/main/java/com/dokdok/retrospective/service/MeetingRetrospectiveService.java b/src/main/java/com/dokdok/retrospective/service/MeetingRetrospectiveService.java index 7979b0f3..e84c5c15 100644 --- a/src/main/java/com/dokdok/retrospective/service/MeetingRetrospectiveService.java +++ b/src/main/java/com/dokdok/retrospective/service/MeetingRetrospectiveService.java @@ -78,9 +78,8 @@ public MeetingRetrospectiveResponse getMeetingRetrospective(Long meetingId){ /** * 토픽별 코멘트 조회 (무한 스크롤) */ - public CursorResponse getTopicComments( + public CursorResponse getComments( Long meetingId, - Long topicId, int pageSize, LocalDateTime cursorCreatedAt, Long cursorCommentId @@ -90,9 +89,7 @@ public CursorResponse buildSummaryMap(List topics) } private CursorResponse fetchComments( - Long topicId, + Long meetingId, int pageSize, LocalDateTime cursorCreatedAt, Long cursorCommentId @@ -157,8 +151,8 @@ private CursorResponse comments = isFirstPage - ? retrospectiveRepository.findByTopicIdFirstPage(topicId, pageable) - : retrospectiveRepository.findByTopicIdAfterCursor(topicId, cursorCreatedAt, cursorCommentId, pageable); + ? retrospectiveRepository.findByTopicIdFirstPage(meetingId, pageable) + : retrospectiveRepository.findByTopicIdAfterCursor(meetingId, cursorCreatedAt, cursorCommentId, pageable); boolean hasNext = comments.size() > pageSize; List pageComments = hasNext @@ -170,7 +164,7 @@ private CursorResponse Date: Fri, 20 Feb 2026 15:39:45 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor=20:=20test=20code=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MeetingRetrospectiveServiceTest.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/dokdok/retrospective/service/MeetingRetrospectiveServiceTest.java b/src/test/java/com/dokdok/retrospective/service/MeetingRetrospectiveServiceTest.java index e4750381..7f9a1255 100644 --- a/src/test/java/com/dokdok/retrospective/service/MeetingRetrospectiveServiceTest.java +++ b/src/test/java/com/dokdok/retrospective/service/MeetingRetrospectiveServiceTest.java @@ -26,7 +26,6 @@ import com.dokdok.topic.entity.TopicStatus; import com.dokdok.topic.repository.TopicAnswerRepository; import com.dokdok.topic.repository.TopicRepository; -import com.dokdok.topic.service.TopicValidator; import com.dokdok.user.entity.User; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -72,9 +71,6 @@ class MeetingRetrospectiveServiceTest { @Mock private MeetingValidator meetingValidator; - @Mock - private TopicValidator topicValidator; - @Test @DisplayName("약속이 없으면 예외가 발생한다") void getMeetingRetrospective_throwsWhenMeetingNotFound() { @@ -190,21 +186,18 @@ void createMeetingRetrospective_success() { // given Long meetingId = 1L; Long userId = 1L; - Long topicId = 1L; Long gatheringId = 1L; Gathering gathering = Gathering.builder().id(gatheringId).build(); Meeting meeting = Meeting.builder().id(meetingId).gathering(gathering).build(); User user = User.builder().id(userId).nickname("사용자1").profileImageUrl("https://image.jpg").build(); - Topic topic = Topic.builder().id(topicId).meeting(meeting).title("토픽1").build(); - MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest(topicId, "회고 코멘트입니다."); + MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest("회고 코멘트입니다."); MeetingRetrospective saved = MeetingRetrospective.builder() .id(1L) .meeting(meeting) .createdBy(user) - .topic(topic) .comment("회고 코멘트입니다.") .build(); @@ -217,7 +210,6 @@ void createMeetingRetrospective_success() { when(meetingValidator.findMeetingOrThrow(meetingId)).thenReturn(meeting); doNothing().when(retrospectiveValidator).validateMeetingRetrospectiveAccess(gatheringId, meetingId, userId); - when(topicValidator.getTopicInMeeting(topicId, meetingId)).thenReturn(topic); when(retrospectiveRepository.save(any(MeetingRetrospective.class))).thenReturn(saved); when(storageService.getPresignedProfileImage("https://image.jpg")).thenReturn("https://image.jpg"); @@ -226,13 +218,12 @@ void createMeetingRetrospective_success() { meetingRetrospectiveService.createMeetingRetrospective(meetingId, request); // then - assertThat(response.meetingRetrospectiveId()).isEqualTo(1L); + assertThat(response.commentId()).isEqualTo(1L); assertThat(response.userId()).isEqualTo(userId); assertThat(response.comment()).isEqualTo("회고 코멘트입니다."); verify(meetingValidator).findMeetingOrThrow(meetingId); verify(retrospectiveValidator).validateMeetingRetrospectiveAccess(gatheringId, meetingId, userId); - verify(topicValidator).getTopicInMeeting(topicId, meetingId); verify(retrospectiveRepository).save(any(MeetingRetrospective.class)); } } @@ -243,7 +234,7 @@ void createMeetingRetrospective_throwsWhenMeetingNotFound() { Long meetingId = 999L; Long userId = 1L; User user = User.builder().id(userId).build(); - MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest(1L, "코멘트"); + MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest("코멘트"); CustomOAuth2User customOAuth2User = mock(CustomOAuth2User.class); when(customOAuth2User.getUser()).thenReturn(user); @@ -273,7 +264,7 @@ void createMeetingRetrospective_throwsWhenNoAccess() { Gathering gathering = Gathering.builder().id(gatheringId).build(); Meeting meeting = Meeting.builder().id(meetingId).gathering(gathering).build(); User user = User.builder().id(userId).build(); - MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest(1L, "코멘트"); + MeetingRetrospectiveRequest request = new MeetingRetrospectiveRequest( "코멘트"); CustomOAuth2User customOAuth2User = mock(CustomOAuth2User.class); when(customOAuth2User.getUser()).thenReturn(user);