diff --git a/src/main/java/com/irum/come2us/domain/category/application/service/CategoryService.java b/src/main/java/com/irum/come2us/domain/category/application/service/CategoryService.java index d0d706e0..bbcb2957 100644 --- a/src/main/java/com/irum/come2us/domain/category/application/service/CategoryService.java +++ b/src/main/java/com/irum/come2us/domain/category/application/service/CategoryService.java @@ -3,6 +3,8 @@ import com.irum.come2us.domain.category.domain.entity.Category; import com.irum.come2us.domain.category.domain.repository.CategoryRepository; import com.irum.come2us.domain.category.presentation.dto.request.CategoryCreateRequest; +import com.irum.come2us.domain.category.presentation.dto.request.CategoryUpdateRequest; +import com.irum.come2us.domain.category.presentation.dto.response.CategoryInfoResponse; import com.irum.come2us.domain.category.presentation.dto.response.CategoryResponse; import com.irum.come2us.global.presentation.advice.exception.CommonException; import com.irum.come2us.global.presentation.advice.exception.errorcode.CategoryErrorCode; @@ -20,15 +22,20 @@ public class CategoryService { private final CategoryRepository categoryRepository; - // ------------------- 전체 조회 ------------------- @Transactional(readOnly = true) - public List findAllCategories() { - return categoryRepository.findAll().stream() - .map(CategoryResponse::fromEntity) - .collect(Collectors.toList()); + public List findRootCategories() { + return categoryRepository.findByParentIsNull().stream() + .map(CategoryInfoResponse::from) + .toList(); + } + + @Transactional(readOnly = true) + public List findByParentId(UUID parentId) { + return categoryRepository.findChildrenByParentId(parentId).stream() + .map(CategoryInfoResponse::from) + .toList(); } - // ------------------- 단일 조회 ------------------- @Transactional(readOnly = true) public CategoryResponse getCategoryById(UUID id) { Category category = @@ -39,7 +46,6 @@ public CategoryResponse getCategoryById(UUID id) { return CategoryResponse.fromEntity(category); } - // ------------------- 트리 조회 ------------------- @Transactional(readOnly = true) public List findCategoryTree() { List roots = categoryRepository.findByParentIsNull(); @@ -48,7 +54,6 @@ public List findCategoryTree() { .collect(Collectors.toList()); } - // ------------------- 생성 ------------------- public CategoryResponse createCategory(CategoryCreateRequest request) { Category category; @@ -69,18 +74,16 @@ public CategoryResponse createCategory(CategoryCreateRequest request) { return CategoryResponse.fromEntity(saved); } - // ------------------- 수정 ------------------- - public CategoryResponse updateCategory(UUID id, String newName) { + public CategoryResponse updateCategory(UUID id, CategoryUpdateRequest request) { Category category = categoryRepository .findById(id) .orElseThrow( () -> new CommonException(CategoryErrorCode.CATEGORY_NOT_FOUND)); - category.updateName(newName); + category.updateName(request.name()); return CategoryResponse.fromEntity(category); } - // ------------------- 삭제 ------------------- public void deleteCategory(UUID id) { Category category = categoryRepository diff --git a/src/main/java/com/irum/come2us/domain/category/domain/entity/Category.java b/src/main/java/com/irum/come2us/domain/category/domain/entity/Category.java index 3034bca8..7b551341 100644 --- a/src/main/java/com/irum/come2us/domain/category/domain/entity/Category.java +++ b/src/main/java/com/irum/come2us/domain/category/domain/entity/Category.java @@ -1,5 +1,6 @@ package com.irum.come2us.domain.category.domain.entity; +import com.irum.come2us.global.domain.BaseEntity; import com.irum.come2us.global.presentation.advice.exception.CommonException; import com.irum.come2us.global.presentation.advice.exception.errorcode.CategoryErrorCode; import jakarta.persistence.*; @@ -15,7 +16,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) @Builder(access = AccessLevel.PRIVATE) -public class Category { +public class Category extends BaseEntity { private static final int MAX_DEPTH = 3; @@ -37,7 +38,6 @@ public class Category { @Column(name = "depth", nullable = false) private int depth; - // ------------------- 생성 메서드 ------------------- public static Category createRootCategory(String name) { return Category.builder().name(name).depth(1).build(); } @@ -58,7 +58,6 @@ private void addChild(Category child) { this.children.add(child); } - // ------------------- 수정 메서드 ------------------- public void updateName(String name) { this.name = name; } diff --git a/src/main/java/com/irum/come2us/domain/category/domain/repository/CategoryRepository.java b/src/main/java/com/irum/come2us/domain/category/domain/repository/CategoryRepository.java index 817c6ea2..2f50cb44 100644 --- a/src/main/java/com/irum/come2us/domain/category/domain/repository/CategoryRepository.java +++ b/src/main/java/com/irum/come2us/domain/category/domain/repository/CategoryRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.repository.query.Param; public interface CategoryRepository extends JpaRepository { - List findByParentIsNull(); // 루트 카테고리 조회 + List findByParentIsNull(); @Query("SELECT c FROM Category c WHERE c.parent.categoryId = :parentId") List findChildrenByParentId(@Param("parentId") UUID parentId); diff --git a/src/main/java/com/irum/come2us/domain/category/presentation/controller/CategoryController.java b/src/main/java/com/irum/come2us/domain/category/presentation/controller/CategoryController.java index 863a3b01..9685ae08 100644 --- a/src/main/java/com/irum/come2us/domain/category/presentation/controller/CategoryController.java +++ b/src/main/java/com/irum/come2us/domain/category/presentation/controller/CategoryController.java @@ -2,9 +2,11 @@ import com.irum.come2us.domain.category.application.service.CategoryService; import com.irum.come2us.domain.category.presentation.dto.request.CategoryCreateRequest; +import com.irum.come2us.domain.category.presentation.dto.request.CategoryUpdateRequest; +import com.irum.come2us.domain.category.presentation.dto.response.CategoryInfoResponse; import com.irum.come2us.domain.category.presentation.dto.response.CategoryResponse; +import jakarta.validation.Valid; import java.util.List; -import java.util.Map; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -16,38 +18,36 @@ public class CategoryController { private final CategoryService categoryService; - // ------------------- 전체 조회 ------------------- @GetMapping - public List getAllCategories() { - return categoryService.findAllCategories(); + public List getAllCategories( + @RequestParam(required = false) UUID parentId) { + if (parentId != null) { + return categoryService.findByParentId(parentId); + } + return categoryService.findRootCategories(); } - // ------------------- 단일 조회 ------------------- @GetMapping("/{id}") public CategoryResponse getCategoryById(@PathVariable UUID id) { return categoryService.getCategoryById(id); } - // ------------------- 트리 조회 ------------------- @GetMapping("/tree") public List getCategoryTree() { return categoryService.findCategoryTree(); } - // ------------------- 생성 ------------------- @PostMapping - public CategoryResponse createCategory(@RequestBody CategoryCreateRequest request) { + public CategoryResponse createCategory(@Valid @RequestBody CategoryCreateRequest request) { return categoryService.createCategory(request); } - // ------------------- 수정 ------------------- @PatchMapping("/{id}") public CategoryResponse updateCategory( - @PathVariable UUID id, @RequestBody Map request) { - return categoryService.updateCategory(id, request.get("name")); + @PathVariable UUID id, @Valid @RequestBody CategoryUpdateRequest request) { + return categoryService.updateCategory(id, request); } - // ------------------- 삭제 ------------------- @DeleteMapping("/{id}") public void deleteCategory(@PathVariable UUID id) { categoryService.deleteCategory(id); diff --git a/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryCreateRequest.java b/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryCreateRequest.java index fb552c54..9bbcedd0 100644 --- a/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryCreateRequest.java +++ b/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryCreateRequest.java @@ -1,6 +1,8 @@ package com.irum.come2us.domain.category.presentation.dto.request; +import jakarta.validation.constraints.NotBlank; import java.util.UUID; -public record CategoryCreateRequest(String name, UUID parentId // null이면 루트 카테고리 +public record CategoryCreateRequest( + @NotBlank(message = "카테고리명은 필수 입력값입니다.") String name, UUID parentId // null이면 루트 카테고리 ) {} diff --git a/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryUpdateRequest.java b/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryUpdateRequest.java new file mode 100644 index 00000000..393391a5 --- /dev/null +++ b/src/main/java/com/irum/come2us/domain/category/presentation/dto/request/CategoryUpdateRequest.java @@ -0,0 +1,5 @@ +package com.irum.come2us.domain.category.presentation.dto.request; + +import jakarta.validation.constraints.NotBlank; + +public record CategoryUpdateRequest(@NotBlank(message = "카테고리명은 필수 입력값입니다.") String name) {} diff --git a/src/main/java/com/irum/come2us/domain/category/presentation/dto/response/CategoryResponse.java b/src/main/java/com/irum/come2us/domain/category/presentation/dto/response/CategoryResponse.java index 67eb5dfc..af52a324 100644 --- a/src/main/java/com/irum/come2us/domain/category/presentation/dto/response/CategoryResponse.java +++ b/src/main/java/com/irum/come2us/domain/category/presentation/dto/response/CategoryResponse.java @@ -11,7 +11,6 @@ public record CategoryResponse( UUID parentId, List children // 트리 조회용 ) { - // ------------------- 단일 조회용 ------------------- public static CategoryResponse fromEntity(Category category) { return new CategoryResponse( category.getCategoryId(), @@ -21,7 +20,6 @@ public static CategoryResponse fromEntity(Category category) { null); } - // ------------------- 트리 조회용 ------------------- public static CategoryResponse fromEntityWithChildren(Category category) { return new CategoryResponse( category.getCategoryId(),