Skip to content

Commit

Permalink
#23 [fix] conflict 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
parkheeddong committed Jan 7, 2024
2 parents 68257b1 + 9cd91ec commit e5cc6e9
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.mile.controller.comment;


import com.mile.comment.service.CommentService;
import com.mile.dto.SuccessResponse;
import com.mile.exception.message.SuccessMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.Principal;

@RestController
@RequestMapping("/api/comment")
@RequiredArgsConstructor
public class CommentController implements CommentControllerSwagger{

private final CommentService commentService;

@DeleteMapping("/{commentId}")
public SuccessResponse deleteComment(
@PathVariable final Long commentId,
final Principal principal
) {
commentService.deleteComment(commentId, Long.valueOf(principal.getName()));
return SuccessResponse.of(SuccessMessage.COMMENT_DELETE_SUCCESS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.mile.controller.comment;

import com.mile.dto.ErrorResponse;
import com.mile.dto.SuccessResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PathVariable;

import java.security.Principal;

@Tag(name = "Comment", description = "댓글 관련 API - 현재는 댓글 삭제만 API 해당")
public interface CommentControllerSwagger {

@Operation(description = "댓글 삭제 API")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "댓글 삭제가 완료되었습니다."),
@ApiResponse(responseCode = "403", description = "해당 사용자는 댓글에 접근 권한이 없습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "해당 댓글이 존재하지 않습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "서버 내부 오류입니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
}
)
SuccessResponse deleteComment(
@PathVariable final Long commentId,
final Principal principal
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.mile.exception.message.SuccessMessage;
import com.mile.post.service.PostService;
import com.mile.post.service.dto.CommentCreateRequest;
import com.mile.post.service.dto.CommentListResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
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.RequestBody;
Expand All @@ -17,7 +19,7 @@
@RestController
@RequestMapping("/api/post")
@RequiredArgsConstructor
public class PostController implements PostControllerSwagger{
public class PostController implements PostControllerSwagger {

private final PostService postService;

Expand All @@ -37,6 +39,7 @@ public SuccessResponse postComment(
}



@PostMapping("/{postId}/curious")
@Override
public SuccessResponse postCurious(
Expand All @@ -46,4 +49,13 @@ public SuccessResponse postCurious(
postService.createCuriousOnPost(postId, Long.valueOf(principal.getName()));
return SuccessResponse.of(SuccessMessage.CURIOUS_CREATE_SUCCESS);
}

@GetMapping("/{postId}/comment")
@Override
public SuccessResponse<CommentListResponse> getComments(
@PathVariable final Long postId,
final Principal principal
) {
return SuccessResponse.of(SuccessMessage.COMMENT_SEARCH_SUCCESS, postService.getComments(postId, Long.valueOf(principal.getName())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.mile.dto.ErrorResponse;
import com.mile.dto.SuccessResponse;
import com.mile.post.service.dto.CommentCreateRequest;
import com.mile.post.service.dto.CommentListResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
Expand Down Expand Up @@ -38,6 +39,7 @@ SuccessResponse postComment(
final Principal principal
);


@Operation(summary = "궁금해요 생성")
@ApiResponses(
value = {
Expand All @@ -52,4 +54,21 @@ SuccessResponse postCurious(
@PathVariable final Long postId,
final Principal principal
);

@Operation(summary = "댓글 리스트 조회")
@ApiResponses(
value = {
@ApiResponse(responseCode = "200", description = "댓글 조회가 완료되었습니다."),
@ApiResponse(responseCode = "403", description = "해당 사용자는 모임에 접근 권한이 없습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "해당 글에 대한 댓글이 존재하지 않습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "서버 내부 오류입니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
}
)
SuccessResponse<CommentListResponse> getComments(
@PathVariable final Long postId,
final Principal principal
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@ public enum ErrorMessage {
USER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 유저는 존재하지 않습니다."),
REFRESH_TOKEN_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 유저의 리프레시 토큰이 존재하지 않습니다."),
POST_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 글은 존재하지 않습니다."),

COMMENTS_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 글에 대한 댓글이 존재하지 않습니다."),
MOIM_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 글모임이 존재하지 않습니다."),
CONTENT_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 모임의 주제가 존재하지 않습니다."),
HANDLER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "요청하신 URL은 정보가 없습니다."),

COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 댓글이 존재하지 않습니다."),
/*
Bad Request
*/
ENUM_VALUE_BAD_REQUEST(HttpStatus.BAD_REQUEST.value(), "요청한 값이 유효하지 않습니다."),
AUTHENTICATION_CODE_EXPIRED(HttpStatus.BAD_REQUEST.value(), "인가 코드가 만료되었습니다."),
SOCIAL_TYPE_BAD_REQUEST(HttpStatus.BAD_REQUEST.value(), "로그인 요청이 유효하지 않습니다."),

VALIDATION_REQUEST_MISSING_EXCEPTION(HttpStatus.BAD_REQUEST.value(), "요청 값이 유효하지 않습니다."),

BEARER_LOST_ERROR(HttpStatus.BAD_REQUEST.value(), "토큰의 요청에 Bearer이 담겨 있지 않습니다."),

CURIOUS_ALREADY_EXISTS_EXCEPTION(HttpStatus.BAD_REQUEST.value(), "'궁금해요'는 이미 존재합니다."),
Expand All @@ -42,6 +41,10 @@ public enum ErrorMessage {
*/
USER_AUTHENTICATE_ERROR(HttpStatus.FORBIDDEN.value(), "해당 사용자는 모임에 접근 권한이 없습니다."),

/*
Forbidden
*/
COMMENT_ACCESS_ERROR(HttpStatus.FORBIDDEN.value(), "해당 사용자는 댓글에 접근 권한이 없습니다."),
/*
Internal Server Error
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ public enum SuccessMessage {
LOGIN_SUCCESS(HttpStatus.OK.value(), "소셜 로그인이 완료되었습니다."),
ISSUE_ACCESS_TOKEN_SUCCESS(HttpStatus.OK.value(), "액세스 토큰 재발급이 완료되었습니다."),
USER_DELETE_SUCCESS(HttpStatus.OK.value(), "회원 삭제가 완료되었습니다."),
COMMENT_DELETE_SUCCESS(HttpStatus.OK.value(), "댓글 삭제가 완료되었습니다."),
LOGOUT_SUCCESS(HttpStatus.OK.value(), "로그아웃이 완료되었습니다."),

TOPIC_SEARCH_SUCCESS(HttpStatus.OK.value(), "주제 조회가 완료되었습니다."),
COMMENT_SEARCH_SUCCESS(HttpStatus.OK.value(), "댓글 조회가 완료되었습니다."),
/*
201 CREATED
*/
COMMENT_CREATE_SUCCESS(HttpStatus.CREATED.value(), "댓글 등록이 완료되었습니다."),
CURIOUS_CREATE_SUCCESS(HttpStatus.CREATED.value(), "궁금해요 생성이 완료되었습니다."),

TOPIC_SEARCH_SUCCESS(HttpStatus.OK.value(), "주제 조회가 완료되었습니다."),
;

int status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mile.post.domain.Post;
import com.mile.post.service.dto.CommentCreateRequest;
import com.mile.user.domain.User;
import com.mile.writerName.domain.WriterName;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
Expand All @@ -12,9 +13,11 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor
Expand All @@ -30,19 +33,19 @@ public class Comment extends BaseTimeEntity {
private boolean anonymous;

@ManyToOne
private User user;
private WriterName writerName;

public static Comment create(
final Post post,
final User user,
final WriterName writerName,
final CommentCreateRequest createRequest,
final boolean anonymous
) {
return Comment
.builder()
.post(post)
.content(createRequest.content())
.user(user)
.writerName(writerName)
.anonymous(anonymous)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

import com.mile.comment.domain.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface CommentRepository extends JpaRepository<Comment, Long> {
}

@Query("select c.writerName.writer.id from Comment c where c = :comment")
Long findUserIdByComment(@Param(value = "comment") final Comment comment);

List<Comment> findByPostId(final Long postId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,97 @@

import com.mile.comment.domain.Comment;
import com.mile.comment.repository.CommentRepository;
import com.mile.exception.message.ErrorMessage;
import com.mile.exception.model.ForbiddenException;
import com.mile.exception.model.NotFoundException;
import com.mile.comment.service.dto.CommentResponse;
import com.mile.post.domain.Post;
import com.mile.post.service.PostAuthenticateService;
import com.mile.post.service.dto.CommentCreateRequest;
import com.mile.user.domain.User;
import com.mile.writerName.domain.WriterName;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentService {

private static boolean ANONYMOUS_TRUE = true;
private final PostAuthenticateService postAuthenticateService;
private final CommentRepository commentRepository;

@Transactional
public void deleteComment(
final Long commentId,
final Long userId
) {
Comment comment = findById(commentId);
authenticateUser(comment, userId);
delete(comment);
}

private void delete(
final Comment comment
) {
commentRepository.delete(comment);
}

private Comment findById(
final Long commentId
) {
return commentRepository.findById(commentId)
.orElseThrow(
() -> new NotFoundException(ErrorMessage.COMMENT_NOT_FOUND)
);
}
private void authenticateUser(
final Comment comment,
final Long userId
) {
if(!commentRepository.findUserIdByComment(comment).equals(userId)) {
throw new ForbiddenException(ErrorMessage.COMMENT_ACCESS_ERROR);
}
}
public void createComment(
final Post post,
final User user,
final WriterName writerName,
final CommentCreateRequest commentCreateRequest
) {
commentRepository.save(Comment.create(post, user, commentCreateRequest, ANONYMOUS_TRUE));
commentRepository.save(Comment.create(post, writerName, commentCreateRequest, ANONYMOUS_TRUE));
}

public List<CommentResponse> getCommentResponse(
final Long postId,
final Long userId
) {
postAuthenticateService.authenticateUserWithPostId(postId, userId);
List<Comment> commentList = findByPostId(postId);
throwIfCommentIsNull(commentList);
return commentList.stream()
.map(comment -> CommentResponse.of(comment, userId)).collect(Collectors.toList());
}

private List<Comment> findByPostId(
final Long postId
) {
return commentRepository.findByPostId(postId);
}

private void throwIfCommentIsNull(
final List<Comment> commentList
) {
if (isCommentListNull(commentList)) {
throw new NotFoundException(ErrorMessage.COMMENTS_NOT_FOUND);
}
}

private boolean isCommentListNull(
final List<Comment> commentList
) {
return commentList.isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mile.comment.service.dto;

import com.mile.comment.domain.Comment;
import com.mile.writerName.domain.WriterName;

public record CommentResponse(
Long commentId,
String name,
String moimName,
String content,
boolean isMyComment
) {
private final static String ANONYMOUS = "작자미상";

public static CommentResponse of(
final Comment comment,
final Long userId
) {
WriterName writerName = comment.getWriterName();
return new CommentResponse(
comment.getId(),
ANONYMOUS + writerName.getId().toString(),
writerName.getMoim().getName(),
comment.getContent(),
writerName.getId().equals(userId)
);
}
}
Loading

0 comments on commit e5cc6e9

Please sign in to comment.