From 66949a15c6c816108a9da3cb22f1e9e3595cdaaa Mon Sep 17 00:00:00 2001 From: Ahn Su-gyeong Date: Wed, 5 Jun 2024 15:27:56 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Feature:=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scrap/business/CategoryFacade.java | 4 +++ .../implement/CategoryCommandService.java | 2 ++ .../implement/CategoryCommandServiceImpl.java | 25 +++++++++++++++++++ .../presentation/CategoryController.java | 22 ++++++++++++++-- .../custom/CategoryAccessDeniedException.java | 18 +++++++++++++ .../DefaultCategoryAccessDeniedException.java | 18 +++++++++++++ .../zzangdol/response/status/ErrorStatus.java | 4 ++- 7 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 moodoodle-common/src/main/java/zzangdol/exception/custom/CategoryAccessDeniedException.java create mode 100644 moodoodle-common/src/main/java/zzangdol/exception/custom/DefaultCategoryAccessDeniedException.java diff --git a/moodoodle-api/src/main/java/zzangdol/scrap/business/CategoryFacade.java b/moodoodle-api/src/main/java/zzangdol/scrap/business/CategoryFacade.java index 7d1d5fa..aeef987 100644 --- a/moodoodle-api/src/main/java/zzangdol/scrap/business/CategoryFacade.java +++ b/moodoodle-api/src/main/java/zzangdol/scrap/business/CategoryFacade.java @@ -40,4 +40,8 @@ public CategoryDiaryListResponse getDiariesByCategory(User user, Long categoryId List diariesByCategory = categoryQueryService.getDiariesByCategory(user, categoryId); return DiaryMapper.toCategoryDiaryListResponse(diariesByCategory); } + + public void deleteCategory(User user, Long categoryId) { + categoryCommandService.deleteCategory(user, categoryId); + } } \ No newline at end of file diff --git a/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandService.java b/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandService.java index 4d5a266..9902e45 100644 --- a/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandService.java +++ b/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandService.java @@ -8,4 +8,6 @@ public interface CategoryCommandService { Category createCategory(User user, CategoryCreateRequest request); + void deleteCategory(User user, Long categoryId); + } diff --git a/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandServiceImpl.java b/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandServiceImpl.java index 42dd47f..e76f6d9 100644 --- a/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandServiceImpl.java +++ b/moodoodle-api/src/main/java/zzangdol/scrap/implement/CategoryCommandServiceImpl.java @@ -4,6 +4,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import zzangdol.constant.Constants; +import zzangdol.exception.custom.CategoryAccessDeniedException; +import zzangdol.exception.custom.CategoryNotFoundException; +import zzangdol.exception.custom.DefaultCategoryAccessDeniedException; import zzangdol.scrap.dao.CategoryRepository; import zzangdol.scrap.domain.Category; import zzangdol.scrap.presentation.dto.request.CategoryCreateRequest; @@ -23,6 +27,27 @@ public Category createCategory(User user, CategoryCreateRequest request) { return categoryRepository.save(category); } + @Override + public void deleteCategory(User user, Long categoryId) { + Category category = categoryRepository.findById(categoryId) + .orElseThrow(() -> CategoryNotFoundException.EXCEPTION); + checkCategoryOwnership(user, category); + checkDefaultCategory(category); + categoryRepository.deleteById(categoryId); + } + + private void checkDefaultCategory(Category category) { + if (category.getName().equals(Constants.DEFAULT_CATEGORY_NAME)) { + throw DefaultCategoryAccessDeniedException.EXCEPTION; + } + } + + private void checkCategoryOwnership(User user, Category category) { + if (!category.getUser().getId().equals(user.getId())) { + throw CategoryAccessDeniedException.EXCEPTION; + } + } + private Category buildCategory(CategoryCreateRequest request, User user) { return Category.builder() .name(request.getName()) diff --git a/moodoodle-api/src/main/java/zzangdol/scrap/presentation/CategoryController.java b/moodoodle-api/src/main/java/zzangdol/scrap/presentation/CategoryController.java index 06b41cd..87056ff 100644 --- a/moodoodle-api/src/main/java/zzangdol/scrap/presentation/CategoryController.java +++ b/moodoodle-api/src/main/java/zzangdol/scrap/presentation/CategoryController.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -66,7 +67,8 @@ public ResponseDto getCategoriesByUser(@AuthUser User user description = "사용자의 카테고리 목록을 반환합니다. 카테고리가 존재하지 않으면 빈 리스트를 반환합니다." ) @GetMapping("/scraps") - public ResponseDto getScrapCategoriesByUser(@AuthUser User user, @RequestParam Long diaryId) { + public ResponseDto getScrapCategoriesByUser(@AuthUser User user, + @RequestParam Long diaryId) { return ResponseDto.onSuccess(categoryFacade.getScrapCategoriesByUser(user, diaryId)); } @@ -79,8 +81,24 @@ public ResponseDto getScrapCategoriesByUser(@AuthUser description = "특정 스크랩 카테고리에 속한 일기 목록을 조회합니다." ) @GetMapping("/{categoryId}/diaries") - public ResponseDto getDiariesByCategory(@AuthUser User user, @PathVariable("categoryId") Long categoryId) { + public ResponseDto getDiariesByCategory(@AuthUser User user, + @PathVariable("categoryId") Long categoryId) { return ResponseDto.onSuccess(categoryFacade.getDiariesByCategory(user, categoryId)); } + @ApiErrorCodeExample({ + ErrorStatus.CATEGORY_NOT_FOUND, + ErrorStatus.INTERNAL_SERVER_ERROR + }) + @Operation( + summary = "카테고리 삭제 🔑", + description = "지정된 ID의 카테고리를 삭제합니다. 삭제 성공 시 true를 반환합니다." + ) + @DeleteMapping("/{categoryId}") + public ResponseDto deleteCategory(@AuthUser User user, + @PathVariable("categoryId") Long categoryId) { + categoryFacade.deleteCategory(user, categoryId); + return ResponseDto.onSuccess(true); + } + } diff --git a/moodoodle-common/src/main/java/zzangdol/exception/custom/CategoryAccessDeniedException.java b/moodoodle-common/src/main/java/zzangdol/exception/custom/CategoryAccessDeniedException.java new file mode 100644 index 0000000..5ab50f6 --- /dev/null +++ b/moodoodle-common/src/main/java/zzangdol/exception/custom/CategoryAccessDeniedException.java @@ -0,0 +1,18 @@ +package zzangdol.exception.custom; + +import zzangdol.exception.GeneralException; +import zzangdol.response.status.ErrorStatus; + +public class CategoryAccessDeniedException extends GeneralException { + + public static final GeneralException EXCEPTION = new CategoryAccessDeniedException(); + + public CategoryAccessDeniedException() { + super(ErrorStatus.CATEGORY_ACCESS_DENIED); + } + + public CategoryAccessDeniedException(ErrorStatus errorStatus) { + super(errorStatus); + } + +} diff --git a/moodoodle-common/src/main/java/zzangdol/exception/custom/DefaultCategoryAccessDeniedException.java b/moodoodle-common/src/main/java/zzangdol/exception/custom/DefaultCategoryAccessDeniedException.java new file mode 100644 index 0000000..8cb61f3 --- /dev/null +++ b/moodoodle-common/src/main/java/zzangdol/exception/custom/DefaultCategoryAccessDeniedException.java @@ -0,0 +1,18 @@ +package zzangdol.exception.custom; + +import zzangdol.exception.GeneralException; +import zzangdol.response.status.ErrorStatus; + +public class DefaultCategoryAccessDeniedException extends GeneralException { + + public static final GeneralException EXCEPTION = new DefaultCategoryAccessDeniedException(); + + public DefaultCategoryAccessDeniedException() { + super(ErrorStatus.DEFAULT_CATEGORY_ACCESS_DENIED); + } + + public DefaultCategoryAccessDeniedException(ErrorStatus errorStatus) { + super(errorStatus); + } + +} diff --git a/moodoodle-common/src/main/java/zzangdol/response/status/ErrorStatus.java b/moodoodle-common/src/main/java/zzangdol/response/status/ErrorStatus.java index bdb6a73..9381912 100644 --- a/moodoodle-common/src/main/java/zzangdol/response/status/ErrorStatus.java +++ b/moodoodle-common/src/main/java/zzangdol/response/status/ErrorStatus.java @@ -43,7 +43,9 @@ public enum ErrorStatus implements BaseStatus { // Scrap (4200 ~ 4250) SCRAP_NOT_FOUND(HttpStatus.NOT_FOUND, 4200, "스크랩이 존재하지 않습니다."), CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, 4201, "카테고리가 존재하지 않습니다."), - SCRAP_DUPLICATION(HttpStatus.CONFLICT, 4202, "해당 사용자와 다이어리에 대해 이미 스크랩이 존재합니다."); + SCRAP_DUPLICATION(HttpStatus.CONFLICT, 4202, "해당 사용자와 다이어리에 대해 이미 스크랩이 존재합니다."), + CATEGORY_ACCESS_DENIED(HttpStatus.FORBIDDEN, 4203, "카테고리 접근이 거부되었습니다."), + DEFAULT_CATEGORY_ACCESS_DENIED(HttpStatus.FORBIDDEN, 4204, "기본 카테고리 접근이 거부되었습니다."); private final HttpStatus httpStatus; private final int code;