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

[MODIFY] 유저 탈퇴시 이벤트 기반으로 삭제해야하는 데이터 삭제 처리 로직 추가 #426

Merged
merged 25 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a16c1e6
[refactor] SoptampFacade에 Transactional 추 (#336)
kseysh Oct 30, 2024
bfaee56
[refactor] 사용하지 않는 메서드 삭제 (#336)
kseysh Oct 30, 2024
0265998
[refactor] 솝탬프 유저 삭제 메서드 추 (#336)
kseysh Oct 30, 2024
70f6fec
[refactor] 알림 삭제 메서드 추가 (#336)
kseysh Oct 30, 2024
3b503aa
[refactor] 불필요한 User 객체 전달을 userId 전달로 변경 (#336)
kseysh Oct 30, 2024
1aed275
[refactor] 불필요한 EventHandler 삭제 처리 (#336)
kseysh Oct 30, 2024
2afbba0
[refactor] 유저 탈퇴시 유저 삭제 Event 추 (#336)
kseysh Oct 30, 2024
5b8b1c1
[refactor] 유저 탈퇴시 솝탬프 유저 삭제 Event 추가 (#336)
kseysh Oct 30, 2024
6108774
[refactor] 스탬프 삭제시 스탬프 s3 이미 삭제 Event 추가 (#336)
kseysh Oct 30, 2024
100e51e
[refactor] 유저 탈퇴시 pokeHistory 삭제 Event 추가 (#336)
kseysh Oct 31, 2024
2d6ca83
[refactor] 유저 탈퇴시 Friend 삭제 Event 추가 (#336)
kseysh Oct 31, 2024
0cb76c8
[refactor] 유저 탈퇴시 Notification 삭제 Event 추가 (#336)
kseysh Oct 31, 2024
bef060c
[refactor] 유저 탈퇴시 PushToken 삭제 메서드 실행 (#336)
kseysh Oct 31, 2024
5290875
[refactor] 유저 탈퇴시 유저 서비스에서 이벤트 기반으로 탈퇴 로직을 처리하도록 변경 (#336)
kseysh Oct 31, 2024
76f66c0
[refactor] 유저 탈퇴시 관련한 오늘의 운세 데이터 삭제 (#336)
kseysh Oct 31, 2024
b468ad3
[refactor] 유저 탈퇴시 파일 삭제 이벤트 발생 테스트 추 (#336)
kseysh Oct 31, 2024
428fe9d
[refactor] 가독성있는 람다 표현식으로 변 (#336)
kseysh Oct 31, 2024
534ab36
[refactor] 유저 탈퇴 책임을 별도의 객체로 관 (#336)
kseysh Oct 31, 2024
62d39c7
[refactor] static이 아닌 싱글톤을 이용해 EventPublisher 관리하도록 변경 (#336)
kseysh Oct 31, 2024
1dc32ca
[refactor] static이 아닌 싱글톤을 이용해 EventPublisher 관리하도록 변경 (#336)
kseysh Oct 31, 2024
d114716
[refactor] 테스트용 기본 yml 변경 (#336)
kseysh Oct 31, 2024
edc486b
[refactor] EventPublisherTest 추가 (#336)
kseysh Oct 31, 2024
a4e71ff
[refactor] 찌르기 실행시 PokeEvent 발생 이벤트 검증 테스트 추가 (#336)
kseysh Oct 31, 2024
994c024
[feat] 스탬프 삭제시 PokeEvent 발생 스탬프 삭제 및 s3이미지 삭제 검증 테스트 추가 (#336)
kseysh Oct 31, 2024
a0f3498
[refactor] 유저 삭제 테스트 책임 이관 (#336)
kseysh Oct 31, 2024
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 @@ -2,12 +2,14 @@

import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.fortune.UserFortune;
import org.sopt.app.interfaces.postgres.fortune.FortuneCardRepository;
import org.sopt.app.interfaces.postgres.fortune.FortuneWordRepository;
import org.sopt.app.interfaces.postgres.fortune.UserFortuneRepository;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -57,4 +59,9 @@ public FortuneCardInfo getTodayFortuneCardByUserId(final Long userId) {
.map(FortuneCardInfo::of)
.orElseThrow(() -> new BadRequestException(ErrorCode.FORTUNE_NOT_FOUND_FROM_USER));
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
userFortuneRepository.deleteAllByUserIdInQuery(event.getUserId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import java.util.Map.Entry;
import org.jetbrains.annotations.NotNull;
import org.sopt.app.application.poke.PokeInfo.Relationship;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.NotFoundException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.common.utils.AnonymousNameGenerator;
import org.sopt.app.domain.entity.Friend;
import org.sopt.app.domain.enums.Friendship;
import org.sopt.app.interfaces.postgres.FriendRepository;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -169,4 +171,10 @@ public boolean getIsNewUser(Long userId) {
public Set<Long> findAllFriendIdsByUserId(Long userId) {
return friendRepository.findAllOfFriendIdsByUserId(userId);
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
friendRepository.deleteAllByFriendUserIdInQuery(event.getUserId());
friendRepository.deleteAllByUserIdInQuery(event.getUserId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.Notification;
Expand All @@ -13,6 +14,7 @@
import org.sopt.app.interfaces.postgres.NotificationRepository;
import org.sopt.app.interfaces.postgres.UserRepository;
import org.sopt.app.presentation.notification.NotificationRequest.RegisterNotificationRequest;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -83,4 +85,9 @@ public boolean getNotificationConfirmStatus(Long userId) {
.toList();
return unreadNotificationList.isEmpty();
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
notificationRepository.deleteByUserIdInQuery(event.getUserId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.PushToken;
import org.sopt.app.domain.entity.User;
import org.sopt.app.domain.enums.PushTokenPlatform;
import org.sopt.app.interfaces.postgres.PushTokenRepository;
import org.sopt.app.presentation.notification.PushTokenRequest;
import org.sopt.app.presentation.notification.PushTokenRequest.PushTokenManageRequest;
import org.sopt.app.presentation.notification.PushTokenResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -59,7 +61,7 @@ public PushTokenResponse.StatusResponse registerDeviceToken(User user, String pu
.platform(PushTokenPlatform.valueOf(platform))
.build();
try {
val entity = new HttpEntity(
val entity = new HttpEntity<>(
createBodyFor(registerToken),
createHeadersFor(ACTION_REGISTER, platform)
);
Expand All @@ -80,37 +82,45 @@ public PushTokenResponse.StatusResponse registerDeviceToken(User user, String pu
.message("토큰 등록 성공")
.build();
}



// 유효하지 않은 토큰으로 인해 BadRequest가 발생하더라도 넘어가야함.(Local 에는 모든 토큰을 쌓아놓기 때문에)
@Transactional
public PushTokenResponse.StatusResponse deleteDeviceToken(PushToken pushToken) {
public void deleteDeviceToken(PushToken pushToken) {
pushTokenRepository.delete(pushToken);
try {
val entity = new HttpEntity(
val entity = new HttpEntity<>(
createBodyFor(pushToken),
createHeadersFor(ACTION_DELETE, pushToken.getPlatform().name())
);
val response = sendRequestToPushServer(entity);
pushTokenRepository.delete(pushToken);
return response.getBody();
response.getBody();
} catch (BadRequestException e) {
return PushTokenResponse.StatusResponse.builder()
PushTokenResponse.StatusResponse.builder()
.status(e.getErrorCode().getHttpStatus().value())
.success(false)
.message(e.getErrorCode().getMessage())
.build();
}
}

@Transactional
public void deleteAllDeviceTokenOf(User user) {
// 기존에 저장되어 있던 Tokens -> 알림 서버에 삭제 요청
List<PushToken> userTokens = pushTokenRepository.findAllByUserId(user.getId());
private ResponseEntity<PushTokenResponse.StatusResponse> sendRequestToPushServer(
HttpEntity<PushTokenManageRequest> requestEntity
) {
return restTemplate.exchange(
baseURI,
HttpMethod.POST,
requestEntity,
PushTokenResponse.StatusResponse.class
);
}

@EventListener(UserWithdrawEvent.class)
public void deleteAllDeviceTokenOf(final UserWithdrawEvent event) {
List<PushToken> userTokens = pushTokenRepository.findAllByUserId(event.getUserId());
if (!userTokens.isEmpty()) {
for (PushToken token : userTokens) {
deleteDeviceToken(token);
this.deleteDeviceToken(token);
}
// 우선 서비스 DB에 있는 모든 토큰 지워버리기
pushTokenRepository.deleteAll(userTokens);
}
}
Expand All @@ -126,18 +136,10 @@ private HttpHeaders createHeadersFor(String action, String platform) {
return headers;
}

private PushTokenRequest.PushTokenManageRequest createBodyFor(PushToken pushToken) {
return new PushTokenRequest.PushTokenManageRequest(
private PushTokenManageRequest createBodyFor(PushToken pushToken) {
return new PushTokenManageRequest(
List.of(String.valueOf(pushToken.getPlaygroundId())),
pushToken.getToken()
);
}
private ResponseEntity<PushTokenResponse.StatusResponse> sendRequestToPushServer(HttpEntity requestEntity) {
return restTemplate.exchange(
baseURI,
HttpMethod.POST,
requestEntity,
PushTokenResponse.StatusResponse.class
);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package org.sopt.app.application.poke;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.val;
import java.util.*;
import lombok.*;
import org.sopt.app.application.poke.PokeInfo.PokeHistoryInfo;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.poke.PokeHistory;
import org.sopt.app.interfaces.postgres.PokeHistoryRepository;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -80,4 +78,10 @@ public List<PokeHistoryInfo> getAllPokeHistoryByUsers(Long userId, Long friendUs
val pokeHistories = pokeHistoryRepository.findAllPokeHistoryByUsers(userId, friendUserId);
return pokeHistories.stream().map(PokeHistoryInfo::from).toList();
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
pokeHistoryRepository.deleteAllByPokerIdInQuery(event.getUserId());
pokeHistoryRepository.deleteAllByPokedIdInQuery(event.getUserId());
}
}
5 changes: 3 additions & 2 deletions src/main/java/org/sopt/app/application/poke/PokeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.sopt.app.common.event.Events;
import org.sopt.app.common.event.EventPublisher;
import org.sopt.app.common.exception.NotFoundException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.poke.PokeHistory;
Expand All @@ -19,6 +19,7 @@ public class PokeService {

private final UserRepository userRepository;
private final PokeHistoryRepository historyRepository;
private final EventPublisher eventPublisher;

@Transactional(readOnly = true)
public PokeInfo.PokeDetail getPokeDetail(Long pokeHistoryId) {
Expand All @@ -39,7 +40,7 @@ public PokeHistory poke(Long pokerUserId, Long pokedUserId, String pokeMessage,

PokeHistory pokeByApplyingReply = createPokeByApplyingReply(pokerUserId, pokedUserId, pokeMessage, isAnonymous);

Events.raise(PokeEvent.of(pokedUser.getPlaygroundId()));
eventPublisher.raise(PokeEvent.of(pokedUser.getPlaygroundId()));
return pokeByApplyingReply;
}

Expand Down
11 changes: 8 additions & 3 deletions src/main/java/org/sopt/app/application/s3/S3Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import lombok.*;
import org.joda.time.LocalDateTime;
import org.slf4j.LoggerFactory;
import org.sopt.app.application.stamp.StampDeletedEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

@Service
Expand Down Expand Up @@ -49,8 +50,12 @@ public S3Info.PreSignedUrl getPreSignedUrl(String folderName) {
.build();
}

@Async
public void deleteFiles(List<String> fileUrls, String folderName) {
@EventListener(StampDeletedEvent.class)
public void handleStampDeletedEvent(StampDeletedEvent event) {
this.deleteFiles(event.getFileUrls(), "stamp");
}

private void deleteFiles(List<String> fileUrls, String folderName) {
val folderURI = bucket + "/mainpage/makers-app-img/" + folderName;
val fileNameList = getFileNameList(fileUrls);
fileNameList.forEach(file -> deleteFile(folderURI, file));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import lombok.*;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo.ActivityCardinalInfo;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo.PlaygroundProfile;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.soptamp.SoptampUser;
import org.sopt.app.domain.enums.PlaygroundPart;
import org.sopt.app.interfaces.postgres.SoptampUserRepository;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -122,4 +124,9 @@ public void initAllSoptampUserPoints() {
soptampUserList.forEach(SoptampUser::initTotalPoints);
soptampUserRepository.saveAll(soptampUserList);
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
soptampUserRepository.deleteByUserId(event.getUserId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

import java.util.List;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.sopt.app.common.event.Event;

@Getter
@RequiredArgsConstructor
public class StampDeletedEvent extends Event {

private List<String> fileUrls;

public StampDeletedEvent(List<String> fileUrls) {
super();
this.fileUrls = fileUrls;
}
private final List<String> fileUrls;
}

This file was deleted.

14 changes: 11 additions & 3 deletions src/main/java/org/sopt/app/application/stamp/StampService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.common.event.Events;
import org.sopt.app.application.user.UserWithdrawEvent;
import org.sopt.app.common.event.EventPublisher;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.soptamp.Stamp;
import org.sopt.app.interfaces.postgres.StampRepository;
import org.sopt.app.presentation.stamp.StampRequest;
import org.sopt.app.presentation.stamp.StampRequest.RegisterStampRequest;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
Expand All @@ -22,6 +24,7 @@
public class StampService {

private final StampRepository stampRepository;
private final EventPublisher eventPublisher;

@Transactional(readOnly = true)
public StampInfo.Stamp findStamp(Long missionId, Long userId) {
Expand Down Expand Up @@ -143,7 +146,7 @@ public void deleteStampById(Long stampId) {
.orElseThrow(() -> new BadRequestException(ErrorCode.STAMP_NOT_FOUND));
stampRepository.deleteById(stampId);

Events.raise(new StampDeletedEvent(stamp.getImages()));
eventPublisher.raise(new StampDeletedEvent(stamp.getImages()));
}

@Transactional
Expand All @@ -152,7 +155,12 @@ public void deleteAllStamps(Long userId) {

val imageUrls = stampRepository.findAllByUserId(userId).stream().map(Stamp::getImages)
.flatMap(Collection::stream).toList();
Events.raise(new StampDeletedEvent(imageUrls));
eventPublisher.raise(new StampDeletedEvent(imageUrls));
}

@EventListener(UserWithdrawEvent.class)
public void handleUserWithdrawEvent(final UserWithdrawEvent event) {
this.deleteAllStamps(event.getUserId());
}

private void validateStampInfo(Stamp entity) {
Expand Down
Loading
Loading