diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/admin/FindManagersResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/admin/FindManagersResponse.java deleted file mode 100644 index 26e64a60..00000000 --- a/src/main/java/clap/server/adapter/inbound/web/dto/admin/FindManagersResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -package clap.server.adapter.inbound.web.dto.admin; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.List; - -@Getter -@AllArgsConstructor -public class FindManagersResponse { - - private Long memberId; - private String nickname; - private String imageUrl; - private int remainingTasks; - - public static List emptyListResponse() { - return List.of(); - } - -} - - diff --git a/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java b/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java deleted file mode 100644 index c3e88222..00000000 --- a/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java +++ /dev/null @@ -1,33 +0,0 @@ -package clap.server.adapter.inbound.web.member; - -import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse; -import clap.server.application.port.inbound.domain.FindManagersUsecase; -import clap.server.common.annotation.architecture.WebAdapter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; - -import java.util.List; - - -@Tag(name = "담당자 조회") -@WebAdapter -@RequiredArgsConstructor -@RequestMapping("/api") -public class ManagerController { - - private final FindManagersUsecase findManagersUsecase; - - @GetMapping("/managers") - public List findManagers() { - - List managers = findManagersUsecase.execute(); - - if (managers.isEmpty()) { - return FindManagersResponse.emptyListResponse(); - } - - return managers; - } -} diff --git a/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java index 355879d4..18a1f9a0 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java @@ -1,33 +1,24 @@ package clap.server.adapter.outbound.persistense; import clap.server.adapter.outbound.persistense.entity.member.MemberEntity; -import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole; import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus; import clap.server.adapter.outbound.persistense.mapper.MemberPersistenceMapper; import clap.server.adapter.outbound.persistense.repository.member.MemberRepository; import clap.server.application.port.outbound.member.CommandMemberPort; import clap.server.application.port.outbound.member.LoadMemberPort; import clap.server.common.annotation.architecture.PersistenceAdapter; -import clap.server.domain.model.task.Task; -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus ; -import clap.server.adapter.outbound.persistense.entity.task.TaskEntity; -import clap.server.adapter.outbound.persistense.repository.task.TaskRepository; -import clap.server.adapter.outbound.persistense.mapper.TaskPersistenceMapper; -import java.util.stream.Collectors; -import java.util.List; - import clap.server.domain.model.member.Member; import lombok.RequiredArgsConstructor; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @PersistenceAdapter @RequiredArgsConstructor public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort { private final MemberRepository memberRepository; private final MemberPersistenceMapper memberPersistenceMapper; - private final TaskRepository taskRepository; - private final TaskPersistenceMapper taskPersistenceMapper; @Override @@ -63,27 +54,5 @@ public void save(final Member member) { memberRepository.save(memberEntity); } - @Override - public List findActiveManagers() { - List memberEntities = memberRepository.findByRoleAndStatus(MemberRole.valueOf("ROLE_MANAGER"), MemberStatus.ACTIVE); - return memberEntities.stream() - .map(memberPersistenceMapper::toDomain) - .collect(Collectors.toList()); - } - - @Override - public int getRemainingTasks(Long memberId) { - List targetStatuses = List.of(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED); - return findTasksByMemberIdAndStatus(memberId, targetStatuses).size(); - } - - - @Override - public List findTasksByMemberIdAndStatus(Long memberId, List taskStatuses) { - List taskEntities = taskRepository.findByProcessor_MemberIdAndTaskStatusIn(memberId, taskStatuses); - return taskEntities.stream() - .map(taskPersistenceMapper::toDomain) - .collect(Collectors.toList()); - } } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/TaskPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/TaskPersistenceAdapter.java index e74a47f2..10167342 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/TaskPersistenceAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/TaskPersistenceAdapter.java @@ -1,8 +1,8 @@ package clap.server.adapter.outbound.persistense; +import clap.server.adapter.inbound.web.dto.task.FilterPendingApprovalResponse; import clap.server.adapter.inbound.web.dto.task.FilterTaskListRequest; import clap.server.adapter.inbound.web.dto.task.FilterTaskListResponse; -import clap.server.adapter.inbound.web.dto.task.FilterPendingApprovalResponse; import clap.server.adapter.outbound.persistense.entity.task.TaskEntity; import clap.server.adapter.outbound.persistense.mapper.TaskPersistenceMapper; import clap.server.adapter.outbound.persistense.repository.task.TaskRepository; @@ -58,5 +58,4 @@ public List findYesterdayTaskByDate(LocalDateTime now) { .stream().map(taskPersistenceMapper::toDomain).toList(); } - } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java b/src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java index c4fdc318..97e1363e 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java @@ -2,19 +2,12 @@ import clap.server.adapter.outbound.persistense.entity.task.TaskEntity; -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; import io.lettuce.core.dynamic.annotation.Param; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; - import org.springframework.stereotype.Repository; - import java.time.LocalDateTime; -import java.util.Collection; - - import java.util.List; @Repository @@ -27,10 +20,6 @@ List findYesterdayTaskByUpdatedAtIsBetween( @Param("updatedAtAfter") LocalDateTime updatedAtAfter, @Param("updatedAtBefore") LocalDateTime updatedAtBefore ); - - - // 'processor'의 'id'로 검색하기 - List findByProcessor_MemberIdAndTaskStatusIn(Long memberId, Collection taskStatuses); } diff --git a/src/main/java/clap/server/application/mapper/MemberMapper.java b/src/main/java/clap/server/application/mapper/MemberMapper.java index 389e7b8a..a314b944 100644 --- a/src/main/java/clap/server/application/mapper/MemberMapper.java +++ b/src/main/java/clap/server/application/mapper/MemberMapper.java @@ -1,23 +1,14 @@ package clap.server.application.mapper; -import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole; -import clap.server.domain.model.member.Department; import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; import clap.server.domain.model.member.Member; -import clap.server.domain.model.member.MemberInfo; public class MemberMapper { private MemberMapper() { throw new IllegalArgumentException(); } - public static Member toMember(MemberInfo memberInfo) { - return Member.builder() - .memberInfo(memberInfo) - .build(); - } - public static MemberProfileResponse toMemberProfileResponse(Member member) { return new MemberProfileResponse( member.getMemberId(), diff --git a/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecase.java b/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecase.java deleted file mode 100644 index 57327d16..00000000 --- a/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecase.java +++ /dev/null @@ -1,8 +0,0 @@ -package clap.server.application.port.inbound.domain; - -import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse; -import java.util.List; - -public interface FindManagersUsecase { - List execute(); -} diff --git a/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecaseImpl.java b/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecaseImpl.java deleted file mode 100644 index 0148fb72..00000000 --- a/src/main/java/clap/server/application/port/inbound/domain/FindManagersUsecaseImpl.java +++ /dev/null @@ -1,41 +0,0 @@ -package clap.server.application.port.inbound.domain; - -import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse; -import clap.server.domain.model.member.Member; -import jakarta.transaction.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class FindManagersUsecaseImpl implements FindManagersUsecase { - - private final MemberService memberService; - - @Override - @Transactional - public List execute() { - - List managers = memberService.findActiveManagers(); - - if (managers.isEmpty()) { - return FindManagersResponse.emptyListResponse(); // 빈 리스트 반환 - } - - return managers.stream().map(manager -> { - int remainingTasks = memberService.getRemainingTasks(manager.getMemberId()); - String nickname = memberService.getMemberNickname(manager.getMemberId()); - String imageUrl = memberService.getMemberImageUrl(manager.getMemberId()); - - return new FindManagersResponse( - manager.getMemberId(), - nickname, - imageUrl, - remainingTasks - ); - }).collect(Collectors.toList()); - } -} diff --git a/src/main/java/clap/server/application/port/inbound/domain/MemberService.java b/src/main/java/clap/server/application/port/inbound/domain/MemberService.java index d8d3e8d8..ac2fb651 100644 --- a/src/main/java/clap/server/application/port/inbound/domain/MemberService.java +++ b/src/main/java/clap/server/application/port/inbound/domain/MemberService.java @@ -2,8 +2,6 @@ import clap.server.application.port.outbound.member.LoadMemberPort; import clap.server.domain.model.member.Member; -import clap.server.domain.model.task.Task; -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; import clap.server.exception.ApplicationException; import clap.server.exception.code.MemberErrorCode; import lombok.RequiredArgsConstructor; @@ -26,33 +24,6 @@ public Member findActiveMember(Long memberId) { () -> new ApplicationException(MemberErrorCode.ACTIVE_MEMBER_NOT_FOUND)); } - public int getRemainingTasks(Long memberId) { - List targetStatuses = List.of(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED); - return loadMemberPort.findTasksByMemberIdAndStatus(memberId, targetStatuses).size(); - } - - public String getMemberNickname(Long memberId) { - Member member = findById(memberId); - if (member.getMemberInfo() == null) { - throw new ApplicationException(MemberErrorCode.MEMBER_NOT_FOUND); - } - return member.getMemberInfo().getNickname(); - } - - public String getMemberImageUrl(Long memberId) { - Member member = findById(memberId); - return member.getImageUrl() != null ? member.getImageUrl() : "default-image-url"; - } - - public List findActiveManagers() { - List activeManagers = loadMemberPort.findActiveManagers(); - - if (activeManagers.isEmpty()) { - return List.of(); - } - return activeManagers; - } - public List findReviewers() { return loadMemberPort.findReviewers(); } diff --git a/src/main/java/clap/server/application/port/outbound/member/LoadMemberPort.java b/src/main/java/clap/server/application/port/outbound/member/LoadMemberPort.java index 1eb3e576..ab81c42d 100644 --- a/src/main/java/clap/server/application/port/outbound/member/LoadMemberPort.java +++ b/src/main/java/clap/server/application/port/outbound/member/LoadMemberPort.java @@ -1,8 +1,7 @@ package clap.server.application.port.outbound.member; import clap.server.domain.model.member.Member; -import clap.server.domain.model.task.Task; // Task 클래스 임포트 확인 -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; // TaskStatus 임포트 + import java.util.List; import java.util.Optional; @@ -11,12 +10,6 @@ public interface LoadMemberPort { Optional findActiveMemberById(Long id); - List findActiveManagers(); - - List findTasksByMemberIdAndStatus(Long memberId, List taskStatuses); - - int getRemainingTasks(Long memberId); - Optional findByNickname(String nickname); List findReviewers(); diff --git a/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java b/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java deleted file mode 100644 index c4cec9c6..00000000 --- a/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java +++ /dev/null @@ -1,211 +0,0 @@ -package clap.server.adapter.inbound.web.admin; - -import clap.server.adapter.outbound.persistense.entity.member.DepartmentEntity; -import clap.server.adapter.outbound.persistense.entity.member.MemberEntity; -import clap.server.adapter.outbound.persistense.entity.member.constant.DepartmentStatus; -import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole; -import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus; -import clap.server.adapter.outbound.persistense.entity.task.CategoryEntity; -import clap.server.adapter.outbound.persistense.entity.task.LabelEntity; -import clap.server.adapter.outbound.persistense.entity.task.TaskEntity; -import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor; -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; -import clap.server.config.elastic.ElasticsearchConfig; -import jakarta.persistence.EntityManager; -import jakarta.transaction.Transactional; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.annotation.Rollback; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.testcontainers.elasticsearch.ElasticsearchContainer; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@Import(ElasticsearchConfig.class) -@SpringBootTest -@Transactional -@AutoConfigureMockMvc -@Testcontainers -public class MemberControllerTest { - - @Container - public static ElasticsearchContainer ES_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:7.17.5") - .withReuse(true); - - @DynamicPropertySource - static void elasticProperties(DynamicPropertyRegistry registry) { - // Elasticsearch 설정 - registry.add("spring.elasticsearch.uris", ES_CONTAINER::getHttpHostAddress); - } - - @Autowired - private MockMvc mockMvc; - - @Autowired - private EntityManager entityManager; - - @BeforeEach - @Transactional - @Rollback(false) - public void setupTestData() { - // 부서 추가 - DepartmentEntity department = DepartmentEntity.builder() - .code("DEPT001") - .name("IT Department") - .status(DepartmentStatus.ACTIVE) - .build(); - entityManager.persist(department); // department 먼저 persist - - // 관리자 추가 - MemberEntity admin = MemberEntity.builder() - .name("Admin User") - .email("admin@example.com") - .nickname("Admin1") - .isReviewer(false) - .role(MemberRole.ROLE_ADMIN) - .departmentRole("Admin") - .status(MemberStatus.ACTIVE) - .password("admin123") - .imageUrl("http://example.com/admin.jpg") - .notificationEnabled(true) - .department(department) // 부서 할당 - .build(); - entityManager.persist(admin); - - // 카테고리 추가 - CategoryEntity category = CategoryEntity.builder() - .code("CATEGORY001") - .name("Development") - .descriptionExample("Development tasks category") - .isDeleted(false) - .admin(admin) - .build(); - entityManager.persist(category); - - // 라벨 추가 - LabelEntity label = LabelEntity.builder() - .admin(admin) - .labelName("일반") - .labelColor(LabelColor.GREY) - .isDeleted(false) - .build(); - entityManager.persist(label); - - // 관리자 (manager) 추가 - MemberEntity manager1 = MemberEntity.builder() // manager1 정의 - .name("Manager1") - .email("manager1@example.com") - .nickname("Manager1") - .isReviewer(true) - .role(MemberRole.ROLE_MANAGER) // 관리자로 설정 - .departmentRole("Manager") - .status(MemberStatus.ACTIVE) - .password("manager123") - .imageUrl("http://example.com/manager1.jpg") - .notificationEnabled(true) - .department(department) // 부서 할당 - .build(); - entityManager.persist(manager1); // manager1 저장 - - // 태스크 추가 - TaskEntity task = TaskEntity.builder() - .taskCode("TASK001") - .title("Task Title") - .description("Task Description") - .category(category) // 카테고리 연결 - .requester(admin) - .taskStatus(TaskStatus.PENDING_COMPLETED) - .processorOrder(1) - .reviewer(admin) - .processor(manager1) // 여기서 manager1을 processor로 설정 - .label(label) - .dueDate(LocalDateTime.now().plusDays(7)) - .completedAt(null) - .build(); - entityManager.persist(task); - - // 일반 사용자 (user) 추가 - MemberEntity user = MemberEntity.builder() - .name("User1") - .email("user1@example.com") - .nickname("User1") - .isReviewer(false) - .role(MemberRole.ROLE_USER) - .departmentRole("User") - .status(MemberStatus.ACTIVE) - .password("user123") - .imageUrl("http://example.com/user1.jpg") - .notificationEnabled(true) - .department(department) // 부서 할당 - .build(); - entityManager.persist(user); - // 두 번째 관리자 추가 - MemberEntity manager2 = MemberEntity.builder() - .name("Manager2") - .email("manager2@example.com") - .nickname("Manager2") - .isReviewer(true) - .role(MemberRole.ROLE_MANAGER) - .departmentRole("Manager") - .status(MemberStatus.ACTIVE) - .password("manager123") - .imageUrl("http://example.com/manager2.jpg") - .notificationEnabled(true) - .department(department) - .build(); - entityManager.persist(manager2); // 두 번째 관리자 저장 - - // 추가로 5명의 사용자 생성 - List members = new ArrayList<>(); - for (int i = 2; i <= 5; i++) { - members.add(MemberEntity.builder() - .name("User" + i) - .email("user" + i + "@example.com") - .nickname("User" + i) - .isReviewer(i % 2 == 0) - .role(MemberRole.ROLE_USER) - .departmentRole("DepartmentUser") - .status(MemberStatus.ACTIVE) - .password("user123") - .imageUrl("http://example.com/user" + i + ".jpg") - .notificationEnabled(i % 2 != 0) - .department(department) // 부서 할당 - .build()); - } - - // 멤버들을 데이터베이스에 저장 - members.forEach(entityManager::persist); - } - - - @Test - @WithMockUser(username = "admin", roles = "ADMIN") - public void testFindManagers() throws Exception { - mockMvc.perform(get("/api/managers")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$[0].nickname").value("Manager1")) - .andExpect(jsonPath("$[0].imageUrl").value("http://example.com/manager1.jpg")) - .andExpect(jsonPath("$[0].remainingTasks").value(1)) - .andExpect(jsonPath("$[1].nickname").value("Manager2")) // 추가된 관리자 - .andExpect(jsonPath("$[1].imageUrl").value("http://example.com/manager2.jpg")) - .andExpect(jsonPath("$[1].remainingTasks").value(0)) // 예시로 추가된 관리자들의 데이터를 검증 - .andDo(print()); - } - -} diff --git a/src/test/java/clap/server/application/service/task/FindTaskListServiceTest.java b/src/test/java/clap/server/application/service/task/FindTaskListServiceTest.java index f533b230..fe4adb02 100644 --- a/src/test/java/clap/server/application/service/task/FindTaskListServiceTest.java +++ b/src/test/java/clap/server/application/service/task/FindTaskListServiceTest.java @@ -1,9 +1,8 @@ package clap.server.application.service.task; -import clap.server.adapter.inbound.web.dto.task.FilterPendingApprovalResponse; import clap.server.adapter.inbound.web.dto.task.FilterTaskListRequest; import clap.server.adapter.inbound.web.dto.task.OrderTaskRequest; - +import clap.server.adapter.inbound.web.dto.task.FilterPendingApprovalResponse; import clap.server.application.Task.FindTaskListService; import clap.server.application.port.inbound.domain.MemberService; import clap.server.application.port.outbound.task.LoadTaskPort; @@ -14,13 +13,15 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.domain.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import java.time.LocalDateTime; import java.util.List; -import static org.assertj.core.api.Assertions.*; - +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when;