Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 컨텐츠 별 soft delete 적용 #58

Merged
merged 1 commit into from
Nov 5, 2024
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 @@ -74,8 +74,8 @@ public static FindPostAndCommentsByIdResponse toFindPostAndCommentsByIdResponse(
post.getVotes().stream()
.filter(vote -> vote.getMember() == member)
.findFirst()
.map(Vote::getSide)
.orElse(Side.NONE),
.map(vote -> vote.getSide().getValue())
.orElse(Side.NONE.getValue()),
post.getTitle(),
post.getMember().getNickname(),
post.getSummaryAi(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@RequiredArgsConstructor
public enum CommentConstants {

UNKNOWN_MEMBER("알 수 없음"),
DELETED_COMMENT("댓글이 삭제되었습니다."),
DELETED_MEMBER("탈퇴한 회원"),
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,22 @@ private ParentComment(

public void deleteParentCommentSoftly() {
this.member = null;
this.nickname = CommentConstants.DELETED_MEMBER.getValue();
this.nickname = CommentConstants.UNKNOWN_MEMBER.getValue();
this.isDeleted = true;
}

public void deleteParentCommentSoftlyWithContent() {
this.member = null;
this.nickname = CommentConstants.DELETED_MEMBER.getValue();
this.nickname = CommentConstants.UNKNOWN_MEMBER.getValue();
this.isDeleted = true;
content = CommentConstants.DELETED_COMMENT.getValue();
}

public void updateContent(String content) {
this.content = content;
}

public void deleteChildComment(Long childCommentId) {
childComments.removeIf(childComment -> childComment.getId().equals(childCommentId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,13 @@ public void validateAndUpdateChildComment(Member member, Long childCommentId, Sa
public void validateAndDeleteChildComment(Member member, Long childCommentId) {
validateChildCommentAuthority(member, childCommentId);

childCommentRepository.findById(childCommentId)
.ifPresent(ChildComment::deleteChildCommentSoftly);
ParentComment parentComment = childCommentRepository.findById(childCommentId)
.orElseThrow(() -> ApiException.from(CHILD_COMMENT_NOT_FOUND))
.getParentComment();

parentComment.deleteChildComment(childCommentId);
childCommentRepository.deleteById(childCommentId);
parentCommentService.deleteIfChildrenIsEmpty(parentComment);
}

// id로 자식 댓글 조회
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,25 @@ public void validateAndUpdateParentComment(Member member, Long commentId, Update
public void validateAndDeleteParentComment(Member member, Long commentId) {
validateParentCommentAuthority(member, commentId);


parentCommentRepository.findById(commentId)
.ifPresent(ParentComment::deleteParentCommentSoftly);
.ifPresent((parentComment) -> {
if(!parentComment.getChildComments().isEmpty()){
parentComment.deleteParentCommentSoftlyWithContent();
return;
}
parentCommentRepository.delete(parentComment);
});
}

// 부모 댓글 조회
public ParentComment findById(Long commentId) {
return parentCommentRepository.findById(commentId)
.orElseThrow(() -> ApiException.from(PARENT_COMMENT_NOT_FOUND));
}

public void deleteIfChildrenIsEmpty(ParentComment parentComment){
if(parentComment.getChildComments().isEmpty()){
parentCommentRepository.delete(parentComment);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public ResponseEntity<DataResponse<Void>> saveProfileImageMetaData(@RequestBody
@DeleteMapping("/profile")
public ResponseEntity<DataResponse<Void>> deleteProfileImage() {
memberService.deleteProfileImage();

return ResponseEntity.status(HttpStatus.NO_CONTENT).body(DataResponse.noContent());
}

Expand All @@ -100,15 +99,14 @@ public ResponseEntity<DataResponse<Void>> loginMember(@RequestParam("email") Str
// 내 정보 조회 (프로필 이미지 포함)
@GetMapping
public ResponseEntity<DataResponse<FindMyInfoResponse>> findMyInfo() {
return ResponseEntity.status(HttpStatus.OK)
.body(DataResponse.from(memberService.findMyInfo()));
return ResponseEntity.status(HttpStatus.OK).body(DataResponse.from(memberService.findMyInfo()));
}

// 비밀번호 수정(현재 비밀번호 확인)
@PutMapping("/password")
public ResponseEntity<DataResponse<Void>> updatePassword(@Valid @RequestBody UpdatePasswordRequest updatePasswordRequest) {
public ResponseEntity<DataResponse<Void>> updatePassword(
@Valid @RequestBody UpdatePasswordRequest updatePasswordRequest) {
memberService.updatePassword(updatePasswordRequest);

return ResponseEntity.status(HttpStatus.CREATED).body(DataResponse.created());
}

Expand All @@ -117,22 +115,19 @@ public ResponseEntity<DataResponse<Void>> updatePassword(@Valid @RequestBody Upd
public ResponseEntity<DataResponse<Void>> sendTemporaryPassword(
@Valid @RequestBody SendTemporaryPasswordRequest sendTemporaryPasswordRequest) throws MessagingException {
memberService.updateTemporaryPasswordAndSendMail(sendTemporaryPasswordRequest);

return ResponseEntity.status(HttpStatus.CREATED).body(DataResponse.created());
}


@GetMapping("/nickname/{nickname}/exists")
public ResponseEntity<DataResponse<NicknameExistsResponse>> checkNicknameExists(@PathVariable("nickname") String nickname) {
public ResponseEntity<DataResponse<NicknameExistsResponse>> checkNicknameExists(
@PathVariable("nickname") String nickname) {
NicknameExistsResponse exist = new NicknameExistsResponse(memberService.checkNicknameExists(nickname));

return ResponseEntity.status(HttpStatus.OK).body(DataResponse.from(exist));
}

@PutMapping("/nickname")
public ResponseEntity<DataResponse<Void>> updateNickname(@RequestBody UpdateNicknameRequest updateNicknameRequest) {
memberService.updateNickname(updateNicknameRequest);

return ResponseEntity.status(HttpStatus.CREATED).body(DataResponse.created());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public void updateNickname(String nickname) {
this.nickname = nickname;
}



@Builder
private Member(
String nickname,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import aimo.backend.common.exception.ApiException;
import aimo.backend.common.exception.ErrorCode;
import aimo.backend.domains.comment.entity.ChildComment;
import aimo.backend.domains.comment.entity.ParentComment;
import aimo.backend.domains.member.dto.request.DeleteMemberRequest;
import aimo.backend.domains.member.dto.response.FindMyInfoResponse;
import aimo.backend.domains.member.dto.request.LogoutRequest;
Expand All @@ -15,6 +17,7 @@
import aimo.backend.common.mapper.MemberMapper;
import aimo.backend.domains.member.repository.MemberRepository;
import aimo.backend.domains.member.repository.ProfileImageRepository;
import aimo.backend.domains.post.service.PostService;
import aimo.backend.domains.privatePost.dto.request.CreateResourceUrlRequest;
import aimo.backend.infrastructure.s3.S3Service;
import aimo.backend.infrastructure.s3.dto.SaveFileMetaDataRequest;
Expand Down Expand Up @@ -46,6 +49,7 @@ public class MemberService {
private final ProfileImageRepository profileImageRepository;
private final S3Service s3Service;
private final MailService mailService;
private final PostService postService;

// 이메일로 멤버 조회
public Optional<Member> findByEmail(String email) {
Expand Down Expand Up @@ -84,6 +88,7 @@ public void deleteMember(DeleteMemberRequest deleteMemberRequest) {
throw ApiException.from(ErrorCode.INVALID_PASSWORD);
}

deleteMemberContents();
memberRepository.delete(member);
}

Expand Down Expand Up @@ -152,6 +157,24 @@ protected boolean isValid(String password, String encodedPassword) {
return passwordEncoder.matches(password, encodedPassword);
}

private void deleteMemberContents(){
Member member = memberLoader.getMember();

member.getPosts()
.forEach(post -> postService.softDeleteBy(post.getId()));

member.getParentComments()
.stream()
.filter(parentComment -> !parentComment.getIsDeleted())
.forEach(ParentComment::deleteParentCommentSoftly);

member.getChildComments()
.stream()
.filter(childComment -> !childComment.getIsDeleted())
.forEach(ChildComment::deleteChildCommentSoftly);

}

// 이메일 중복 검사
private void validateDuplicateEmail(String email) {
if (memberRepository.existsByEmail(email)) {
Expand All @@ -166,6 +189,8 @@ private void validateDuplicateNickname(String nickname) {
}
}



@Transactional(rollbackFor = ApiException.class)
public void updateTemporaryPasswordAndSendMail(SendTemporaryPasswordRequest sendTemporaryPasswordRequest) throws
MessagingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,41 +35,30 @@ public class PostController {
@PostMapping
public ResponseEntity<DataResponse<Void>> savePost(@RequestBody @Valid SavePostRequest request) {
postService.save(request);

return ResponseEntity
.status(HttpStatus.CREATED)
.body(DataResponse.created());
return ResponseEntity.status(HttpStatus.CREATED).body(DataResponse.created());
}

@GetMapping
public ResponseEntity<DataResponse<Page<FindPostsByPostTypeResponse>>> findPostsByPostType(
@RequestParam("type") @NotNull PostType postType,
@RequestParam("page") @NotNull Integer page,
@RequestParam("size") @NotNull Integer size
) {
Page<FindPostsByPostTypeResponse> responses = postService.findPostDtosByPostType(postType, page, size);

return ResponseEntity.ok(DataResponse.from(responses));
@RequestParam("type") @NotNull PostType postType, @RequestParam("page") @NotNull Integer page,
@RequestParam("size") @NotNull Integer size) {
return ResponseEntity.ok(DataResponse.from(postService.findPostDtosByPostType(postType, page, size)));
}

@GetMapping("/{postId}")
public ResponseEntity<DataResponse<FindPostAndCommentsByIdResponse>> findPostAndComments(
@PathVariable Long postId) {

FindPostAndCommentsByIdResponse response = postService.findPostAndCommentsDtoById(postId);

return ResponseEntity.ok(DataResponse.from(response));
return ResponseEntity.ok(DataResponse.from(postService.findPostAndCommentsDtoById(postId)));
}

@DeleteMapping("/{postId}")
public ResponseEntity<DataResponse<Void>> deletePost(@PathVariable Long postId) {
postService.deletePost(postId);

postService.deletePostBy(postId);
return ResponseEntity.ok(DataResponse.noContent());
}

@PostMapping("/{postId}/views")
public void increaseView(@PathVariable Long postId) {
postViewService.increaseView(postId);
postViewService.increaseViewBy(postId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public class VoteController {
private final MemberLoader memberLoader;

@PostMapping("/{postId}/votes")
public ResponseEntity<DataResponse<Void>> votePost(
@PathVariable Long postId,
@RequestParam("side") Side side
) {
public ResponseEntity<DataResponse<Void>> votePost(@PathVariable Long postId, @RequestParam("side") Side side) {
voteService.votePost(memberLoader.getMember(), postId, side);

return ResponseEntity.ok(DataResponse.noContent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
public class FindPostAndCommentsByIdResponse {
private final Boolean isMine;
private final Boolean isLiked;
@Enumerated(EnumType.STRING)
private final Side side;
private final String side;
private final String title;
private final String nickname;
private final String content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import aimo.backend.domains.member.entity.Member;
import aimo.backend.domains.post.model.Category;
import aimo.backend.domains.post.model.Side;
import aimo.backend.domains.privatePost.entity.PrivatePost;
import aimo.backend.domains.privatePost.model.OriginType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -102,11 +103,16 @@ public Integer getCommentsCount() {
.reduce(1, Integer::sum);
}

public void deletePost() {
public void delete() {
this.member.getPosts().remove(this);
this.member = null;
}

public void softDelete() {
this.member = null;
this.privatePostId = null;
}

public Integer getPlaintiffVotesCount() {
return votes.stream()
.filter(vote -> vote.getSide() == Side.PLAINTIFF)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import lombok.Getter;

@Getter
public enum Side {
PLAINTIFF("plaintiff"),
DEFENDANT("defendant"),
NONE("none");
PLAINTIFF("PLAINTIFF"),
DEFENDANT("DEFENDANT"),
NONE("NONE");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private Page<Post> findCommentedPosts(Long memberId, Pageable pageable) {

// 글 삭제
@Transactional
public void deletePost(Long postId) {
public void deletePostBy(Long postId) {
Long memberId = memberLoader.getMember().getId();
validateDeletePost(memberId, postId);

Expand All @@ -149,4 +149,10 @@ public void validateDeletePost(Long memberId, Long postId) {
throw ApiException.from(POST_DELETE_UNAUTHORIZED);
}
}

public void softDeleteBy(Long postId) {
Post post = findById(postId);
privatePostService.deletePrivatePostBy(post.getPrivatePostId());
post.softDelete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class PostViewService {

// 조회수 증가
@Transactional(rollbackFor = Exception.class)
public void increaseView(Long postId) {
public void increaseViewBy(Long postId) {
Member member = memberLoader.getMember();
Post post = postService.findById(postId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import aimo.backend.domains.privatePost.dto.request.SpeachToTextRequest;
import aimo.backend.domains.privatePost.dto.response.SpeachToTextResponse;

import aimo.backend.domains.privatePost.dto.response.JudgementFromAiResponse;
import aimo.backend.domains.privatePost.dto.request.TextRecordRequest;
import aimo.backend.domains.privatePost.service.AudioRecordService;
import aimo.backend.domains.privatePost.service.ChatRecordService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package aimo.backend.domains.privatePost.dto.response;

public record SpeachToTextResponse(
String title,
String script
) {
}
) { }
Loading