Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ public ResponseEntity<ApiResponse<QuestionResDTO.StatusUpdateRes>> updateQuestio
questionService.updateQuestionStatus(questionId, userId));
}

// 댓글 수정
// PATCH /api/comments/{commentId}
@PatchMapping("/api/comments/{commentId}")
public ResponseEntity<ApiResponse<QuestionResDTO.CommentUpdateDeleteRes>> updateComment(
@PathVariable Long commentId,
@RequestBody QuestionReqDTO.CommentUpdateReq request,
@AuthenticationPrincipal Long userId
) {
return ResponseUtil.success(QuestionSuccessCode.COMMENT_UPDATED,
questionService.updateComment(commentId, request, userId));
}

// 댓글 삭제
// DELETE /api/comments/{commentId}
@DeleteMapping("/api/comments/{commentId}")
public ResponseEntity<ApiResponse<QuestionResDTO.CommentUpdateDeleteRes>> deleteComment(
@PathVariable Long commentId,
@AuthenticationPrincipal Long userId
) {
return ResponseUtil.success(QuestionSuccessCode.COMMENT_DELETED,
questionService.deleteComment(commentId, userId));
}

// 이해도 체크 생성
// POST /api/sessions/{sessionId}/understanding-checks
@PostMapping("/api/sessions/{sessionId}/understanding-checks")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ public static class CommentReq {
private Long parentCommentId; // 대댓글일 때만 값이 있음, 일반 댓글이면 null
}

// 댓글 수정 요청
@Getter
@NoArgsConstructor
public static class CommentUpdateReq {
private String content;
}

// 이해도 체크 응답 요청
@Getter
@NoArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ public record CommentCreateRes(
) {
}

// 댓글 수정/삭제 응답
public record CommentUpdateDeleteRes(
Long commentId,
String content,
LocalDateTime updatedAt,
LocalDateTime deletedAt
) {
}

// 좋아요 토글 응답
// isLiked: true면 좋아요 추가된 상태, false면 취소된 상태
public record LikeRes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,16 @@ public class QuestionComment {

@Column(name = "deleted_at")
private LocalDateTime deletedAt;

// 댓글 내용 수정
public void updateContent(String content) {
this.content = content;
this.updatedAt = LocalDateTime.now();
}

// 댓글 소프트 삭제
public void softDelete() {
this.deletedAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public enum QuestionSuccessCode implements BaseCode {
QUESTION_STATUS_UPDATED(HttpStatus.OK, "QUESTION200_7", "질문 상태가 변경되었습니다."),
QUESTION_CREATED(HttpStatus.CREATED, "QUESTION201_1", "질문이 등록되었습니다."),
COMMENT_CREATED(HttpStatus.CREATED, "QUESTION201_2", "댓글이 등록되었습니다."),
COMMENT_UPDATED(HttpStatus.OK, "QUESTION200_8", "댓글이 수정되었습니다."),
COMMENT_DELETED(HttpStatus.OK, "QUESTION200_9", "댓글이 삭제되었습니다."),
UNDERSTANDING_CHECK_CREATED(HttpStatus.CREATED, "QUESTION201_3", "이해도 체크가 생성되었습니다.");

private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,40 @@ public QuestionResDTO.UpdateDeleteRes deleteQuestion(Long questionId, Long userI
);
}

// 댓글 수정
@Transactional
public QuestionResDTO.CommentUpdateDeleteRes updateComment(
Long commentId,
QuestionReqDTO.CommentUpdateReq request,
Long userId
) {
User loginUser = findLoginUser(userId);
QuestionComment comment = findComment(commentId);
validateCommentOwner(comment, loginUser);

comment.updateContent(request.getContent());

return new QuestionResDTO.CommentUpdateDeleteRes(
comment.getId(), comment.getContent(),
comment.getUpdatedAt(), comment.getDeletedAt()
);
}

// 댓글 삭제
@Transactional
public QuestionResDTO.CommentUpdateDeleteRes deleteComment(Long commentId, Long userId) {
User loginUser = findLoginUser(userId);
QuestionComment comment = findComment(commentId);
validateCommentOwner(comment, loginUser);

comment.softDelete();

return new QuestionResDTO.CommentUpdateDeleteRes(
comment.getId(), comment.getContent(),
comment.getUpdatedAt(), comment.getDeletedAt()
);
}

// 질문 상태 완료 전환
// PATCH /api/questions/{questionId}/status
@Transactional
Expand Down Expand Up @@ -404,6 +438,18 @@ private void validateQuestionOwner(Question question, User loginUser) {
}
}

private void validateCommentOwner(QuestionComment comment, User loginUser) {
if (!comment.getUser().getId().equals(loginUser.getId())) {
throw new QuestionException(HttpStatus.FORBIDDEN, "본인의 댓글만 수정/삭제할 수 있습니다.");
}
}

private QuestionComment findComment(Long commentId) {
return questionCommentRepository.findById(commentId)
.filter(c -> c.getDeletedAt() == null)
.orElseThrow(() -> new QuestionException(HttpStatus.NOT_FOUND, "댓글을 찾을 수 없습니다."));
}

private UnderstandResChoice applyUnderstandingResponse(
UnderstandingCheck check, User loginUser, UnderstandResChoice requestedChoice
) {
Expand Down
Loading