Skip to content

Commit

Permalink
feat: 회원탈퇴 API (#59)
Browse files Browse the repository at this point in the history
* feat: 회원 탈퇴 사유 저장 table 추가

* feat: 회원 탈퇴 로직 추가

* feat: 회원 탈퇴 api 추가
  • Loading branch information
TaeyeonRoyce authored Feb 14, 2024
1 parent 38c5b2b commit df04ea9
Show file tree
Hide file tree
Showing 27 changed files with 254 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/main/java/com/baro/archive/domain/ArchiveRepository.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baro.archive.domain;

import com.baro.member.domain.Member;
import java.util.List;

public interface ArchiveRepository {
Expand All @@ -26,5 +27,7 @@ public interface ArchiveRepository {

List<Archive> findAllByMemberIdAndMemoFolderId(Long memberId, Long memoFolderId);

void deleteAllByMember(Member member);

List<Archive> findAllTemplates(Long memberId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.baro.archive.infra;

import com.baro.archive.domain.Archive;
import com.baro.member.domain.Member;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -19,5 +20,7 @@ public interface ArchiveJpaRepository extends JpaRepository<Archive, Long> {

List<Archive> findAllByMemberIdAndMemoFolderIdAndTemplateIdIsNotNull(Long memberId, Long folderId);

void deleteAllByMember(Member member);

List<Archive> findAllByMemberIdAndTemplateIdIsNotNull(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.baro.archive.domain.ArchiveRepository;
import com.baro.archive.exception.ArchiveException;
import com.baro.archive.exception.ArchiveExceptionType;
import com.baro.member.domain.Member;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand Down Expand Up @@ -56,6 +57,11 @@ public List<Archive> findAllByMemberIdAndMemoFolderId(Long memberId, Long memoFo
return archiveJpaRepository.findAllByMemberIdAndMemoFolderId(memberId, memoFolderId);
}

@Override
public void deleteAllByMember(Member member) {
archiveJpaRepository.deleteAllByMember(member);
}

@Override
public List<Archive> findAllTemplates(Long memberId) {
return archiveJpaRepository.findAllByMemberIdAndTemplateIdIsNotNull(memberId);
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/com/baro/member/application/MemberService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.baro.member.application;

import com.baro.archive.domain.ArchiveRepository;
import com.baro.common.image.ImageStorageClient;
import com.baro.common.image.dto.ImageUploadResult;
import com.baro.member.application.dto.DeleteMemberCommand;
import com.baro.member.application.dto.GetMemberProfileResult;
import com.baro.member.application.dto.UpdateMemberProfileCommand;
import com.baro.member.application.dto.UpdateProfileImageCommand;
import com.baro.member.domain.Member;
import com.baro.member.domain.MemberRepository;
import com.baro.member.domain.MemberWithdrawalInfo;
import com.baro.member.domain.MemberWithdrawalInfoRepository;
import com.baro.member.exception.MemberException;
import com.baro.member.exception.MemberExceptionType;
import com.baro.memo.domain.TemporalMemoRepository;
import com.baro.memofolder.domain.MemoFolderRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,6 +26,10 @@ public class MemberService {

private final MemberRepository memberRepository;
private final ImageStorageClient imageStorageClient;
private final TemporalMemoRepository temporalMemoRepository;
private final ArchiveRepository archiveRepository;
private final MemoFolderRepository memoFolderRepository;
private final MemberWithdrawalInfoRepository memberWithdrawalInfoRepository;

@Transactional(readOnly = true)
public GetMemberProfileResult getMyProfile(Long id) {
Expand Down Expand Up @@ -54,4 +64,13 @@ public void updateProfileImage(UpdateProfileImageCommand command) {
ImageUploadResult imageUploadResult = imageStorageClient.upload(command.image());
member.updateProfileImage(imageUploadResult.key());
}

public void deleteMember(DeleteMemberCommand command) {
Member member = memberRepository.getById(command.memberId());
temporalMemoRepository.deleteAllByMember(member);
archiveRepository.deleteAllByMember(member);
memoFolderRepository.deleteAllByMember(member);
memberRepository.deleteById(command.memberId());
memberWithdrawalInfoRepository.save(new MemberWithdrawalInfo(command.reason()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.baro.member.application.dto;

public record DeleteMemberCommand(
Long memberId,
String reason
) {
}
2 changes: 2 additions & 0 deletions src/main/java/com/baro/member/domain/MemberRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public interface MemberRepository {
Optional<Member> findById(Long memberId);

Member getById(Long memberId);

void deleteById(Long aLong);
}
34 changes: 34 additions & 0 deletions src/main/java/com/baro/member/domain/MemberWithdrawalInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.baro.member.domain;

import com.baro.common.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class MemberWithdrawalInfo extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false, columnDefinition = "BIGINT UNSIGNED")
private Long id;

@Column(nullable = false)
private String reason;

public MemberWithdrawalInfo(Long id, String reason) {
this.id = id;
this.reason = reason;
}

public MemberWithdrawalInfo(String reason) {
this(null, reason);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.baro.member.domain;

public interface MemberWithdrawalInfoRepository {

MemberWithdrawalInfo save(MemberWithdrawalInfo memberWithdrawalInfo);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ public Member getById(Long memberId) {
return this.findById(memberId)
.orElseThrow(() -> new MemberException(MemberExceptionType.NOT_EXIST_MEMBER));
}

@Override
public void deleteById(Long memberId) {
memberJpaRepository.deleteById(memberId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.baro.member.infrastructure;

import com.baro.member.domain.MemberWithdrawalInfo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberWithdrawalInfoJpaRepository extends JpaRepository<MemberWithdrawalInfo, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.baro.member.infrastructure;

import com.baro.member.domain.MemberWithdrawalInfo;
import com.baro.member.domain.MemberWithdrawalInfoRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
@Repository
public class MemberWithdrawalInfoRepositoryImpl implements MemberWithdrawalInfoRepository {

private final MemberWithdrawalInfoJpaRepository memberWithdrawalInfoJpaRepository;

@Override
public MemberWithdrawalInfo save(MemberWithdrawalInfo memberWithdrawalInfo) {
return memberWithdrawalInfoJpaRepository.save(memberWithdrawalInfo);
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/baro/member/presentation/MemberController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.baro.auth.domain.AuthMember;
import com.baro.member.application.MemberService;
import com.baro.member.application.dto.DeleteMemberCommand;
import com.baro.member.application.dto.GetMemberProfileResult;
import com.baro.member.application.dto.UpdateMemberProfileCommand;
import com.baro.member.application.dto.UpdateProfileImageCommand;
import com.baro.member.presentation.dto.DeleteMemberRequest;
import com.baro.member.presentation.dto.UpdateMemberProfileRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -59,4 +61,14 @@ public ResponseEntity<Void> updateProfileImage(
memberService.updateProfileImage(command);
return ResponseEntity.noContent().build();
}

@DeleteMapping
public ResponseEntity<Void> deleteMember(
AuthMember authMember,
@RequestBody DeleteMemberRequest request
) {
DeleteMemberCommand command = new DeleteMemberCommand(authMember.id(), request.reason());
memberService.deleteMember(command);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.baro.member.presentation.dto;

public record DeleteMemberRequest(
String reason
) {
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baro.memo.domain;

import com.baro.member.domain.Member;
import java.time.LocalDateTime;
import java.util.List;

Expand All @@ -16,4 +17,6 @@ public interface TemporalMemoRepository {
List<TemporalMemo> findAllByMemberIdAndCreatedAtBetween(Long memberId, LocalDateTime start, LocalDateTime end);

void deleteAllByCreatedAtLessThanEqual(LocalDateTime weekBefore);

void deleteAllByMember(Member member);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baro.memo.infrastructure;

import com.baro.member.domain.Member;
import com.baro.memo.domain.TemporalMemo;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -10,4 +11,6 @@ public interface TemporalMemoJpaRepository extends JpaRepository<TemporalMemo, L
List<TemporalMemo> findAllByMemberIdAndCreatedAtBetween(Long memberId, LocalDateTime start, LocalDateTime end);

void deleteAllByCreatedAtLessThanEqual(LocalDateTime localDateTime);

void deleteAllByMember(Member member);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baro.memo.infrastructure;

import com.baro.member.domain.Member;
import com.baro.memo.domain.TemporalMemo;
import com.baro.memo.domain.TemporalMemoRepository;
import com.baro.memo.exception.TemporalMemoException;
Expand Down Expand Up @@ -46,4 +47,9 @@ public List<TemporalMemo> findAllByMemberIdAndCreatedAtBetween(Long memberId, Lo
public void deleteAllByCreatedAtLessThanEqual(LocalDateTime weekBefore) {
temporalMemoJpaRepository.deleteAllByCreatedAtLessThanEqual(weekBefore);
}

@Override
public void deleteAllByMember(Member member) {
temporalMemoJpaRepository.deleteAllByMember(member);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ public interface MemoFolderRepository {
void delete(MemoFolder memoFolder);

MemoFolder getByMemberIdAndIsDefaultTrue(Long memberId);

void deleteAllByMember(Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface MemoFolderJpaRepository extends JpaRepository<MemoFolder, Long>
List<MemoFolder> findAllByMember(Member member);

Optional<MemoFolder> findByMemberIdAndIsDefaultTrue(Long memberId);

void deleteAllByMember(Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ public MemoFolder getByMemberIdAndIsDefaultTrue(Long memberId) {
return memoFolderJpaRepository.findByMemberIdAndIsDefaultTrue(memberId)
.orElseThrow(() -> new MemoFolderException(MemoFolderExceptionType.NOT_EXIST_MEMO_FOLDER));
}

@Override
public void deleteAllByMember(Member member) {
memoFolderJpaRepository.deleteAllByMember(member);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.baro.archive.domain.ArchiveRepository;
import com.baro.archive.exception.ArchiveException;
import com.baro.archive.exception.ArchiveExceptionType;
import com.baro.member.domain.Member;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -84,6 +85,11 @@ public List<Archive> findAllTemplates(Long memberId) {
.toList();
}

@Override
public void deleteAllByMember(Member member) {
archives.values().removeIf(archive -> archive.getMember().getId().equals(member.getId()));
}

@Override
public List<Archive> findAllArchives(Long memberId, Long folderId) {
return archives.values().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;

import com.baro.auth.domain.Token;
import com.baro.member.presentation.dto.DeleteMemberRequest;
import com.baro.member.presentation.dto.UpdateMemberProfileRequest;
import io.restassured.RestAssured;
import io.restassured.builder.MultiPartSpecBuilder;
Expand All @@ -33,6 +34,8 @@ public class MemberAcceptanceSteps {
public static final MultipartFile 프로필_이미지 = new MockMultipartFile("image", "image", "multipart/form-data",
"image".getBytes());

public static final DeleteMemberRequest 회원_탈퇴_요청 = new DeleteMemberRequest("탈퇴 사유");

public static ExtractableResponse<Response> 내_프로필_조회_요청(Token 토큰) {
return RestAssured.given(requestSpec).log().all()
.filter(document(DEFAULT_REST_DOCS_PATH,
Expand Down Expand Up @@ -145,4 +148,19 @@ public class MemberAcceptanceSteps {
throw new RuntimeException(e);
}
}

public static ExtractableResponse<Response> 회원_탈퇴_요청(Token 토큰, DeleteMemberRequest 요청) {
return RestAssured.given(requestSpec).log().all()
.filter(document(DEFAULT_REST_DOCS_PATH,
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("인증 토큰")
)
))
.header(HttpHeaders.AUTHORIZATION, "Bearer " + 토큰.accessToken())
.body(요청)
.contentType("application/json")
.when().delete("/members")
.then().log().all()
.extract();
}
}
Loading

0 comments on commit df04ea9

Please sign in to comment.