diff --git a/README.md b/README.md index c1f5044a..82be84ca 100644 --- a/README.md +++ b/README.md @@ -67,3 +67,5 @@ compiler(`⌘,` > `Build, Execution, Deployment` > `Compiler` > `Java Compiler` ### Deploy TODO with docker + + diff --git a/src/main/java/org/poolc/api/comment/controller/CommentController.java b/src/main/java/org/poolc/api/comment/controller/CommentController.java index 77f2370e..fa7baee3 100644 --- a/src/main/java/org/poolc/api/comment/controller/CommentController.java +++ b/src/main/java/org/poolc/api/comment/controller/CommentController.java @@ -25,24 +25,21 @@ @RequiredArgsConstructor @RequestMapping("/comment") public class CommentController { - private final PostService postService; private final CommentService commentService; private final LikeService likeService; @PostMapping - public ResponseEntity createComment(@AuthenticationPrincipal Member member, + public ResponseEntity createComment(@AuthenticationPrincipal Member member, @RequestBody @Valid CommentCreateRequest request) { - Post post = postService.findPostById(member, request.getPostId()); - CommentCreateValues values = new CommentCreateValues(post, member, request); - Comment newComment = commentService.createComment(values); - return ResponseEntity.status(HttpStatus.CREATED).body(CommentResponse.of(newComment)); + commentService.createComment(member, request); + return ResponseEntity.status(HttpStatus.CREATED).build(); } @PutMapping("/{commentId}") public ResponseEntity updateComment(@AuthenticationPrincipal Member member, @PathVariable Long commentId, @RequestBody CommentUpdateRequest request) { - commentService.updateComment(member, commentId, new CommentUpdateValues(request)); + commentService.updateComment(member, commentId, request); return ResponseEntity.status(HttpStatus.OK).build(); } @@ -54,9 +51,7 @@ public ResponseEntity deleteComment(@AuthenticationPrincipal Member member @PostMapping("/{commentId}/like") public ResponseEntity likeComment(@AuthenticationPrincipal Member member, @PathVariable Long commentId) { - Comment comment = commentService.findById(commentId); - if (!member.equals(comment.getMember())) likeService.like(member.getLoginID(), Subject.COMMENT, commentId); - else throw new IllegalArgumentException("본인의 댓글은 좋아할 수 없습니다."); + likeService.like(member, Subject.COMMENT, commentId); return ResponseEntity.status(HttpStatus.OK).build(); } } diff --git a/src/main/java/org/poolc/api/comment/domain/Comment.java b/src/main/java/org/poolc/api/comment/domain/Comment.java index d20f582c..1b24be49 100644 --- a/src/main/java/org/poolc/api/comment/domain/Comment.java +++ b/src/main/java/org/poolc/api/comment/domain/Comment.java @@ -78,11 +78,7 @@ public Comment(Comment parent, CommentCreateValues values) { this.body = values.getBody(); this.isDeleted = false; this.parent = parent; - if (parent != null) { - this.isChild = true; - } else { - this.isChild = false; - } + this.isChild = parent != null; this.children = new ArrayList<>(); this.likeCount = 0L; } diff --git a/src/main/java/org/poolc/api/comment/dto/CommentUpdateRequest.java b/src/main/java/org/poolc/api/comment/dto/CommentUpdateRequest.java index ee65794b..23093aba 100644 --- a/src/main/java/org/poolc/api/comment/dto/CommentUpdateRequest.java +++ b/src/main/java/org/poolc/api/comment/dto/CommentUpdateRequest.java @@ -4,8 +4,8 @@ @Getter public class CommentUpdateRequest { - private Boolean anonymous; - private String body; + private final Boolean anonymous; + private final String body; public CommentUpdateRequest(Boolean anonymous, String body) { this.anonymous = anonymous; diff --git a/src/main/java/org/poolc/api/comment/service/CommentService.java b/src/main/java/org/poolc/api/comment/service/CommentService.java index a5b6f8db..7af057ed 100644 --- a/src/main/java/org/poolc/api/comment/service/CommentService.java +++ b/src/main/java/org/poolc/api/comment/service/CommentService.java @@ -1,5 +1,10 @@ package org.poolc.api.comment.service; +import org.poolc.api.comment.dto.CommentCreateRequest; +import org.poolc.api.comment.dto.CommentResponse; +import org.poolc.api.comment.dto.CommentUpdateRequest; +import org.poolc.api.post.service.PostService; +import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import org.poolc.api.auth.exception.UnauthorizedException; import org.poolc.api.badge.service.BadgeConditionService; @@ -24,38 +29,41 @@ public class CommentService { //좋아요 수에 따라 뱃지 자동지급을 위함 private final BadgeConditionService badgeConditionService; private final NotificationService notificationService; - public Comment createComment(CommentCreateValues values) { - Comment parent = null; - if (values.getParentId() != null && values.getParentId() != 0) parent = findById(values.getParentId()); - if (parent != null && parent.getIsChild()) { - throw new IllegalArgumentException("대댓글에 대댓글을 달 수 없습니다."); - } else { - Comment comment = new Comment(parent, values); - commentRepository.save(comment); - comment.getPost().addCommentCount(); - if (parent == null) notificationService.createCommentNotification(values.getMember().getLoginID(), values.getPost().getMember().getLoginID(), values.getPost().getId()); - else notificationService.createRecommentNotification(values.getMember().getLoginID(), parent.getMember().getLoginID(), values.getPost().getId(), parent.getId()); - return comment; - } + private final PostService postService; + + @Transactional + public void createComment(Member member, CommentCreateRequest request) { + Post post = postService.findById(member, request.getPostId()); + CommentCreateValues values = new CommentCreateValues(post, member, request); + + Comment parent = findParentComment(values.getParentId()); + validateParentComment(parent); + + Comment comment = saveComment(values, parent); + sendNotifications(values, parent); } + @Transactional(readOnly = true) public List findCommentsByPost(Post post) { return commentRepository.findAllByPost(post).stream() .sorted(Comparator.comparing(Comment::getCreatedAt)) .collect(Collectors.toList()); } + @Transactional(readOnly = true) public List findCommentsByParent(Long parentId) { Comment parent = commentRepository.findById(parentId) .orElseThrow(() -> new NoSuchElementException("No comment found with given comment id.")); return commentRepository.findAllByParent(parent); } + @Transactional(readOnly = true) public Comment findById(Long commentId) { return commentRepository.findById(commentId) .orElseThrow(() -> new NoSuchElementException("No comment found with given comment id.")); } + @Transactional public void deleteComment(Member member, Long commentId) { Comment comment = findById(commentId); checkWriterOrAdmin(member, comment); @@ -63,12 +71,14 @@ public void deleteComment(Member member, Long commentId) { comment.getPost().deductCommentCount(); } - public void updateComment(Member member, Long commentId, CommentUpdateValues commentUpdateValues) { + @Transactional + public void updateComment(Member member, Long commentId, CommentUpdateRequest request) { Comment comment = findById(commentId); checkWriter(member, comment); - comment.updateComment(commentUpdateValues); + comment.updateComment(new CommentUpdateValues(request)); } + @Transactional public void likeComment(Member member, Long commentId) { Comment comment = findById(commentId); checkNotWriter(member, comment); @@ -78,6 +88,7 @@ public void likeComment(Member member, Long commentId) { } } + @Transactional public void dislikeComment(Member member, Long commentId) { Comment comment = findById(commentId); checkNotWriter(member, comment); @@ -87,6 +98,39 @@ public void dislikeComment(Member member, Long commentId) { } } + // TODO + private Comment findParentComment(Long parentId) { + if (parentId != null && parentId != 0) { + return findById(parentId); + } + return null; + } + + private void validateParentComment(Comment parent) { + if (parent != null && parent.getIsChild()) { + throw new IllegalArgumentException("대댓글에 대댓글을 달 수 없습니다."); + } + } + + private Comment saveComment(CommentCreateValues values, Comment parent) { + Comment comment = new Comment(parent, values); + commentRepository.save(comment); + comment.getPost().addCommentCount(); + return comment; + } + + private void sendNotifications(CommentCreateValues values, Comment parent) { + String commenterID = values.getMember().getLoginID(); + String postWriterID = values.getPost().getMember().getLoginID(); + + if (parent == null && !commenterID.equals(postWriterID)) { + notificationService.createCommentNotification(commenterID, postWriterID, values.getPost().getId()); + } else if (parent != null && !parent.getMember().equals(values.getMember())) { + String parentCommenterID = parent.getMember().getLoginID(); + notificationService.createRecommentNotification(commenterID, parentCommenterID, values.getPost().getId(), parent.getId()); + } + } + private void checkWriterOrAdmin(Member member, Comment comment) { if (!comment.getMember().equals(member) && !member.isAdmin()) throw new UnauthorizedException("접근할 수 없습니다."); } diff --git a/src/main/java/org/poolc/api/comment/vo/CommentCreateValues.java b/src/main/java/org/poolc/api/comment/vo/CommentCreateValues.java index 063d9dc0..751d5016 100644 --- a/src/main/java/org/poolc/api/comment/vo/CommentCreateValues.java +++ b/src/main/java/org/poolc/api/comment/vo/CommentCreateValues.java @@ -1,7 +1,6 @@ package org.poolc.api.comment.vo; import lombok.Getter; -import org.poolc.api.comment.domain.Comment; import org.poolc.api.comment.dto.CommentCreateRequest; import org.poolc.api.member.domain.Member; import org.poolc.api.post.domain.Post; @@ -21,4 +20,4 @@ public CommentCreateValues(Post post, Member member, CommentCreateRequest reques this.body = request.getBody(); this.parentId = request.getParentId(); } -} +} \ No newline at end of file diff --git a/src/main/java/org/poolc/api/comment/vo/CommentUpdateValues.java b/src/main/java/org/poolc/api/comment/vo/CommentUpdateValues.java index 81c65df6..dafd8d93 100644 --- a/src/main/java/org/poolc/api/comment/vo/CommentUpdateValues.java +++ b/src/main/java/org/poolc/api/comment/vo/CommentUpdateValues.java @@ -12,4 +12,4 @@ public CommentUpdateValues(CommentUpdateRequest commentUpdateRequest) { this.anonymous = commentUpdateRequest.getAnonymous(); this.body = commentUpdateRequest.getBody(); } -} +} \ No newline at end of file diff --git a/src/main/java/org/poolc/api/conversation/controller/ConversationController.java b/src/main/java/org/poolc/api/conversation/controller/ConversationController.java index c67d1c45..ec47fbc4 100644 --- a/src/main/java/org/poolc/api/conversation/controller/ConversationController.java +++ b/src/main/java/org/poolc/api/conversation/controller/ConversationController.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import org.poolc.api.conversation.domain.Conversation; import org.poolc.api.conversation.dto.ConversationCreateRequest; +import org.poolc.api.conversation.dto.ConversationResponse; import org.poolc.api.conversation.service.ConversationService; import org.poolc.api.member.domain.Member; import org.poolc.api.message.dto.MessageResponse; @@ -23,14 +24,18 @@ public class ConversationController { private final ConversationService conversationService; private final MessageService messageService; + // get all conversations + @GetMapping("/all") + public ResponseEntity> getAllConversations(@AuthenticationPrincipal Member member) { + return ResponseEntity.status(HttpStatus.OK).body(conversationService.findAllConversationsForLoginID(member.getLoginID())); + } + // create conversation @PostMapping("/new") - public ResponseEntity createConversation(@AuthenticationPrincipal Member member, + public ResponseEntity createConversation(@AuthenticationPrincipal Member member, @RequestBody ConversationCreateRequest request) { - String conversationId = conversationService.createConversation( - conversationService.convertToConversationCreateValues(request) - ); - return ResponseEntity.status(HttpStatus.CREATED).body(conversationId); + ConversationResponse response = conversationService.createConversation(member.getLoginID(), request); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } // get conversation @@ -38,31 +43,14 @@ public ResponseEntity createConversation(@AuthenticationPrincipal Member public ResponseEntity> viewConversation(@AuthenticationPrincipal Member member, @PathVariable String conversationId) { - Conversation conversation = conversationService.findConversationById(conversationId, member.getLoginID()); - List responses= messageService.findMessagesByConversationId(member, conversationId) - .stream() - .map(MessageResponse::of) - .collect(Collectors.toList()); - return ResponseEntity.status(HttpStatus.OK).body(responses); + return ResponseEntity.status(HttpStatus.OK).body(messageService.findMessageResponsesByConversationId(member, conversationId)); } // delete conversation @DeleteMapping("/{conversationId}") public ResponseEntity deleteConversation(@AuthenticationPrincipal Member member, @PathVariable String conversationId) { - conversationService.deleteConversation(conversationId, member.getLoginID()); - - messageService.findMessagesByConversationId(member, conversationId) - .stream() - .map(message -> { - if (message.getConversation().getStarterLoginID().equals(member.getLoginID())) { - messageService.deleteMessageByStarter(member, message.getId()); - } else { - messageService.deleteMessageByOther(member, message.getId()); - } - return null; - }); - + conversationService.deleteConversation(member.getLoginID(), conversationId); return ResponseEntity.status(HttpStatus.OK).build(); } } diff --git a/src/main/java/org/poolc/api/conversation/domain/Conversation.java b/src/main/java/org/poolc/api/conversation/domain/Conversation.java index f508874c..1a113d0a 100644 --- a/src/main/java/org/poolc/api/conversation/domain/Conversation.java +++ b/src/main/java/org/poolc/api/conversation/domain/Conversation.java @@ -1,20 +1,22 @@ package org.poolc.api.conversation.domain; import lombok.Getter; +import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import org.poolc.api.common.domain.TimestampEntity; import org.poolc.api.conversation.vo.ConversationCreateValues; import javax.persistence.*; +import org.poolc.api.message.domain.Message; @Entity @Getter -@Table(name = "conversations") +@Table(name = "conversation") public class Conversation extends TimestampEntity { @Id @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") - @Column(name = "conversation_id", columnDefinition = "CHAR(32)") + @Column(name = "id", columnDefinition = "CHAR(32)") private String id; @Column(name = "starter_login_id", nullable = false) @@ -23,12 +25,6 @@ public class Conversation extends TimestampEntity { @Column(name = "other_login_id", nullable = false) private String otherLoginID; - @Column(name = "starter_name", nullable = false) - private String starterName; - - @Column(name = "other_name", nullable = false) - private String otherName; - @Column(name = "starter_anonymous", nullable = false) private boolean starterAnonymous; @@ -41,13 +37,15 @@ public class Conversation extends TimestampEntity { @Column(name = "other_deleted") private boolean otherDeleted = false; + @Setter + @OneToOne + private Message lastMessage; + protected Conversation() {} - public Conversation(String starterLoginID, String otherLoginID, String starterName, String otherName, boolean starterAnonymous, boolean otherAnonymous) { + public Conversation(String starterLoginID, String otherLoginID, boolean starterAnonymous, boolean otherAnonymous) { this.starterLoginID = starterLoginID; this.otherLoginID = otherLoginID; - this.starterName = starterName; - this.otherName = otherName; this.starterAnonymous = starterAnonymous; this.otherAnonymous = otherAnonymous; } @@ -55,17 +53,16 @@ public Conversation(String starterLoginID, String otherLoginID, String starterNa public Conversation(ConversationCreateValues values) { this.starterLoginID = values.getStarterLoginID(); this.otherLoginID = values.getOtherLoginID(); - this.starterName = values.getStarterName(); - this.otherName = values.getOtherName(); this.starterAnonymous = values.isStarterAnonymous(); this.otherAnonymous = values.isOtherAnonymous(); } - public void setSenderDeleted() { + public void setStarterDeleted() { this.starterDeleted = true; } public void setReceiverDeleted() { this.otherDeleted = true; } + } diff --git a/src/main/java/org/poolc/api/conversation/dto/ConversationCreateRequest.java b/src/main/java/org/poolc/api/conversation/dto/ConversationCreateRequest.java index f3d7ebcd..64f39920 100644 --- a/src/main/java/org/poolc/api/conversation/dto/ConversationCreateRequest.java +++ b/src/main/java/org/poolc/api/conversation/dto/ConversationCreateRequest.java @@ -6,14 +6,12 @@ @Getter @Builder public class ConversationCreateRequest { - private String starterLoginID; private String otherLoginID; private boolean starterAnonymous; private boolean otherAnonymous; protected ConversationCreateRequest() {} - public ConversationCreateRequest(String starterLoginID, String otherLoginID, boolean starterAnonymous, boolean otherAnonymous) { - this.starterLoginID = starterLoginID; + public ConversationCreateRequest(String otherLoginID, boolean starterAnonymous, boolean otherAnonymous) { this.otherLoginID = otherLoginID; this.starterAnonymous = starterAnonymous; this.otherAnonymous = otherAnonymous; diff --git a/src/main/java/org/poolc/api/conversation/dto/ConversationResponse.java b/src/main/java/org/poolc/api/conversation/dto/ConversationResponse.java index 56be925d..49905a9b 100644 --- a/src/main/java/org/poolc/api/conversation/dto/ConversationResponse.java +++ b/src/main/java/org/poolc/api/conversation/dto/ConversationResponse.java @@ -4,29 +4,28 @@ import lombok.Getter; import lombok.Setter; import org.poolc.api.conversation.domain.Conversation; +import org.poolc.api.message.dto.MessageResponse; @Getter @Setter(AccessLevel.PRIVATE) public class ConversationResponse { private String id; - private String senderNameOrAnonymous; - private String receiverNameOrAnonymous; + private String starterLoginID; + private String otherLoginID; + private boolean starterAnonymous; + private boolean otherAnonymous; + private MessageResponse lastMessage; protected ConversationResponse() {} public static ConversationResponse of(Conversation conversation) { ConversationResponse response = new ConversationResponse(); response.setId(conversation.getId()); - if (conversation.isStarterAnonymous()) { - response.setSenderNameOrAnonymous("익명"); - } else { - response.setSenderNameOrAnonymous(conversation.getStarterName()); - } - if (conversation.isOtherAnonymous()) { - response.setReceiverNameOrAnonymous("익명"); - } else { - response.setReceiverNameOrAnonymous(conversation.getOtherName()); - } + response.setStarterLoginID(conversation.getStarterLoginID()); + response.setOtherLoginID(conversation.getOtherLoginID()); + response.setStarterAnonymous(conversation.isStarterAnonymous()); + response.setOtherAnonymous(conversation.isOtherAnonymous()); + if (conversation.getLastMessage() != null) response.setLastMessage(MessageResponse.of(conversation.getLastMessage())); return response; } } diff --git a/src/main/java/org/poolc/api/conversation/repository/ConversationRepository.java b/src/main/java/org/poolc/api/conversation/repository/ConversationRepository.java index 505d7167..52603133 100644 --- a/src/main/java/org/poolc/api/conversation/repository/ConversationRepository.java +++ b/src/main/java/org/poolc/api/conversation/repository/ConversationRepository.java @@ -1,5 +1,6 @@ package org.poolc.api.conversation.repository; +import java.util.List; import org.poolc.api.conversation.domain.Conversation; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -8,6 +9,7 @@ @Repository public interface ConversationRepository extends JpaRepository { - Optional findByStarterLoginIDAndOtherLoginID(String starterLoginID, String otherLoginID); + Optional findByStarterLoginIDAndOtherLoginIDAndStarterAnonymousFalseAndOtherAnonymousFalse(String starterLoginID, String otherLoginID); Optional findById(String id); + List findAllByStarterLoginIDOrOtherLoginID(String loginID1, String loginID2); } diff --git a/src/main/java/org/poolc/api/conversation/service/ConversationService.java b/src/main/java/org/poolc/api/conversation/service/ConversationService.java index ef8f6af8..15c93efd 100644 --- a/src/main/java/org/poolc/api/conversation/service/ConversationService.java +++ b/src/main/java/org/poolc/api/conversation/service/ConversationService.java @@ -1,8 +1,12 @@ package org.poolc.api.conversation.service; +import java.util.List; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.poolc.api.comment.dto.CommentResponse; import org.poolc.api.conversation.domain.Conversation; import org.poolc.api.conversation.dto.ConversationCreateRequest; +import org.poolc.api.conversation.dto.ConversationResponse; import org.poolc.api.conversation.repository.ConversationRepository; import org.poolc.api.conversation.vo.ConversationCreateValues; import org.poolc.api.member.service.MemberService; @@ -10,6 +14,7 @@ import java.util.NoSuchElementException; import java.util.Optional; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -17,41 +22,40 @@ public class ConversationService { private final ConversationRepository conversationRepository; private final MemberService memberService; - public String createConversation(ConversationCreateValues values) { - checkValidParties(values.getStarterLoginID(), values.getOtherLoginID()); - String conversationId = checkExistingConversation(values.getStarterLoginID(), values.getOtherLoginID()); - if (conversationId != null) return conversationId; - else conversationRepository.save(new Conversation(values)); - Conversation conversation = findConversationByStarterAndOther(values.getStarterLoginID(), values.getOtherLoginID()); - return conversation.getId(); + @Transactional + public ConversationResponse createConversation(String starterLoginID, ConversationCreateRequest request) { + checkValidParties(starterLoginID, request.getOtherLoginID()); + String conversationId = null; + if (!request.isStarterAnonymous() && !request.isOtherAnonymous()) { + conversationId = checkExistingConversation(starterLoginID, request.getOtherLoginID()); + } + if (conversationId != null) { + return ConversationResponse.of(conversationRepository.findById(conversationId).get()); + } + Conversation conversation = new Conversation(new ConversationCreateValues(starterLoginID, request.getOtherLoginID(), request.isStarterAnonymous(), request.isOtherAnonymous())); + conversationRepository.save(conversation); + return ConversationResponse.of(conversation); } - public ConversationCreateValues convertToConversationCreateValues(ConversationCreateRequest request) { - String receiverName = checkValidParties(request.getStarterLoginID(), request.getOtherLoginID()); - String senderName = memberService.getMemberByLoginID(request.getOtherLoginID()).getName(); - return new ConversationCreateValues( - request.getStarterLoginID(), request.getOtherLoginID(), - senderName, receiverName, - request.isStarterAnonymous(), request.isOtherAnonymous() - ); + @Transactional(readOnly = true) + public ConversationResponse getConversationResponseById(String conversationId, String loginID) { + Conversation conversation = findConversationById(conversationId, loginID); + return ConversationResponse.of(conversation); } - public Conversation findConversationById(String conversationId, String loginID) { - Conversation conversation = conversationRepository.findById(conversationId) - .orElseThrow(() -> new NoSuchElementException("No conversation found with the given id.")); - checkWhetherInvolved(conversation, loginID); - return conversation; - } - public Conversation findConversationByStarterAndOther(String starterLoginID, String otherLoginID) { - return conversationRepository.findByStarterLoginIDAndOtherLoginID(starterLoginID, otherLoginID) - .orElseThrow(() -> new NoSuchElementException("No conversation found with the given parties.")); + @Transactional(readOnly = true) + public List findAllConversationsForLoginID(String loginID) { + return conversationRepository.findAllByStarterLoginIDOrOtherLoginID(loginID, loginID) + .stream().map(ConversationResponse::of) + .collect(Collectors.toList()); } + @Transactional public void deleteConversation(String conversationId, String loginID) { Conversation conversation = findConversationById(conversationId, loginID); checkWhetherInvolved(conversation, loginID); - boolean sender = findWhetherSenderOrReceiver(conversation, loginID); - if (sender) conversation.setSenderDeleted(); + boolean sender = findWhetherStarterOrOther(conversation, loginID); + if (sender) conversation.setStarterDeleted(); else conversation.setReceiverDeleted(); } @@ -60,11 +64,19 @@ public void checkWhetherInvolved(Conversation conversation, String loginID) { throw new IllegalArgumentException("You are not involved in this conversation."); } } - public boolean findWhetherSenderOrReceiver(Conversation conversation, String loginID) { + + public boolean findWhetherStarterOrOther(Conversation conversation, String loginID) { return conversation.getStarterLoginID().equals(loginID); } - private String checkValidParties(String starterLoginID, String otherLoginID) { + public Conversation findConversationById(String conversationId, String loginID) { + Conversation conversation = conversationRepository.findById(conversationId) + .orElseThrow(() -> new NoSuchElementException("No conversation found with the given id.")); + checkWhetherInvolved(conversation, loginID); + return conversation; + } + + private void checkValidParties(String starterLoginID, String otherLoginID) { if (starterLoginID.equals(otherLoginID)) { throw new IllegalArgumentException("Sender and receiver cannot be the same person."); } @@ -74,11 +86,11 @@ private String checkValidParties(String starterLoginID, String otherLoginID) { if (memberService.checkMemberExistsByLoginID(otherLoginID)) { throw new NoSuchElementException("Receiver is not found."); } - return memberService.getMemberByLoginID(otherLoginID).getName(); - } + } + // 두 사용자 모두 실명인 conversation이 존재하는지 확인 private String checkExistingConversation(String starterLoginID, String otherLoginID) { - Optional conversationOptional = conversationRepository.findByStarterLoginIDAndOtherLoginID(starterLoginID, otherLoginID); + Optional conversationOptional = conversationRepository.findByStarterLoginIDAndOtherLoginIDAndStarterAnonymousFalseAndOtherAnonymousFalse(starterLoginID, otherLoginID); if (conversationOptional.isPresent() && !conversationOptional.get().isStarterDeleted() && !conversationOptional.get().isStarterAnonymous() && diff --git a/src/main/java/org/poolc/api/conversation/vo/ConversationCreateValues.java b/src/main/java/org/poolc/api/conversation/vo/ConversationCreateValues.java index 4ea14701..ce06051c 100644 --- a/src/main/java/org/poolc/api/conversation/vo/ConversationCreateValues.java +++ b/src/main/java/org/poolc/api/conversation/vo/ConversationCreateValues.java @@ -6,18 +6,14 @@ public class ConversationCreateValues { private String starterLoginID; private String otherLoginID; - private String starterName; - private String otherName; private boolean starterAnonymous; private boolean otherAnonymous; protected ConversationCreateValues() {} - public ConversationCreateValues(String starterLoginID, String otherLoginID, String starterName, String otherName, boolean starterAnonymous, boolean otherAnonymous) { + public ConversationCreateValues(String starterLoginID, String otherLoginID, boolean starterAnonymous, boolean otherAnonymous) { this.starterLoginID = starterLoginID; this.otherLoginID = otherLoginID; - this.starterName = starterName; - this.otherName = otherName; this.starterAnonymous = starterAnonymous; this.otherAnonymous = otherAnonymous; } diff --git a/src/main/java/org/poolc/api/like/domain/Like.java b/src/main/java/org/poolc/api/like/domain/Like.java index 025483a5..793fb109 100644 --- a/src/main/java/org/poolc/api/like/domain/Like.java +++ b/src/main/java/org/poolc/api/like/domain/Like.java @@ -16,8 +16,8 @@ public class Like { @Column(name = "id") private Long id; - @Column(name = "member_id", nullable = false) - private String memberId; + @Column(name = "login_ID", nullable = false) + private String loginID; @Column(name = "subject", nullable = false) private Subject subject; @@ -27,8 +27,8 @@ public class Like { protected Like() {} - public Like(String memberId, Subject subject, Long subjectId) { - this.memberId = memberId; + public Like(String loginID, Subject subject, Long subjectId) { + this.loginID = loginID; this.subject = subject; this.subjectId = subjectId; } diff --git a/src/main/java/org/poolc/api/like/domain/Subject.java b/src/main/java/org/poolc/api/like/domain/Subject.java index 0eb7c56e..c4118b6f 100644 --- a/src/main/java/org/poolc/api/like/domain/Subject.java +++ b/src/main/java/org/poolc/api/like/domain/Subject.java @@ -2,5 +2,5 @@ public enum Subject { POST, - COMMENT; + COMMENT } diff --git a/src/main/java/org/poolc/api/like/repository/LikeRepository.java b/src/main/java/org/poolc/api/like/repository/LikeRepository.java index 06121f3b..d9331408 100644 --- a/src/main/java/org/poolc/api/like/repository/LikeRepository.java +++ b/src/main/java/org/poolc/api/like/repository/LikeRepository.java @@ -3,13 +3,12 @@ import org.poolc.api.like.domain.Like; import org.poolc.api.like.domain.Subject; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.Optional; @Repository public interface LikeRepository extends JpaRepository { - Optional findByMemberIdAndSubjectAndSubjectId(String memberId, Subject subject, Long subjectId); - boolean existsByMemberIdAndSubjectAndSubjectId(String memberId, Subject subject, Long subjectId); + Optional findByLoginIDAndSubjectAndSubjectId(String loginID, Subject subject, Long subjectId); + boolean existsByLoginIDAndSubjectAndSubjectId(String loginID, Subject subject, Long subjectId); } diff --git a/src/main/java/org/poolc/api/like/service/LikeService.java b/src/main/java/org/poolc/api/like/service/LikeService.java index 0772dc68..a987d7ed 100644 --- a/src/main/java/org/poolc/api/like/service/LikeService.java +++ b/src/main/java/org/poolc/api/like/service/LikeService.java @@ -12,8 +12,10 @@ import org.poolc.api.post.domain.Post; import org.poolc.api.post.service.PostService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.NoSuchElementException; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -21,24 +23,34 @@ public class LikeService { private final LikeRepository likeRepository; private final PostService postService; private final CommentService commentService; - private final MemberService memberService; - public void like(String memberId, Subject subject, Long subjectId) { - Member member = memberService.getMemberByLoginID(memberId); - if (checkIfLiked(memberId, subject, subjectId)) { - Long likeId = likeRepository.findByMemberIdAndSubjectAndSubjectId(memberId, subject, subjectId) - .get() - .getSubjectId(); + @Transactional + public void like(Member member, Subject subject, Long subjectId) { + if (checkIfSelf(member, subject, subjectId)) throw new IllegalArgumentException("자신의 글에는 좋아요를 누를 수 없습니다."); + if (checkIfLiked(member.getLoginID(), subject, subjectId)) { + // 이미 if condition으로 null 여부 확인 완료한 상태 + Long likeId = likeRepository.findByLoginIDAndSubjectAndSubjectId(member.getLoginID(), subject, subjectId).get().getId(); likeRepository.deleteById(likeId); deductLikeToSubject(member, subject, subjectId); } else { - likeRepository.save(new Like(memberId, subject, subjectId)); + likeRepository.save(new Like(member.getLoginID(), subject, subjectId)); addLikeToSubject(member, subject, subjectId); } } - private boolean checkIfLiked(String memberId, Subject subject, Long subjectId) { - return likeRepository.existsByMemberIdAndSubjectAndSubjectId(memberId, subject, subjectId); + private boolean checkIfSelf(Member member, Subject subject, Long subjectId) { + switch (subject) { + case COMMENT: + return commentService.findById(subjectId).getMember().equals(member); + case POST: + return postService.findById(member, subjectId).getMember().equals(member); + default: + return false; + } + } + + private boolean checkIfLiked(String loginID, Subject subject, Long subjectId) { + return likeRepository.existsByLoginIDAndSubjectAndSubjectId(loginID, subject, subjectId); } private void addLikeToSubject(Member member, Subject subject, Long subjectId) { diff --git a/src/main/java/org/poolc/api/member/domain/Member.java b/src/main/java/org/poolc/api/member/domain/Member.java index 9765d91b..dac0b099 100644 --- a/src/main/java/org/poolc/api/member/domain/Member.java +++ b/src/main/java/org/poolc/api/member/domain/Member.java @@ -72,9 +72,6 @@ public class Member extends TimestampEntity implements UserDetails { @JoinColumn(name = "badge_id") private Badge badge; - @Column(name = "notification_count", columnDefinition = "bigint default 0") - private Long notificationCount=0L; - protected Member() { } @@ -284,6 +281,4 @@ public void deleteBadge(){ this.badge = null; } - public void addNotification() { this.notificationCount ++; } - public void resetNotificationCount() {this.notificationCount = 0L;} } diff --git a/src/main/java/org/poolc/api/message/controller/MessageController.java b/src/main/java/org/poolc/api/message/controller/MessageController.java index a40a77d7..9803f14c 100644 --- a/src/main/java/org/poolc/api/message/controller/MessageController.java +++ b/src/main/java/org/poolc/api/message/controller/MessageController.java @@ -1,66 +1,42 @@ package org.poolc.api.message.controller; import lombok.RequiredArgsConstructor; -import org.poolc.api.conversation.domain.Conversation; -import org.poolc.api.conversation.service.ConversationService; import org.poolc.api.member.domain.Member; -import org.poolc.api.member.service.MemberService; -import org.poolc.api.message.domain.Message; import org.poolc.api.message.dto.MessageCreateRequest; import org.poolc.api.message.dto.MessageResponse; import org.poolc.api.message.service.MessageService; import org.poolc.api.message.vo.MessageCreateValues; -import org.poolc.api.notification.service.NotificationService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; -@Controller +@RestController @RequiredArgsConstructor -@RequestMapping("/conversation") +@RequestMapping("/message") public class MessageController { private final MessageService messageService; - private final MemberService memberService; - private final NotificationService notificationService; - private final ConversationService conversationService; - @PostMapping("/{conversationId}/send") - public ResponseEntity writeMessage(@AuthenticationPrincipal Member member, - @PathVariable String conversationId, + @PostMapping("/send") + public ResponseEntity sendMessage(@AuthenticationPrincipal Member member, @RequestBody @Valid MessageCreateRequest request) { - String senderId = request.getSenderId(); - String receiverId = request.getReceiverId(); - - Member receiver = memberService.getMemberByLoginID(receiverId); - messageService.write(member, receiverId, new MessageCreateValues(conversationId, request)); - - if (request.getSenderAnonymous()) senderId = "익명"; - if (request.getReceiverAnonymous()) receiverId = "익명"; - - notificationService.createMessageNotification(senderId, receiverId); + messageService.writeMessage(member, new MessageCreateValues(request)); return ResponseEntity.status(HttpStatus.CREATED).build(); } @GetMapping("/{messageId}") - public ResponseEntity viewMessage(@AuthenticationPrincipal Member member, + public ResponseEntity getMessage(@AuthenticationPrincipal Member member, @PathVariable Long messageId) { - Message message = messageService.findMessageById(member, messageId); - return ResponseEntity.status(HttpStatus.OK).body(MessageResponse.of(message)); + MessageResponse response = messageService.getMessageResponseById(member, messageId); + return ResponseEntity.status(HttpStatus.OK).body(response); } @DeleteMapping("/{messageId}") public ResponseEntity deleteMessage(@AuthenticationPrincipal Member member, @PathVariable Long messageId) { - Message message = messageService.findMessageById(member, messageId); - Conversation conversation = conversationService.findConversationById(message.getConversation().getId(), member.getLoginID()); - if (conversation.getStarterLoginID().equals(member.getLoginID())) { - messageService.deleteMessageByStarter(member, messageId); - } - else messageService.deleteMessageByOther(member, messageId); + messageService.deleteMessage(member, messageId); return ResponseEntity.status(HttpStatus.OK).build(); } } diff --git a/src/main/java/org/poolc/api/message/domain/Message.java b/src/main/java/org/poolc/api/message/domain/Message.java index b64dd4c5..0c389a9f 100644 --- a/src/main/java/org/poolc/api/message/domain/Message.java +++ b/src/main/java/org/poolc/api/message/domain/Message.java @@ -25,20 +25,20 @@ public class Message extends TimestampEntity { @Column(name = "content", nullable = false) private String content; - @Column(name = "starter_is_sender") - private boolean starterIsSender; + @Column(name = "sent_by_starter", nullable = false) + private Boolean sentByStarter; - @Column(name = "deleted_by_sender", nullable = false, columnDefinition = "boolean default false") + @Column(name = "deleted_by_starter", nullable = false, columnDefinition = "boolean default false") private Boolean deletedByStarter; @Column(name = "deleted_by_other", nullable = false, columnDefinition = "boolean default false") private Boolean deletedByOther; @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "conversation", referencedColumnName = "conversation_id") + @JoinColumn(name = "conversation", referencedColumnName = "id", nullable = false) private Conversation conversation; - @Column(name = "starter_anonymous", nullable = false) + /*@Column(name = "starter_anonymous", nullable = false) private Boolean starterAnonymous; @Column(name = "other_anonymous", nullable = false) @@ -49,20 +49,18 @@ public class Message extends TimestampEntity { @Column(name = "other_name") private String otherName; - +*/ protected Message() {} - public Message(String content, boolean starterIsSender, Conversation conversation, Boolean starterAnonymous, Boolean otherAnonymous, String starterName, String otherName) { + public Message(Member member, String content, Conversation conversation, Boolean sentByStarter) { this.content = content; - this.starterIsSender = starterIsSender; this.conversation = conversation; - this.starterAnonymous = starterAnonymous; - this.otherAnonymous = otherAnonymous; - this.starterName = starterName; - this.otherName = otherName; + this.sentByStarter = sentByStarter; + this.deletedByStarter = false; + this.deletedByOther = false; } - public void starterDeletes() { + public void senderDeletes() { this.deletedByStarter = true; } @@ -74,5 +72,4 @@ public boolean isDeleted() { return this.deletedByStarter && this.deletedByOther; } - } diff --git a/src/main/java/org/poolc/api/message/dto/MessageCreateRequest.java b/src/main/java/org/poolc/api/message/dto/MessageCreateRequest.java index 3e1d3ed3..1bb9b00a 100644 --- a/src/main/java/org/poolc/api/message/dto/MessageCreateRequest.java +++ b/src/main/java/org/poolc/api/message/dto/MessageCreateRequest.java @@ -6,17 +6,11 @@ @Getter public class MessageCreateRequest { private final String content; - private final String senderId; - private final String receiverId; - private final Boolean senderAnonymous; - private final Boolean receiverAnonymous; + private final String conversationId; @JsonCreator - public MessageCreateRequest(String content, String senderId, String receiverId, Boolean senderAnonymous, Boolean receiverAnonymous) { + public MessageCreateRequest(String content, String conversationId) { this.content = content; - this.senderId = senderId; - this.receiverId = receiverId; - this.senderAnonymous = senderAnonymous; - this.receiverAnonymous = receiverAnonymous; + this.conversationId = conversationId; } } diff --git a/src/main/java/org/poolc/api/message/dto/MessageResponse.java b/src/main/java/org/poolc/api/message/dto/MessageResponse.java index f54a4dee..2957344e 100644 --- a/src/main/java/org/poolc/api/message/dto/MessageResponse.java +++ b/src/main/java/org/poolc/api/message/dto/MessageResponse.java @@ -11,17 +11,14 @@ @Setter(AccessLevel.PRIVATE) public class MessageResponse { private String content; - private String receiverName; + private boolean sentByStarter; private LocalDateTime sentAt; public static MessageResponse of(Message message) { MessageResponse response = new MessageResponse(); response.setContent(message.getContent()); response.setSentAt(message.getCreatedAt()); - - if (message.getOtherAnonymous()) response.setReceiverName("익명"); - else response.setReceiverName(message.getOtherName()); - + response.setSentByStarter(message.getSentByStarter()); return response; } } diff --git a/src/main/java/org/poolc/api/message/repository/MessageRepository.java b/src/main/java/org/poolc/api/message/repository/MessageRepository.java index 5447ed15..efc42d27 100644 --- a/src/main/java/org/poolc/api/message/repository/MessageRepository.java +++ b/src/main/java/org/poolc/api/message/repository/MessageRepository.java @@ -2,15 +2,12 @@ import org.poolc.api.message.domain.Message; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface MessageRepository extends JpaRepository { - List findAllByConversationId(String conversationId); - @Query("select m from Message m where m.conversation.id=(:id)") - List findAllByConversationID(@Param("id") String conversationID); + + List findAllByConversationId(String conversationID); } diff --git a/src/main/java/org/poolc/api/message/service/MessageService.java b/src/main/java/org/poolc/api/message/service/MessageService.java index d1c12d19..193421c0 100644 --- a/src/main/java/org/poolc/api/message/service/MessageService.java +++ b/src/main/java/org/poolc/api/message/service/MessageService.java @@ -4,10 +4,11 @@ import org.poolc.api.conversation.domain.Conversation; import org.poolc.api.conversation.service.ConversationService; import org.poolc.api.member.domain.Member; -import org.poolc.api.member.service.MemberService; import org.poolc.api.message.domain.Message; +import org.poolc.api.message.dto.MessageResponse; import org.poolc.api.message.repository.MessageRepository; import org.poolc.api.message.vo.MessageCreateValues; +import org.poolc.api.notification.service.NotificationService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,61 +20,77 @@ @Service @RequiredArgsConstructor public class MessageService { + + private static final String MESSAGE_NOT_FOUND = "No message found with given id."; + private final MessageRepository messageRepository; private final ConversationService conversationService; - private final MemberService memberService; + private final NotificationService notificationService; - public Message findMessageById(Member member, Long messageId) { - Message message = messageRepository.findById(messageId) - .orElseThrow(() -> new NoSuchElementException("No message found with given id.")); - if (message.isDeleted()) throw new NoSuchElementException("No message found with given id."); - conversationService.checkWhetherInvolved(message.getConversation(), member.getLoginID()); - return message; + @Transactional(readOnly = true) + public MessageResponse getMessageResponseById(Member member, Long messageId) { + Message message = findMessageById(member, messageId); + return MessageResponse.of(message); } - public List findMessagesByConversationId(Member member, String conversationId) { - List messageList = messageRepository.findAllByConversationId(conversationId); + @Transactional(readOnly = true) + public List findMessageResponsesByConversationId(Member member, String conversationId) { Conversation conversation = conversationService.findConversationById(conversationId, member.getLoginID()); + List messageList = messageRepository.findAllByConversationId(conversationId); conversationService.checkWhetherInvolved(conversation, member.getLoginID()); return messageList.stream() .filter(message -> !message.isDeleted()) - .sorted(Comparator.comparing(Message::getCreatedAt).reversed()) + .sorted(Comparator.comparing(Message::getCreatedAt)) + .map(MessageResponse::of) .collect(Collectors.toList()); } @Transactional - public Message write(Member member, String receiverLoginID, MessageCreateValues values) { - String senderName = member.getName(); - String receiverName = memberService.getMemberByLoginID(receiverLoginID).getName(); - String starterId = conversationService.findConversationById(values.getConversationId(), member.getLoginID()) - .getStarterLoginID(); - Conversation conversation = conversationService.findConversationById(values.getConversationId(), member.getLoginID()); - boolean starterIsSender = member.getLoginID().equals(starterId); - Message message = new Message( - values.getContent(), - starterIsSender, - conversation, - values.getSenderAnonymous(), - values.getReceiverAnonymous(), - senderName, - receiverName - ); + public void writeMessage(Member sender, MessageCreateValues values) { + Conversation conversation = conversationService.findConversationById(values.getConversationId(), sender.getLoginID()); + boolean sentByStarter = conversation.getStarterLoginID().equals(sender.getLoginID()); + + Message message = new Message(sender, values.getContent(), conversation, sentByStarter); messageRepository.save(message); - return message; + conversation.setLastMessage(message); + + String receiverID = conversation.getStarterLoginID().equals(sender.getLoginID()) ? conversation.getOtherLoginID() : conversation.getStarterLoginID(); + String senderID = null; + if (sentByStarter && !conversation.isStarterAnonymous()) { + senderID = conversation.getStarterLoginID(); + } + if (!sentByStarter && !conversation.isOtherAnonymous()) { + senderID = conversation.getOtherLoginID(); + } + + notificationService.createMessageNotification(senderID, receiverID, message.getId()); } - public void deleteMessageByStarter(Member member, Long messageId) { + + @Transactional + public void deleteMessage(Member member, Long messageId) { Message message = findMessageById(member, messageId); conversationService.checkWhetherInvolved(message.getConversation(), member.getLoginID()); - conversationService.findWhetherSenderOrReceiver(message.getConversation(), member.getLoginID()); - message.starterDeletes(); + conversationService.findWhetherStarterOrOther(message.getConversation(), member.getLoginID()); + + boolean deletedByStarter = message.getConversation().getStarterLoginID().equals(member.getLoginID()); + if (deletedByStarter) { + message.senderDeletes(); + } else { + message.otherDeletes(); + } } - public void deleteMessageByOther(Member member, Long messageId) { - Message message = findMessageById(member, messageId); + private Message findMessageById(Member member, Long messageId) { + Message message = messageRepository.findById(messageId) + .orElseThrow(() -> new NoSuchElementException(MESSAGE_NOT_FOUND)); + Conversation conversation = message.getConversation(); + boolean isStarter = conversation.getStarterLoginID().equals(member.getLoginID()); + if (message.isDeleted() || (isStarter && message.getDeletedByStarter()) || !isStarter && message.getDeletedByOther()) { + throw new NoSuchElementException(MESSAGE_NOT_FOUND); + } conversationService.checkWhetherInvolved(message.getConversation(), member.getLoginID()); - conversationService.findWhetherSenderOrReceiver(message.getConversation(), member.getLoginID()); - message.otherDeletes(); + return message; } } diff --git a/src/main/java/org/poolc/api/message/vo/MessageCreateValues.java b/src/main/java/org/poolc/api/message/vo/MessageCreateValues.java index 9829a383..ea3746f0 100644 --- a/src/main/java/org/poolc/api/message/vo/MessageCreateValues.java +++ b/src/main/java/org/poolc/api/message/vo/MessageCreateValues.java @@ -7,14 +7,10 @@ public class MessageCreateValues { private final String content; private final String conversationId; - private final Boolean senderAnonymous; - private final Boolean receiverAnonymous; - public MessageCreateValues(String conversationId, MessageCreateRequest request) { + public MessageCreateValues(MessageCreateRequest request) { this.content = request.getContent(); - this.conversationId = conversationId; - this.senderAnonymous = request.getSenderAnonymous(); - this.receiverAnonymous = request.getReceiverAnonymous(); + this.conversationId = request.getConversationId(); } } diff --git a/src/main/java/org/poolc/api/notification/controller/NotificationController.java b/src/main/java/org/poolc/api/notification/controller/NotificationController.java index be2f393e..cb3f0f9b 100644 --- a/src/main/java/org/poolc/api/notification/controller/NotificationController.java +++ b/src/main/java/org/poolc/api/notification/controller/NotificationController.java @@ -4,12 +4,15 @@ import org.poolc.api.member.domain.Member; import org.poolc.api.notification.domain.Notification; import org.poolc.api.notification.dto.NotificationResponse; +import org.poolc.api.notification.dto.NotificationSummaryResponse; import org.poolc.api.notification.service.NotificationService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; 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 java.util.List; @@ -21,21 +24,23 @@ public class NotificationController { private final NotificationService notificationService; + @PostMapping("/{notificationId}") + public ResponseEntity viewNotification(@AuthenticationPrincipal Member member, @PathVariable("notificationId") Long notificationId) { + NotificationResponse response = notificationService.readNotification(member, notificationId); + return ResponseEntity.status(HttpStatus.OK).body(response); + } + @GetMapping("/unread") - public ResponseEntity> getUnreadNotifications(@AuthenticationPrincipal Member member) { - List notifications = notificationService.getUnreadNotificationsForMember(member.getLoginID()); - List responses = notifications.stream() - .map(NotificationResponse::of) - .collect(Collectors.toList()); - return ResponseEntity.status(HttpStatus.OK).body(responses); + public ResponseEntity getUnreadNotifications(@AuthenticationPrincipal Member member) { + NotificationSummaryResponse summaryResponse = notificationService.getUnreadNotificationsForMember(member); + return ResponseEntity.status(HttpStatus.OK).body(summaryResponse); } + @GetMapping("/all") - public ResponseEntity> getAllNotifications(@AuthenticationPrincipal Member member) { - List notifications = notificationService.getAllNotificationsForMember(member.getLoginID()); - List responses = notifications.stream() - .map(NotificationResponse::of) - .collect(Collectors.toList()); - return ResponseEntity.status(HttpStatus.OK).body(responses); + public ResponseEntity getAllNotifications(@AuthenticationPrincipal Member member) { + NotificationSummaryResponse summaryResponse = notificationService.getAllNotificationsForMember(member); + return ResponseEntity.status(HttpStatus.OK).body(summaryResponse); } + } diff --git a/src/main/java/org/poolc/api/notification/domain/Notification.java b/src/main/java/org/poolc/api/notification/domain/Notification.java index eb06c990..ff9de870 100644 --- a/src/main/java/org/poolc/api/notification/domain/Notification.java +++ b/src/main/java/org/poolc/api/notification/domain/Notification.java @@ -17,20 +17,14 @@ public class Notification extends TimestampEntity { @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "NOTIFICATION_SEQ_GENERATOR") private Long id; - @Column(name = "sender_id", nullable = true) + @Column(name = "sender_id") private String senderId; @Column(name = "receiver_id", nullable = false) private String receiverId; - @Column(name = "sender_name") - private String senderName; - - @Column(name = "post_id") - private Long postId; - - @Column(name = "parent_comment_id") - private Long parentCommentId; + @Column(name = "caused_by_id") + private Long causedById; @Column(name = "notification_type", nullable = false) private NotificationType notificationType; @@ -40,30 +34,22 @@ public class Notification extends TimestampEntity { protected Notification() {} - // 쪽지 알림 - public Notification(String senderId, String receiverId, String senderName, NotificationType notificationType) { - this.senderId = senderId; - this.receiverId = receiverId; - this.senderName = senderName; - this.notificationType = notificationType; - } - - // 뱃지 알림 + // 뱃지 알림 or 익명 쪽지 알림 public Notification(String receiverId, NotificationType notificationType) { this.receiverId = receiverId; this.notificationType = notificationType; } // 댓글 알림 - public Notification(String senderId, String receiverId, String senderName, Long postId, NotificationType notificationType) { + public Notification(String senderId, String receiverId, Long postId, NotificationType notificationType) { this.senderId = senderId; this.receiverId = receiverId; - this.senderName = senderName; - this.postId = postId; + this.causedById = postId; this.notificationType = notificationType; } // 대댓글 알림 + /* public Notification(String senderId, String receiverId, String senderName, Long postId, Long parentCommentId, NotificationType notificationType) { this.senderId = senderId; this.receiverId = receiverId; @@ -72,6 +58,7 @@ public Notification(String senderId, String receiverId, String senderName, Long this.parentCommentId = parentCommentId; this.notificationType = notificationType; } + */ public boolean isRead() { return this.readStatus; } diff --git a/src/main/java/org/poolc/api/notification/domain/NotificationType.java b/src/main/java/org/poolc/api/notification/domain/NotificationType.java index 6549c535..318418c5 100644 --- a/src/main/java/org/poolc/api/notification/domain/NotificationType.java +++ b/src/main/java/org/poolc/api/notification/domain/NotificationType.java @@ -1,16 +1,8 @@ package org.poolc.api.notification.domain; public enum NotificationType { - MESSAGE("님이 쪽지를 보냈습니다."), - BADGE("새 뱃지를 받았습니다!"), - COMMENT("님이 댓글을 달았습니다."), - RECOMMENT("님이 대댓글을 달았습니다."); - - private final String description; - - private NotificationType(String description) { - this.description = description; - } - - public String getDescription() { return this.description; } + MESSAGE, + BADGE, + COMMENT, + POST; } diff --git a/src/main/java/org/poolc/api/notification/dto/NotificationResponse.java b/src/main/java/org/poolc/api/notification/dto/NotificationResponse.java index a73a2b52..7cdf4281 100644 --- a/src/main/java/org/poolc/api/notification/dto/NotificationResponse.java +++ b/src/main/java/org/poolc/api/notification/dto/NotificationResponse.java @@ -11,34 +11,21 @@ @Getter @Setter(AccessLevel.PRIVATE) public class NotificationResponse { - private String receiverId; + private Long notificationId; private Boolean readStatus; - private String notificationType; + private NotificationType notificationType; private LocalDateTime createdAt; - - private String senderName; - private String senderId; - // 댓글 알림이면 포스트로 링크 - private Long postId; - - // 대댓글이면 해당 댓글 주인에게 알림 보내기 위해 - private Long parentCommentId; + private Long causedById; public static NotificationResponse of(Notification notification) { NotificationResponse response = new NotificationResponse(); - response.setNotificationType(notification.getNotificationType().getDescription()); + response.setNotificationId(notification.getId()); + response.setNotificationType(notification.getNotificationType()); response.setReadStatus(notification.getReadStatus()); response.setCreatedAt(notification.getCreatedAt()); - response.setReceiverId(notification.getReceiverId()); if (notification.getNotificationType() != NotificationType.BADGE) { - response.setSenderId(notification.getSenderId()); - response.setSenderName(notification.getSenderName()); - if (notification.getNotificationType() == NotificationType.COMMENT) { - response.setPostId(notification.getPostId()); - } else if (notification.getNotificationType() == NotificationType.RECOMMENT) { - response.setParentCommentId(notification.getParentCommentId()); - } + response.setCausedById(notification.getCausedById()); } return response; diff --git a/src/main/java/org/poolc/api/notification/dto/NotificationSummaryResponse.java b/src/main/java/org/poolc/api/notification/dto/NotificationSummaryResponse.java new file mode 100644 index 00000000..69e7759e --- /dev/null +++ b/src/main/java/org/poolc/api/notification/dto/NotificationSummaryResponse.java @@ -0,0 +1,18 @@ +package org.poolc.api.notification.dto; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class NotificationSummaryResponse { + private long unreadCount; + private List responses; + + public static NotificationSummaryResponse of(long unreadCount, List responses) { + NotificationSummaryResponse response = new NotificationSummaryResponse(); + response.responses = responses; + response.unreadCount = unreadCount; + return response; + } +} diff --git a/src/main/java/org/poolc/api/notification/repository/NotificationRepository.java b/src/main/java/org/poolc/api/notification/repository/NotificationRepository.java index cb42a689..aefcb27c 100644 --- a/src/main/java/org/poolc/api/notification/repository/NotificationRepository.java +++ b/src/main/java/org/poolc/api/notification/repository/NotificationRepository.java @@ -13,4 +13,6 @@ public interface NotificationRepository extends JpaRepository findAllByReceiverId(String receiverId); + @Query("SELECT COUNT(n) FROM Notification n WHERE n.receiverId = :receiverId AND n.readStatus = false") + Long countByReceiverIdAndReadIsFalse(String receiverId); } diff --git a/src/main/java/org/poolc/api/notification/service/NotificationService.java b/src/main/java/org/poolc/api/notification/service/NotificationService.java index cd1b5df2..627b9c93 100644 --- a/src/main/java/org/poolc/api/notification/service/NotificationService.java +++ b/src/main/java/org/poolc/api/notification/service/NotificationService.java @@ -1,9 +1,11 @@ package org.poolc.api.notification.service; +import org.poolc.api.notification.dto.NotificationResponse; +import org.poolc.api.notification.dto.NotificationSummaryResponse; +import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import org.poolc.api.member.domain.Member; import org.poolc.api.member.repository.MemberRepository; -import org.poolc.api.member.service.MemberService; import org.poolc.api.notification.domain.Notification; import org.poolc.api.notification.domain.NotificationType; import org.poolc.api.notification.repository.NotificationRepository; @@ -20,62 +22,71 @@ public class NotificationService { private final NotificationRepository notificationRepository; private final MemberRepository memberRepository; - public List getUnreadNotificationsForMember(String receiverId) { - List notifications = notificationRepository.findByReceiverIdAndReadStatus(receiverId, false) + @Transactional + public NotificationSummaryResponse getUnreadNotificationsForMember(Member member) { + List responses = notificationRepository.findByReceiverIdAndReadStatus(member.getLoginID(), false) .stream() .sorted(Comparator.comparing(Notification::getCreatedAt).reversed()) + .map(NotificationResponse::of) .collect(Collectors.toList()); - notifications.forEach(Notification::memberReads); - Member recipient = getMemberByLoginID(receiverId); - recipient.resetNotificationCount(); - return notifications; + long unreadCount = notificationRepository.countByReceiverIdAndReadIsFalse(member.getLoginID()); + return NotificationSummaryResponse.of(unreadCount, responses); } - public List getAllNotificationsForMember(String receiverId) { - List notifications = notificationRepository.findAllByReceiverId(receiverId) + @Transactional + public NotificationSummaryResponse getAllNotificationsForMember(Member member) { + List responses = notificationRepository.findAllByReceiverId(member.getLoginID()) .stream() + //.peek(Notification::memberReads) // Apply the memberReads method .sorted(Comparator.comparing(Notification::getCreatedAt).reversed()) + .map(NotificationResponse::of) .collect(Collectors.toList()); - notifications.forEach(Notification::memberReads); - Member recipient = getMemberByLoginID(receiverId); - recipient.resetNotificationCount(); - return notifications; + long unreadCount = notificationRepository.countByReceiverIdAndReadIsFalse(member.getLoginID()); + return NotificationSummaryResponse.of(unreadCount, responses); } - + @Transactional public void createBadgeNotification(Member receiver) { - notificationRepository.save(new Notification(receiver.getLoginID(), NotificationType.BADGE)); - receiver.addNotification(); + Notification notification = new Notification(receiver.getLoginID(), NotificationType.BADGE); + notificationRepository.save(notification); + //sendRealTimeNotification(notification); } - public void createMessageNotification(String senderId, String receiverId) { - Member sender = getMemberByLoginID(senderId); + @Transactional + public void createMessageNotification(String senderId, String receiverId, Long messageId) { Member receiver = getMemberByLoginID(receiverId); - notificationRepository.save(new Notification(senderId, receiverId, sender.getName(), NotificationType.MESSAGE)); - receiver.addNotification(); + Notification notification = new Notification(senderId, receiverId, messageId, NotificationType.MESSAGE); + notificationRepository.save(notification); } + @Transactional public void createCommentNotification(String senderId, String receiverId, Long postId) { Member sender = getMemberByLoginID(senderId); Member receiver = getMemberByLoginID(receiverId); - notificationRepository.save(new Notification(senderId, receiverId, sender.getName(), postId, NotificationType.COMMENT)); - receiver.addNotification(); + notificationRepository.save(new Notification(senderId, receiverId, postId, NotificationType.POST)); } + @Transactional public void createRecommentNotification(String senderId, String receiverId, Long postId, Long parentCommentId) { Member sender = getMemberByLoginID(senderId); Member receiver = getMemberByLoginID(receiverId); - notificationRepository.save(new Notification(senderId, receiverId, sender.getName(), postId, parentCommentId, NotificationType.RECOMMENT)); - receiver.addNotification(); + notificationRepository.save(new Notification(senderId, receiverId, parentCommentId, NotificationType.COMMENT)); } - public void readNotification(Long notificationId) { + @Transactional + public NotificationResponse readNotification(Member member, Long notificationId) { Notification notification = notificationRepository.findById(notificationId) - .orElseThrow(() -> new NoSuchElementException("No notification with given id.")); + .orElseThrow(() -> new NoSuchElementException("No notification found with given id.")); + checkIfSelf(member, notification); notification.memberReads(); + return NotificationResponse.of(notification); } private Member getMemberByLoginID(String loginID) { return memberRepository.findByLoginID(loginID) .orElseThrow(() -> new NoSuchElementException("No user found with given loginID")); } + + private void checkIfSelf(Member member, Notification notification) { + if (!notification.getReceiverId().equals(member.getLoginID())) throw new NoSuchElementException("No notification found."); + } } diff --git a/src/main/java/org/poolc/api/post/controller/PostController.java b/src/main/java/org/poolc/api/post/controller/PostController.java index 149b0514..2c3d7d3f 100644 --- a/src/main/java/org/poolc/api/post/controller/PostController.java +++ b/src/main/java/org/poolc/api/post/controller/PostController.java @@ -33,13 +33,13 @@ public class PostController { @PostMapping(value = "/post/new") public ResponseEntity registerPost(@AuthenticationPrincipal Member member, @RequestBody PostCreateRequest request) { - postService.createPost(new PostCreateValues(member, request)); + postService.createPost(member, request); return ResponseEntity.status(HttpStatus.CREATED).build(); } @GetMapping("/post/{postId}") public ResponseEntity viewPost(@AuthenticationPrincipal Member member, @PathVariable Long postId) { - Post post = postService.findPostById(member, postId); + Post post = postService.findById(member, postId); PostResponse response = PostResponse.of(post, scrapService.isScrap(member.getLoginID(),postId)); return ResponseEntity.status(HttpStatus.OK).body(response); } @@ -62,14 +62,14 @@ public ResponseEntity viewMyPosts(@AuthenticationPrincipal Mem public ResponseEntity updatePost(@AuthenticationPrincipal Member member, @PathVariable Long postId, @RequestBody @Valid PostUpdateRequest request) { - Post post = postService.findPostById(member, postId); + Post post = postService.findById(member, postId); postService.updatePost(member, postId, new PostUpdateValues(post.getPostType(), request)); return ResponseEntity.status(HttpStatus.OK).build(); } @PostMapping("/post/{postId}/like") public ResponseEntity likePost(@AuthenticationPrincipal Member member, @PathVariable Long postId) { - likeService.like(member.getLoginID(), Subject.POST, postId); + likeService.like(member, Subject.POST, postId); return ResponseEntity.status(HttpStatus.OK).build(); } diff --git a/src/main/java/org/poolc/api/post/domain/BoardType.java b/src/main/java/org/poolc/api/post/domain/BoardType.java index 95fe0c64..88c816c7 100644 --- a/src/main/java/org/poolc/api/post/domain/BoardType.java +++ b/src/main/java/org/poolc/api/post/domain/BoardType.java @@ -1,14 +1,16 @@ package org.poolc.api.post.domain; import java.util.Arrays; +import lombok.Getter; public enum BoardType { - NOTICE(0L, "공지 게시판"), - FREE(0L, "자유 게시판"), - JOB(0L, "취업 게시판"), - PROJECT(0L, "프로젝트 게시판"), - CS(0L, "CS 게시판"); + NOTICE(0L, "notice"), + FREE(0L, "free"), + JOB(0L, "job"), + PROJECT(0L, "project"), + CS(0L, "cs"); + @Getter private Long postCount; private final String boardName; @@ -17,10 +19,6 @@ private BoardType(Long postCount, String boardName) { this.boardName = boardName; } - public Long getPostCount() { - return postCount; - } - public static BoardType getBoardTypeByName(String name) { return Arrays.stream(BoardType.values()) .filter(boardType -> boardType.boardName.equals(name)) diff --git a/src/main/java/org/poolc/api/post/domain/Post.java b/src/main/java/org/poolc/api/post/domain/Post.java index 4402bc08..d51960e4 100644 --- a/src/main/java/org/poolc/api/post/domain/Post.java +++ b/src/main/java/org/poolc/api/post/domain/Post.java @@ -13,6 +13,7 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static javax.persistence.FetchType.EAGER; @@ -155,15 +156,16 @@ public void setIsDeleted() { } public void updatePost(PostType postType, PostUpdateValues values) { - this.anonymous = values.getAnonymous(); - this.title = values.getTitle(); - this.body = values.getBody(); - this.fileList = values.getFileList(); + Optional.ofNullable(values.getAnonymous()).ifPresent(anonymous -> this.anonymous = anonymous); + Optional.ofNullable(values.getTitle()).ifPresent(title -> this.title = title); + Optional.ofNullable(values.getBody()).ifPresent(body -> this.body = body); + Optional.ofNullable(values.getFileList()).ifPresent(fileList -> this.fileList = fileList); + if (postType == PostType.JOB_POST) { - this.position = values.getPosition(); - this.region = values.getRegion(); - this.field = values.getField(); - this.deadline = values.getDeadline(); + Optional.ofNullable(values.getPosition()).ifPresent(position -> this.position = position); + Optional.ofNullable(values.getRegion()).ifPresent(region -> this.region = region); + Optional.ofNullable(values.getField()).ifPresent(field -> this.field = field); + Optional.ofNullable(values.getDeadline()).ifPresent(deadline -> this.deadline = deadline); } } } diff --git a/src/main/java/org/poolc/api/post/dto/GetPostsResponse.java b/src/main/java/org/poolc/api/post/dto/GetPostsResponse.java index dd50e286..27b4e6aa 100644 --- a/src/main/java/org/poolc/api/post/dto/GetPostsResponse.java +++ b/src/main/java/org/poolc/api/post/dto/GetPostsResponse.java @@ -11,8 +11,6 @@ import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; @Getter @Setter @@ -39,7 +37,7 @@ public class GetPostsResponse { public static GetPostsResponse of(Post post) { GetPostsResponse response = new GetPostsResponse(); - if (post.getIsDeleted()) return null; + // if (post.getIsDeleted()) return null; if (!post.getAnonymous()) { response.setWriterName(post.getMember().getName()); response.setWriterLoginId(post.getMember().getLoginID()); diff --git a/src/main/java/org/poolc/api/post/dto/PostCreateRequest.java b/src/main/java/org/poolc/api/post/dto/PostCreateRequest.java index db8109a3..593b741f 100644 --- a/src/main/java/org/poolc/api/post/dto/PostCreateRequest.java +++ b/src/main/java/org/poolc/api/post/dto/PostCreateRequest.java @@ -36,8 +36,7 @@ public class PostCreateRequest { private LocalDate deadline; @JsonCreator public PostCreateRequest(BoardType boardType, Boolean anonymous, String title, String body, List fileList, - PostType postType, Boolean isQuestion, - JobType position, String region, String field, LocalDate deadline) { + PostType postType, Boolean isQuestion, JobType position, String region, String field, LocalDate deadline) { this.boardType = boardType; this.anonymous = anonymous; this.title = title; diff --git a/src/main/java/org/poolc/api/post/dto/PostResponse.java b/src/main/java/org/poolc/api/post/dto/PostResponse.java index c6b3ef6f..76d05426 100644 --- a/src/main/java/org/poolc/api/post/dto/PostResponse.java +++ b/src/main/java/org/poolc/api/post/dto/PostResponse.java @@ -46,7 +46,7 @@ public class PostResponse { public static PostResponse of(Post post, boolean isScraped) { PostResponse response = new PostResponse(); - if (post.getIsDeleted()) return null; + // if (post.getIsDeleted()) return null; if (!post.getAnonymous()) { response.setWriterName(post.getMember().getName()); response.setWriterLoginId(post.getMember().getLoginID()); diff --git a/src/main/java/org/poolc/api/post/dto/PostUpdateRequest.java b/src/main/java/org/poolc/api/post/dto/PostUpdateRequest.java index 4ccc31de..3b872971 100644 --- a/src/main/java/org/poolc/api/post/dto/PostUpdateRequest.java +++ b/src/main/java/org/poolc/api/post/dto/PostUpdateRequest.java @@ -22,7 +22,8 @@ public class PostUpdateRequest { private LocalDate deadline; @JsonCreator - public PostUpdateRequest(Boolean anonymous, String title, String body, List fileList, List commentList, JobType position, String region, String field, LocalDate deadline) { + public PostUpdateRequest(Boolean anonymous, String title, String body, List fileList, List commentList, JobType position, + String region, String field, LocalDate deadline) { this.anonymous = anonymous; this.title = title; this.body = body; diff --git a/src/main/java/org/poolc/api/post/repository/PostRepository.java b/src/main/java/org/poolc/api/post/repository/PostRepository.java index dd68abfb..6e2cd502 100644 --- a/src/main/java/org/poolc/api/post/repository/PostRepository.java +++ b/src/main/java/org/poolc/api/post/repository/PostRepository.java @@ -9,14 +9,18 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface PostRepository extends JpaRepository, PagingAndSortingRepository, JpaSpecificationExecutor { + @Query("select p from Post p where p.member=:member and p.isDeleted=false") Page findByMember(Member member, Pageable pageable); @Query("select p from Post p where p.boardType=:boardType and p.isDeleted=false") - Page findByBoardType(BoardType boardType, Pageable pageable); + Page findByBoardType(@Param("boardType") BoardType boardType, Pageable pageable); + + @Query("select p from Post p where (p.title like %:title% or p.body like %:body%) and p.isDeleted = false") Page findByTitleContainingOrBodyContaining(String title, String body, Pageable pageable); } diff --git a/src/main/java/org/poolc/api/post/service/PostService.java b/src/main/java/org/poolc/api/post/service/PostService.java index dec6d3fd..7522d4f4 100644 --- a/src/main/java/org/poolc/api/post/service/PostService.java +++ b/src/main/java/org/poolc/api/post/service/PostService.java @@ -9,6 +9,7 @@ import org.poolc.api.post.domain.Post; import org.poolc.api.post.dto.GetBoardResponse; import org.poolc.api.post.dto.GetPostsResponse; +import org.poolc.api.post.dto.PostCreateRequest; import org.poolc.api.post.repository.PostRepository; import org.poolc.api.post.vo.PostCreateValues; import org.poolc.api.post.vo.PostUpdateValues; @@ -31,7 +32,7 @@ public class PostService { //좋아요 수에 따라 뱃지 자동지급 용도 private final BadgeConditionService badgeConditionService; - public Post findPostById(Member member, Long postId) { + public Post findById(Member member, Long postId) { Post post = postRepository.findById(postId) .orElseThrow(() -> new NoSuchElementException("No post found with given post id.")); checkReadPermission(member, post.getBoardType()); @@ -67,7 +68,8 @@ public GetBoardResponse findPostsByBoard(Member member, BoardType boardType, int } @Transactional - public void createPost(PostCreateValues values) { + public void createPost(Member member, PostCreateRequest request) { + PostCreateValues values = new PostCreateValues(member, request); checkWritePermission(values.getMember(), values.getBoardType()); Post post = new Post(values.getMember(), values); postRepository.save(post); @@ -76,14 +78,14 @@ public void createPost(PostCreateValues values) { @Transactional public void updatePost(Member member, Long postId, PostUpdateValues values) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkWriter(member, post); post.updatePost(post.getPostType(), values); - postRepository.save(post); + // postRepository.save(post); } public void likePost(Member member, Long postId) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkNotWriter(member, post); post.addLikeCount(); badgeConditionService.like(post.getMember()); @@ -91,7 +93,7 @@ public void likePost(Member member, Long postId) { } public void dislikePost(Member member, Long postId) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkNotWriter(member, post); post.deductLikeCount(); badgeConditionService.dislike(post.getMember()); @@ -99,27 +101,28 @@ public void dislikePost(Member member, Long postId) { } public void scrapPost(Member member, Long postId) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkNotWriter(member, post); post.addScrapCount(); postRepository.save(post); } public void unscrapPost(Member member, Long postId) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkNotWriter(member, post); post.deductScrapCount(); postRepository.save(post); } + @Transactional public void deletePost(Member member, Long postId) { - Post post = findPostById(member, postId); + Post post = findById(member, postId); checkWriterOrAdmin(member, post); - if (!post.getIsQuestion()) { + if (post.getIsQuestion() == null || !post.getIsQuestion()) { post.setIsDeleted(); } BoardType.removePostCount(post.getBoardType()); - postRepository.save(post); + // postRepository.save(post); } public GetBoardResponse searchPost(Member member, String keyword, int page) { diff --git a/src/main/java/org/poolc/api/scrap/service/ScrapService.java b/src/main/java/org/poolc/api/scrap/service/ScrapService.java index f519ace1..93270a30 100644 --- a/src/main/java/org/poolc/api/scrap/service/ScrapService.java +++ b/src/main/java/org/poolc/api/scrap/service/ScrapService.java @@ -60,7 +60,7 @@ public GetBoardResponse viewMyPosts(Member member, int page) { } private GetPostsResponse scrapToPostResponse(Member member, Scrap scrap) { - Post post = postService.findPostById(member, scrap.getPostId()); + Post post = postService.findById(member, scrap.getPostId()); return GetPostsResponse.of(post); } }