Skip to content

Commit 67672ec

Browse files
CLAP-128 Feature : 2차 카테고리 추가 API
* CLAP-104 CI/CD : dev 환경 cd 스크립트 checkout 버전수정 <footer> - 관련: #55 * CLAP-110 Feature : 담당자별 작업 처리량 조회 API 구현 <footer> - 관련: #73 * CLAP-111 Refactor : 통계 조회 API 리팩토링 및 기능 수정 <footer> - 관련: #74 * 내 작업한 내용에 대한 설명 * 내 작업한 내용에 대한 설명 * 담당자 조회 API 구현 * CLAP-111 Refactor : 통계 조회 API 주소 통합, 리팩토링, 예외처리 <footer> - 관련: #74 * CLAP-111 Test : 테스트코드 및 설정 수정 <footer> - 관련: #74 * Bug : 프로퍼티파일 수정 * CLAP-128 Feature : 2차 카테고리 추가 API <footer> - 관련: #95
1 parent 9082009 commit 67672ec

File tree

6 files changed

+165
-14
lines changed

6 files changed

+165
-14
lines changed

src/main/java/clap/server/adapter/inbound/web/admin/addCategoryController.java renamed to src/main/java/clap/server/adapter/inbound/web/admin/AddCategoryController.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
package clap.server.adapter.inbound.web.admin;
22

33
import clap.server.adapter.inbound.security.SecurityUserDetails;
4+
import clap.server.adapter.inbound.web.dto.AddSubCategoryRequest;
45
import clap.server.adapter.inbound.web.dto.admin.AddMainCategoryRequest;
56
import clap.server.application.port.inbound.management.AddMainCategoryUsecase;
7+
import clap.server.application.port.inbound.management.AddSubCategoryUsecase;
68
import clap.server.common.annotation.architecture.WebAdapter;
79
import io.swagger.v3.oas.annotations.Operation;
810
import io.swagger.v3.oas.annotations.tags.Tag;
11+
import jakarta.validation.Valid;
912
import lombok.RequiredArgsConstructor;
1013
import org.springframework.security.access.annotation.Secured;
1114
import org.springframework.security.core.annotation.AuthenticationPrincipal;
12-
import org.springframework.validation.annotation.Validated;
1315
import org.springframework.web.bind.annotation.PostMapping;
1416
import org.springframework.web.bind.annotation.RequestBody;
1517

1618
@Tag(name = "카테고리 추가")
1719
@WebAdapter
1820
@RequiredArgsConstructor
19-
public class addCategoryController {
21+
public class AddCategoryController {
2022
private final AddMainCategoryUsecase addMainCategoryUsecase;
23+
private final AddSubCategoryUsecase addSubCategoryUsecase;
2124

2225
@Operation(summary = "1차 카테고리 추가")
2326
@PostMapping("/api/maincategory")
2427
@Secured("ROLE_ADMIN")
25-
public void addMainCategory(@AuthenticationPrincipal SecurityUserDetails userInfo, @Validated @RequestBody AddMainCategoryRequest addMainCategoryRequest) {
28+
public void addMainCategory(@AuthenticationPrincipal SecurityUserDetails userInfo, @Valid @RequestBody AddMainCategoryRequest addMainCategoryRequest) {
2629
addMainCategoryUsecase.addMainCategory(userInfo.getUserId(), addMainCategoryRequest.code(), addMainCategoryRequest.name());
2730
}
2831

29-
// @Operation(summary = "2차 카테고리 추가")
30-
// @PostMapping("/api/subcategory")
31-
// @Secured("ROLE_ADMIN")
32-
// public void addSubCategory(@Validated @RequestBody AddCategoryRequest addCategoryRequest) {
33-
// addMainCategoryUsecase.addSubCategory(addCategoryRequest.code(), addCategoryRequest.name());
34-
// }
32+
@Operation(summary = "2차 카테고리 추가")
33+
@PostMapping("/api/subcategory")
34+
@Secured("ROLE_ADMIN")
35+
public void addSubCategory(@AuthenticationPrincipal SecurityUserDetails userInfo, @Valid @RequestBody AddSubCategoryRequest addCategoryRequest) {
36+
addSubCategoryUsecase.addSubCategory(userInfo.getUserId(), addCategoryRequest.mainCategoryId(), addCategoryRequest.code(), addCategoryRequest.name());
37+
}
3538

3639
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package clap.server.adapter.inbound.web.dto;
2+
3+
import jakarta.validation.constraints.Min;
4+
import jakarta.validation.constraints.NotBlank;
5+
import jakarta.validation.constraints.Pattern;
6+
import org.hibernate.validator.constraints.Length;
7+
8+
public record AddSubCategoryRequest(
9+
@Min(1)
10+
Long mainCategoryId,
11+
@NotBlank @Length(max = 20)
12+
String name,
13+
@NotBlank @Pattern(regexp = "^[A-Z]{1,2}$", message = "올바른 카테고리 코드 형식이 아닙니다.")
14+
String code) {
15+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package clap.server.application.port.inbound.management;
2+
3+
4+
public interface AddSubCategoryUsecase {
5+
void addSubCategory(Long adminId, Long mainCategoryId, String code, String name);
6+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package clap.server.application.service.admin;
2+
3+
import clap.server.application.port.inbound.management.AddSubCategoryUsecase;
4+
import clap.server.application.port.outbound.member.LoadMemberPort;
5+
import clap.server.application.port.outbound.task.CommandCategoryPort;
6+
import clap.server.application.port.outbound.task.LoadCategoryPort;
7+
import clap.server.common.annotation.architecture.ApplicationService;
8+
import clap.server.domain.model.member.Member;
9+
import clap.server.domain.model.task.Category;
10+
import clap.server.exception.ApplicationException;
11+
import lombok.RequiredArgsConstructor;
12+
13+
import java.util.Optional;
14+
15+
import static clap.server.exception.code.MemberErrorCode.ACTIVE_MEMBER_NOT_FOUND;
16+
import static clap.server.exception.code.TaskErrorCode.CATEGORY_NOT_FOUND;
17+
18+
@ApplicationService
19+
@RequiredArgsConstructor
20+
public class AddSubCategoryService implements AddSubCategoryUsecase {
21+
private final CommandCategoryPort commandCategoryPort;
22+
private final LoadMemberPort loadMemberPort;
23+
private final LoadCategoryPort loadCategoryPort;
24+
25+
@Override
26+
public void addSubCategory(Long adminId, Long mainCategoryId, String code, String name) {
27+
Optional<Member> activeMember = loadMemberPort.findActiveMemberById(adminId);
28+
Optional<Category> mainCategory = loadCategoryPort.findById(mainCategoryId);
29+
30+
Category subCategory = Category.createSubCategory(
31+
activeMember.orElseThrow(() -> new ApplicationException(ACTIVE_MEMBER_NOT_FOUND)),
32+
mainCategory.orElseThrow(() -> new ApplicationException(CATEGORY_NOT_FOUND)),
33+
code, name);
34+
commandCategoryPort.save(subCategory);
35+
}
36+
}

src/main/java/clap/server/domain/model/task/Category.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,20 @@ public class Category extends BaseTime {
2424
private LocalDateTime updatedAt;
2525

2626
public static Category createMainCategory(Member admin, String code, String name) {
27-
Category category = new Category();
28-
category.admin = admin;
29-
category.code = code;
30-
category.name = name;
31-
return category;
27+
return Category.builder()
28+
.admin(admin)
29+
.code(code)
30+
.name(name)
31+
.build();
32+
}
33+
34+
public static Category createSubCategory(Member admin, Category mainCategory, String code, String name) {
35+
return Category.builder()
36+
.mainCategory(mainCategory)
37+
.admin(admin)
38+
.code(code)
39+
.name(name)
40+
.build();
3241
}
3342
}
3443

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package clap.server.application.service.admin;
2+
3+
import clap.server.adapter.outbound.persistense.entity.member.MemberEntity;
4+
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole;
5+
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
6+
import clap.server.adapter.outbound.persistense.entity.task.CategoryEntity;
7+
import jakarta.persistence.EntityManager;
8+
import jakarta.transaction.Transactional;
9+
import org.junit.jupiter.api.Test;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.boot.test.context.SpringBootTest;
12+
import org.springframework.test.annotation.Rollback;
13+
import org.springframework.test.context.DynamicPropertyRegistry;
14+
import org.springframework.test.context.DynamicPropertySource;
15+
import org.testcontainers.elasticsearch.ElasticsearchContainer;
16+
import org.testcontainers.junit.jupiter.Container;
17+
import org.testcontainers.junit.jupiter.Testcontainers;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
@SpringBootTest
22+
@Testcontainers
23+
@Transactional
24+
class AddCategoryServiceTest {
25+
26+
@Container
27+
public static ElasticsearchContainer ES_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:7.17.5")
28+
.withReuse(true);
29+
30+
@DynamicPropertySource
31+
static void elasticProperties(DynamicPropertyRegistry registry) {
32+
// Elasticsearch 설정
33+
registry.add("spring.elasticsearch.uris", ES_CONTAINER::getHttpHostAddress);
34+
}
35+
36+
@Autowired
37+
private AddMainCategoryService addMainCategoryService;
38+
@Autowired
39+
private AddSubCategoryService addsubCategoryService;
40+
@Autowired
41+
private EntityManager entityManager;
42+
43+
@Test
44+
@Transactional
45+
@Rollback(false)
46+
void addMainCategory() {
47+
// 관리자 추가
48+
MemberEntity admin = MemberEntity.builder()
49+
.name("Admin")
50+
.email("admin@example.com")
51+
.nickname("admin.ad")
52+
.isReviewer(false)
53+
.role(MemberRole.ROLE_ADMIN)
54+
.departmentRole("Admin")
55+
.status(MemberStatus.ACTIVE)
56+
.password("admin123")
57+
.build();
58+
entityManager.persist(admin);
59+
60+
admin = entityManager.find(MemberEntity.class, 1);
61+
addMainCategoryService.addMainCategory(admin.getMemberId(), "VM", "가상머신");
62+
63+
CategoryEntity category = entityManager.find(CategoryEntity.class, 1);
64+
assertThat(category.getCategoryId()).isEqualTo(1);
65+
assertThat(category.getName()).isEqualTo("가상머신");
66+
assertThat(category.getCode()).isEqualTo("VM");
67+
assertThat(category.getAdmin().getMemberId()).isEqualTo(1);
68+
}
69+
70+
@Test
71+
void addSubCategory() {
72+
MemberEntity admin = entityManager.find(MemberEntity.class, 1);
73+
addsubCategoryService.addSubCategory(admin.getMemberId(), 1L, "CR", "생성");
74+
75+
CategoryEntity category = entityManager.find(CategoryEntity.class, 2);
76+
assertThat(category.getCategoryId()).isEqualTo(2);
77+
assertThat(category.getMainCategory().getCategoryId()).isEqualTo(1);
78+
assertThat(category.getName()).isEqualTo("생성");
79+
assertThat(category.getCode()).isEqualTo("CR");
80+
assertThat(category.getAdmin().getMemberId()).isEqualTo(1);
81+
}
82+
}

0 commit comments

Comments
 (0)