diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/controller/QuestionController.java b/backend/src/main/java/com/example/Piroin/project/domain/question/controller/QuestionController.java index 543f41d..3cd0b8a 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/controller/QuestionController.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/controller/QuestionController.java @@ -109,6 +109,7 @@ public ResponseEntity> deleteQuestio } // 질문 상태 완료 전환 (관리자 전용) + // 부원이 댓글을 달아 미해결로 자동 전환되는 흐름은 댓글 등록 서비스 내부에서만 처리한다. // PATCH /api/questions/{questionId}/status @PatchMapping("/api/questions/{questionId}/status") public ResponseEntity> updateQuestionStatus( diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/dto/QuestionResDTO.java b/backend/src/main/java/com/example/Piroin/project/domain/question/dto/QuestionResDTO.java index 5b49df7..0347795 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/dto/QuestionResDTO.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/dto/QuestionResDTO.java @@ -37,6 +37,7 @@ public record CommentCreateRes( Long questionId, String displayName, String content, + Boolean isResolved, LocalDateTime createdAt ) { } @@ -91,6 +92,7 @@ public record CommentResponse( String displayName, String content, String imageUrl, + Boolean isMine, LocalDateTime createdAt, List replies ) { @@ -186,6 +188,8 @@ public record CommentCreatedEvent( String type, Long sessionId, Long questionId, + // 댓글 작성 후 서버 내부 규칙까지 반영된 최신 해결 상태 + Boolean isResolved, Integer commentCount, List previewComments ) { diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java b/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java index f877bf0..0d47992 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java @@ -86,7 +86,7 @@ private QuestionResDTO.QuestionDetailResponse toDetailResponse(Question question questionCommentRepository.findByQuestionAndParentCommentIsNullAndDeletedAtIsNullOrderByCreatedAtAsc(question); List commentResponses = topComments.stream() - .map(comment -> toCommentResponse(question, comment)) + .map(comment -> toCommentResponse(question, comment, loginUser)) .toList(); return new QuestionResDTO.QuestionDetailResponse( @@ -97,23 +97,29 @@ private QuestionResDTO.QuestionDetailResponse toDetailResponse(Question question ); } - private QuestionResDTO.CommentResponse toCommentResponse(Question question, QuestionComment comment) { + private QuestionResDTO.CommentResponse toCommentResponse(Question question, QuestionComment comment, User loginUser) { List replies = questionCommentRepository.findByParentCommentAndDeletedAtIsNullOrderByCreatedAtAsc(comment); List replyResponses = replies.stream() .map(reply -> new QuestionResDTO.CommentResponse( reply.getId(), getDisplayName(question, reply.getUser()), - reply.getContent(), reply.getImageUrl(), reply.getCreatedAt(), List.of() + reply.getContent(), reply.getImageUrl(), isCommentMine(reply, loginUser), + reply.getCreatedAt(), List.of() )) .toList(); return new QuestionResDTO.CommentResponse( comment.getId(), getDisplayName(question, comment.getUser()), - comment.getContent(), comment.getImageUrl(), comment.getCreatedAt(), replyResponses + comment.getContent(), comment.getImageUrl(), isCommentMine(comment, loginUser), + comment.getCreatedAt(), replyResponses ); } + private boolean isCommentMine(QuestionComment comment, User loginUser) { + return comment.getUser().getId().equals(loginUser.getId()); + } + // 댓글 등록 // POST /api/questions/{questionId}/comments @Transactional @@ -141,7 +147,8 @@ public QuestionResDTO.CommentCreateRes createComment( .build(); questionCommentRepository.save(comment); - // 3. 해결된 질문에 댓글이 달리면 미해결로 자동 전환 + // 수동 해결/미해결 변경은 운영진 권한이 필요하지만, + // 댓글 작성으로 인한 미해결 전환은 권한 API가 아니라 서버 내부 도메인 규칙이다. if (question.getIsResolved()) { question.markUnresolved(); } @@ -150,7 +157,8 @@ public QuestionResDTO.CommentCreateRes createComment( String displayName = assignAnonymousIdentity(question, loginUser); QuestionResDTO.CommentCreateRes response = new QuestionResDTO.CommentCreateRes( - comment.getId(), question.getId(), displayName, comment.getContent(), comment.getCreatedAt() + comment.getId(), question.getId(), displayName, + comment.getContent(), question.getIsResolved(), comment.getCreatedAt() ); // DB 반영이 끝난 뒤 같은 질문방 구독자들이 목록 댓글 미리보기를 갱신하도록 알린다. @@ -337,7 +345,8 @@ public QuestionResDTO.CommentUpdateDeleteRes deleteComment(Long commentId, Long @Transactional public QuestionResDTO.StatusUpdateRes updateQuestionStatus(Long questionId, Long userId) { User loginUser = findLoginUser(userId); - validateAdmin(loginUser); // 관리자만 호출 가능 + // 사용자가 직접 상태를 바꾸는 수동 해결 처리는 운영진만 가능하다. + validateAdmin(loginUser); Question question = findQuestion(questionId); question.markResolved(); @@ -660,6 +669,7 @@ private void publishCommentCreatedEventAfterCommit(Question question) { "COMMENT_CREATED", sessionId, questionId, + question.getIsResolved(), summaryContext.commentCounts().getOrDefault(questionId, 0), summaryContext.previewComments().getOrDefault(questionId, List.of()) );