diff --git a/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/GoalApplicationService.kt b/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/GoalApplicationService.kt index cd671de..54bb3ba 100644 --- a/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/GoalApplicationService.kt +++ b/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/GoalApplicationService.kt @@ -183,7 +183,7 @@ class GoalApplicationService( isNotUsersGoal(goal, userId) isAlreadyStarted(goal) - goalService.delete( + goalService.softDelete( goal = goal, userEntity = userService.loadById(userId).fromDto(), ) diff --git a/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/UserApplicationService.kt b/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/UserApplicationService.kt index 03818ca..5f96f1e 100644 --- a/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/UserApplicationService.kt +++ b/raisedragon-api/src/main/kotlin/com/whatever/raisedragon/applicationservice/UserApplicationService.kt @@ -1,7 +1,14 @@ package com.whatever.raisedragon.applicationservice +import com.whatever.raisedragon.common.exception.BaseException +import com.whatever.raisedragon.common.exception.ExceptionCode import com.whatever.raisedragon.controller.user.UserNicknameDuplicatedResponse import com.whatever.raisedragon.controller.user.UserRetrieveResponse +import com.whatever.raisedragon.domain.betting.BettingService +import com.whatever.raisedragon.domain.gifticon.GifticonService +import com.whatever.raisedragon.domain.goal.GoalService +import com.whatever.raisedragon.domain.goalproof.GoalProofService +import com.whatever.raisedragon.domain.refreshtoken.RefreshTokenService import com.whatever.raisedragon.domain.user.UserService import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -9,7 +16,12 @@ import org.springframework.transaction.annotation.Transactional @Service @Transactional(readOnly = true) class UserApplicationService( - private val userService: UserService + private val userService: UserService, + private val refreshTokenService: RefreshTokenService, + private val goalService: GoalService, + private val goalProofService: GoalProofService, + private val gifticonService: GifticonService, + private val bettingService: BettingService, ) { fun retrieve(id: Long): UserRetrieveResponse { @@ -31,8 +43,21 @@ class UserApplicationService( ) } + @Transactional fun delete(id: Long) { - userService.softDelete(id) + val user = userService.loadById(id) + if (goalService.findProceedingGoalIsExistsByUser(user)) { + throw BaseException.of( + exceptionCode = ExceptionCode.E400_BAD_REQUEST, + executionMessage = "아직 진행중인 다짐이 있어 회원탈퇴에 실패했습니다." + ) + } + userService.hardDelete(id) + refreshTokenService.hardDelete(user) + goalService.hardDelete(user) + goalProofService.hardDelete(user) + gifticonService.hardDelete(user) + bettingService.hardDelete(user) } fun isNicknameDuplicated( diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/betting/BettingService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/betting/BettingService.kt index f3942ed..daefcb1 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/betting/BettingService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/betting/BettingService.kt @@ -1,7 +1,9 @@ package com.whatever.raisedragon.domain.betting import com.whatever.raisedragon.domain.goal.GoalRepository +import com.whatever.raisedragon.domain.user.User import com.whatever.raisedragon.domain.user.UserRepository +import com.whatever.raisedragon.domain.user.fromDto import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -97,4 +99,10 @@ class BettingService( ?: throw IllegalStateException("Cannot find betting $bettingId") betting.deletedAt = LocalDateTime.now() } + + @Transactional + fun hardDelete(user: User) { + val bettings = bettingRepository.findAllByUserEntity(user.fromDto()) + bettingRepository.deleteAll(bettings) + } } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonRepository.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonRepository.kt index 2960b02..6c48274 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonRepository.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonRepository.kt @@ -1,7 +1,10 @@ package com.whatever.raisedragon.domain.gifticon +import com.whatever.raisedragon.domain.user.UserEntity import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository @Repository -interface GifticonRepository : JpaRepository \ No newline at end of file +interface GifticonRepository : JpaRepository { + fun findAllByUserEntity(userEntity: UserEntity): List +} \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonService.kt index b176916..d1ae56a 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/gifticon/GifticonService.kt @@ -1,16 +1,19 @@ package com.whatever.raisedragon.domain.gifticon +import com.whatever.raisedragon.domain.user.User import com.whatever.raisedragon.domain.user.UserRepository +import com.whatever.raisedragon.domain.user.fromDto import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -@Transactional +@Transactional(readOnly = true) @Service class GifticonService( private val gifticonRepository: GifticonRepository, private val userRepository: UserRepository ) { + @Transactional fun create( userId: Long, url: String, @@ -27,4 +30,10 @@ class GifticonService( fun loadById(gifticonId: Long): Gifticon { return gifticonRepository.findById(gifticonId).get().toDto() } + + @Transactional + fun hardDelete(user: User) { + val gifticons = gifticonRepository.findAllByUserEntity(user.fromDto()) + gifticonRepository.deleteAll(gifticons) + } } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalRepository.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalRepository.kt index 1a97a17..c064a57 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalRepository.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalRepository.kt @@ -14,4 +14,5 @@ interface GoalRepository : JpaRepository { fun findAllByEndDateLessThanEqualAndResultIs(endDate: LocalDateTime, result: Result): List fun findAllByUserEntityAndResult(userEntity: UserEntity, result: Result): List + fun existsByUserEntityAndEndDateIsAfter(userEntity: UserEntity, now: LocalDateTime): Boolean } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalService.kt index 33ff88c..db57d82 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goal/GoalService.kt @@ -1,7 +1,9 @@ package com.whatever.raisedragon.domain.goal +import com.whatever.raisedragon.domain.user.User import com.whatever.raisedragon.domain.user.UserEntity import com.whatever.raisedragon.domain.user.UserRepository +import com.whatever.raisedragon.domain.user.fromDto import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -83,7 +85,7 @@ class GoalService( } @Transactional - fun delete( + fun softDelete( goal: Goal, userEntity: UserEntity, ): Goal { @@ -93,8 +95,19 @@ class GoalService( return goalEntity.toDto() } + @Transactional + fun hardDelete(user: User) { + val goals = goalRepository.findAllByUserEntity(user.fromDto()) + goalRepository.deleteAll(goals) + } + + @Transactional fun increaseThreshold(goal: Goal, userEntity: UserEntity) { val goalEntity = goal.fromDto(userEntity) goalEntity.threshold = Threshold(goalEntity.threshold.value + 1) } + + fun findProceedingGoalIsExistsByUser(user: User): Boolean { + return goalRepository.existsByUserEntityAndEndDateIsAfter(user.fromDto(), LocalDateTime.now()) + } } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofRepository.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofRepository.kt index 9f452df..e8187ab 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofRepository.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofRepository.kt @@ -9,5 +9,7 @@ import org.springframework.stereotype.Repository interface GoalProofRepository : JpaRepository { fun findAllByUserEntityAndGoalEntity(userEntity: UserEntity, goalEntity: GoalEntity): List + fun findAllByUserEntity(userEntity: UserEntity): List + fun countAllByGoalEntity(goalEntity: GoalEntity): Int } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofService.kt index 3642d29..512a465 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/goalproof/GoalProofService.kt @@ -64,4 +64,10 @@ class GoalProofService( comment?.let { goalProof.comment = it } return goalProof.toDto() } + + @Transactional + fun hardDelete(user: User) { + val goalProofs = goalProofRepository.findAllByUserEntity(user.fromDto()) + goalProofRepository.deleteAll(goalProofs) + } } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/refreshtoken/RefreshTokenService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/refreshtoken/RefreshTokenService.kt index f6fef12..829e36a 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/refreshtoken/RefreshTokenService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/refreshtoken/RefreshTokenService.kt @@ -29,4 +29,10 @@ class RefreshTokenService( fun updatePayloadByVo(refreshToken: RefreshToken, userEntity: UserEntity) { val refreshTokenEntity = refreshToken.fromDto(userEntity) } + + @Transactional + fun hardDelete(user: User) { + val refreshTokenEntity = refreshTokenRepository.findByUserEntity(user.fromDto())!! + refreshTokenRepository.delete(refreshTokenEntity) + } } \ No newline at end of file diff --git a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/user/UserService.kt b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/user/UserService.kt index 7370724..5582c6b 100644 --- a/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/user/UserService.kt +++ b/raisedragon-core/src/main/kotlin/com/whatever/raisedragon/domain/user/UserService.kt @@ -44,6 +44,12 @@ class UserService( userEntity.disable() } + @Transactional + fun hardDelete(id: Long) { + val userEntity = loadById(id).fromDto() + userRepository.delete(userEntity) + } + @Transactional fun convertBySoftDeleteToEntity(id: Long) { val userEntity = loadById(id).fromDto()