diff --git a/src/main/java/com/back/domain/mybar/controller/MyBarController.java b/src/main/java/com/back/domain/mybar/controller/MyBarController.java index 808dbb7..8950047 100644 --- a/src/main/java/com/back/domain/mybar/controller/MyBarController.java +++ b/src/main/java/com/back/domain/mybar/controller/MyBarController.java @@ -77,5 +77,15 @@ public RsData unkeep( myBarService.unkeep(userId, cocktailId); return RsData.of(200, "deleted"); } + + @DeleteMapping + @Operation(summary = "내 바 전체 삭제", description = "내 바에 담긴 모든 칵테일을 소프트 삭제합니다") + public RsData clearAll( + @AuthenticationPrincipal SecurityUser principal + ) { + Long userId = principal.getId(); + myBarService.clearAll(userId); + return RsData.of(200, "cleared"); + } } diff --git a/src/main/java/com/back/domain/mybar/repository/MyBarRepository.java b/src/main/java/com/back/domain/mybar/repository/MyBarRepository.java index f4c858b..0b26188 100644 --- a/src/main/java/com/back/domain/mybar/repository/MyBarRepository.java +++ b/src/main/java/com/back/domain/mybar/repository/MyBarRepository.java @@ -38,6 +38,15 @@ public interface MyBarRepository extends JpaRepository { /** 복원/재킵을 위해 status 무시하고 한 건 찾기 (없으면 Optional.empty) */ Optional findByUser_IdAndCocktail_Id(Long userId, Long cocktailId); + @Modifying(clearAutomatically = true, flushAutomatically = true) + @Query(""" + update MyBar m + set m.status = 'DELETED', m.deletedAt = CURRENT_TIMESTAMP + where m.user.id = :userId + and m.status = 'ACTIVE' + """) + int softDeleteAllByUser(Long userId); + @Modifying(clearAutomatically = true, flushAutomatically = true) @Query(""" update MyBar m diff --git a/src/main/java/com/back/domain/mybar/service/MyBarService.java b/src/main/java/com/back/domain/mybar/service/MyBarService.java index 6f7ced4..eb56991 100644 --- a/src/main/java/com/back/domain/mybar/service/MyBarService.java +++ b/src/main/java/com/back/domain/mybar/service/MyBarService.java @@ -123,5 +123,13 @@ public void unkeep(Long userId, Long cocktailId) { abvScoreService.revokeForKeep(userId); } } + + @Transactional + public void clearAll(Long userId) { + int changed = myBarRepository.softDeleteAllByUser(userId); + if (changed > 0) { + abvScoreService.revokeForKeep(userId, changed); + } + } } diff --git a/src/main/java/com/back/domain/user/service/AbvScoreService.java b/src/main/java/com/back/domain/user/service/AbvScoreService.java index ec66e02..48039c7 100644 --- a/src/main/java/com/back/domain/user/service/AbvScoreService.java +++ b/src/main/java/com/back/domain/user/service/AbvScoreService.java @@ -58,6 +58,14 @@ public void revokeForKeep(Long userId) { addScore(userId, -KEEP_SCORE); } + @Transactional + public void revokeForKeep(Long userId, int count) { + if (count <= 0) { + return; + } + addScore(userId, -KEEP_SCORE * count); + } + private void addScore(Long userId, double delta) { User user = userRepository.findById(userId) .orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다.")); diff --git a/src/test/java/com/back/domain/mybar/controller/MyBarControllerTest.java b/src/test/java/com/back/domain/mybar/controller/MyBarControllerTest.java index 8c1a885..2a9f8c4 100644 --- a/src/test/java/com/back/domain/mybar/controller/MyBarControllerTest.java +++ b/src/test/java/com/back/domain/mybar/controller/MyBarControllerTest.java @@ -220,4 +220,22 @@ void unkeepCocktail() throws Exception { verify(myBarService).unkeep(principal.getId(), cocktailId); } + + @Test + @DisplayName("Clear entire my bar") + void clearAllMyBar() throws Exception { + SecurityUser principal = createPrincipal(21L); + + willDoNothing().given(myBarService).clearAll(principal.getId()); + + mockMvc.perform(delete("/me/bar") + .with(withPrincipal(principal)) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.message").value("cleared")) + .andExpect(jsonPath("$.data").doesNotExist()); + + verify(myBarService).clearAll(principal.getId()); + } }