diff --git a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/dto/response/TodoNotificationInfoResponse.java b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/dto/response/TodoNotificationInfoResponse.java index 398ff869..156b62ad 100644 --- a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/dto/response/TodoNotificationInfoResponse.java +++ b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/dto/response/TodoNotificationInfoResponse.java @@ -1,15 +1,19 @@ package com.pawith.todoapplication.dto.response; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; -import lombok.Getter; +import com.pawith.tododomain.entity.TodoNotification; import java.time.LocalTime; +import java.util.Optional; +import java.util.function.Supplier; -@AllArgsConstructor -@Getter -public class TodoNotificationInfoResponse { - private Boolean isNotification; - @JsonInclude(JsonInclude.Include.NON_NULL) - private LocalTime notificationTime; +public record TodoNotificationInfoResponse( + Boolean isNotification, + @JsonInclude(JsonInclude.Include.NON_NULL) LocalTime notificationTime +) { + public static TodoNotificationInfoResponse of(Supplier> todoNotificationSupplier) { + return todoNotificationSupplier.get() + .map(todoNotification -> new TodoNotificationInfoResponse(true, todoNotification.getNotificationTime())) + .orElse(new TodoNotificationInfoResponse(false, null)); + } } diff --git a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/handler/IncompleteTodoCountNotificationHandler.java b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/handler/IncompleteTodoCountNotificationHandler.java index 474896ee..9a4ee387 100644 --- a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/handler/IncompleteTodoCountNotificationHandler.java +++ b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/handler/IncompleteTodoCountNotificationHandler.java @@ -56,7 +56,7 @@ private void cachingUserInfo(List executionResult) { .map(IncompleteTodoCountInfoDao::getUserId) .filter(userId -> !valueOperator.contains(userId)) .toList(); - userQueryService.findUserMapByIds(userIds) + userQueryService.findMapWithUserIdKeyByIds(userIds) .forEach((userId, user) -> valueOperator.setWithExpire(userId, user.getNickname(), 1, TimeUnit.MINUTES)); } } diff --git a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/RegistersGetUseCase.java b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/RegistersGetUseCase.java index 6b90fe04..86a0042c 100644 --- a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/RegistersGetUseCase.java +++ b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/RegistersGetUseCase.java @@ -47,7 +47,7 @@ public ListResponse getManageRegisters(final Long te final Map registerUserMap = getRegisterUserMap(allRegisters); Comparator authorityComparator = Comparator.comparing(Enum::ordinal); final List manageRegisterInfoResponses = allRegisters.stream() - .sorted(Comparator.comparing(register -> register.getAuthority(), authorityComparator)) + .sorted(Comparator.comparing(Register::getAuthority, authorityComparator)) .map(register -> { final User registerUser = registerUserMap.get(register.getUserId()); return new RegisterManageInfoResponse(register.getId(), register.getAuthority(), registerUser.getNickname(), registerUser.getEmail(), registerUser.getImageUrl()); @@ -67,7 +67,7 @@ private Map getRegisterUserMap(List allRegisters) { final List registerUserIds = allRegisters.stream() .map(Register::getUserId) .collect(Collectors.toList()); - return userQueryService.findUserMapByIds(registerUserIds); + return userQueryService.findMapWithUserIdKeyByIds(registerUserIds); } public ListResponse searchRegisterByNickname(final Long todoTeamId, final String nickname) { diff --git a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoCompleteGetUseCase.java b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoCompleteGetUseCase.java new file mode 100644 index 00000000..18b3ea1e --- /dev/null +++ b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoCompleteGetUseCase.java @@ -0,0 +1,18 @@ +package com.pawith.todoapplication.service; + +import com.pawith.commonmodule.annotation.ApplicationService; +import com.pawith.todoapplication.dto.response.TodoCompletionResponse; +import com.pawith.tododomain.entity.Todo; +import com.pawith.tododomain.service.TodoQueryService; +import lombok.RequiredArgsConstructor; + +@ApplicationService +@RequiredArgsConstructor +public class TodoCompleteGetUseCase { + private final TodoQueryService todoQueryService; + + public TodoCompletionResponse getTodoCompletion(Long todoId) { + final Todo todo = todoQueryService.findTodoByTodoId(todoId); + return new TodoCompletionResponse(todo.getCompletionStatus()); + } +} diff --git a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoGetUseCase.java b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoGetUseCase.java index 21898d0b..e32d9bda 100644 --- a/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoGetUseCase.java +++ b/Domain-Module/Todo-Module/Todo-Application/src/main/java/com/pawith/todoapplication/service/TodoGetUseCase.java @@ -2,7 +2,10 @@ import com.pawith.commonmodule.annotation.ApplicationService; import com.pawith.commonmodule.response.ListResponse; -import com.pawith.todoapplication.dto.response.*; +import com.pawith.todoapplication.dto.response.AssignUserInfoResponse; +import com.pawith.todoapplication.dto.response.CategorySubTodoResponse; +import com.pawith.todoapplication.dto.response.TodoInfoResponse; +import com.pawith.todoapplication.dto.response.TodoNotificationInfoResponse; import com.pawith.todoapplication.mapper.TodoMapper; import com.pawith.tododomain.entity.*; import com.pawith.tododomain.service.AssignQueryService; @@ -16,7 +19,6 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; -import java.time.LocalTime; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -33,6 +35,7 @@ public class TodoGetUseCase { private final AssignQueryService assignQueryService; private final TodoNotificationQueryService todoNotificationQueryService; + public ListResponse getTodoListByTodoTeamId(final Long todoTeamId) { final User user = userUtils.getAccessUser(); final List allAssigns = assignQueryService.findAllByUserIdAndTodoTeamIdAndScheduledDate(user.getId(), todoTeamId); @@ -49,36 +52,40 @@ public ListResponse getTodoListByTodoTeamId(final Long todoTea public ListResponse getTodoListByCategoryId(Long categoryId, LocalDate moveDate) { final User accessUser = userUtils.getAccessUser(); - final Map> todoAssignMap = createTodoAssignListMap(categoryId, moveDate); - final Map todoNotificationMap = createTodoNotificationMapWithTodoId(new ArrayList<>(todoAssignMap.keySet()), accessUser.getId()); + + final Map> todoAssignMap = + assignQueryService.findMapWithTodoKeyAndAssignListValueByCategoryIdAndScheduledDate(categoryId, moveDate); + final List todoList = List.copyOf(todoAssignMap.keySet()); + + final Map todoNotificationMap = + todoNotificationQueryService.findMapTodoIdKeyAndTodoNotificationValueByTodoIdsAndUserId(todoList, accessUser.getId()); + final Map userMap = createUserIdMap(todoAssignMap); - final ArrayList todoMainResponses = new ArrayList<>(); - for (Todo todo : todoAssignMap.keySet()) { - final AtomicReference isAssigned = new AtomicReference<>(false); - final List assignUserInfoResponses = todoAssignMap.get(todo).stream() - .map(assign -> { - final Register register = assign.getRegister(); - final User findUser = userMap.get(register.getUserId()); - if (Objects.equals(findUser.getId(), accessUser.getId())) { - isAssigned.set(true); - } - return new AssignUserInfoResponse(findUser.getId(), findUser.getNickname(), assign.getCompletionStatus()); - }) - .sorted(Comparator.comparing(assignUserInfoResponse -> !Objects.equals(assignUserInfoResponse.getAssigneeId(), accessUser.getId()))) - .collect(Collectors.toList()); - TodoNotificationInfoResponse todoNotificationInfoResponse = getTodoNotificationInfoResponse(todo, todoNotificationMap); - todoMainResponses.add(TodoMapper.mapToCategorySubTodoResponse(todo, assignUserInfoResponses, isAssigned.get(),todoNotificationInfoResponse)); - } - return ListResponse.from(todoMainResponses); + + final List subTodoResponseList = todoList.stream() + .map(todo -> { + final AtomicReference isAssigned = new AtomicReference<>(false); + final List assigns = todoAssignMap.get(todo); + final List assignUserInfoResponses = getAssignUserInfoResponses(assigns, userMap, accessUser, isAssigned); + final TodoNotificationInfoResponse todoNotificationInfoResponse = + TodoNotificationInfoResponse.of(() -> Optional.ofNullable(todoNotificationMap.get(todo.getId()))); + return TodoMapper.mapToCategorySubTodoResponse(todo, assignUserInfoResponses, isAssigned.get(), todoNotificationInfoResponse); + }).toList(); + return ListResponse.from(subTodoResponseList); } - private static TodoNotificationInfoResponse getTodoNotificationInfoResponse(Todo todo, Map todoNotificationMap) { - if(todoNotificationMap.containsKey(todo.getId())){ - final TodoNotification todoNotification = todoNotificationMap.get(todo.getId()); - final LocalTime notificationTime = todoNotification.getNotificationTime(); - return new TodoNotificationInfoResponse(true, notificationTime); - } - return new TodoNotificationInfoResponse(false, null); + private List getAssignUserInfoResponses(List assigns, Map userMap, User accessUser, AtomicReference isAssigned) { + return assigns.stream() + .map(assign -> { + final Register register = assign.getRegister(); + final User findUser = userMap.get(register.getUserId()); + if (Objects.equals(findUser.getId(), accessUser.getId())) { + isAssigned.set(true); + } + return new AssignUserInfoResponse(findUser.getId(), findUser.getNickname(), assign.getCompletionStatus()); + }) + .sorted(Comparator.comparing(assignUserInfoResponse -> !Objects.equals(assignUserInfoResponse.getAssigneeId(), accessUser.getId()))) + .collect(Collectors.toList()); } private Map createUserIdMap(Map> groupByTodo) { @@ -90,25 +97,7 @@ private Map createUserIdMap(Map> groupByTodo) { }) .boxed() .collect(Collectors.toList()); - return userQueryService.findUserMapByIds(userIds); - } - - private Map createTodoNotificationMapWithTodoId(List todoList, Long userId) { - final List todoIds = todoList.stream().map(Todo::getId).collect(Collectors.toList()); - return todoNotificationQueryService.findAllByTodoIdsWithIncompleteAssign(todoIds, userId) - .stream() - .collect(Collectors.toMap(todoNotification -> todoNotification.getAssign().getTodo().getId(), todoNotification -> todoNotification)); - } - - public TodoCompletionResponse getTodoCompletion(Long todoId) { - final Todo todo = todoQueryService.findTodoByTodoId(todoId); - return new TodoCompletionResponse(todo.getCompletionStatus()); - } - - private Map> createTodoAssignListMap(Long categoryId, LocalDate moveDate) { - return assignQueryService.findAllAssignByCategoryIdAndScheduledDate(categoryId, moveDate) - .stream() - .collect(Collectors.groupingBy(Assign::getTodo, LinkedHashMap::new, Collectors.toList())); + return userQueryService.findMapWithUserIdKeyByIds(userIds); } } diff --git a/Domain-Module/Todo-Module/Todo-Application/src/test/java/com/pawith/todoapplication/service/RegistersGetUseCaseTest.java b/Domain-Module/Todo-Module/Todo-Application/src/test/java/com/pawith/todoapplication/service/RegistersGetUseCaseTest.java index 13a2b412..90afc8ee 100644 --- a/Domain-Module/Todo-Module/Todo-Application/src/test/java/com/pawith/todoapplication/service/RegistersGetUseCaseTest.java +++ b/Domain-Module/Todo-Module/Todo-Application/src/test/java/com/pawith/todoapplication/service/RegistersGetUseCaseTest.java @@ -56,7 +56,7 @@ void getRegisters() { ); final List userIds = registerList.stream().map(Register::getUserId).collect(Collectors.toList()); given(registerQueryService.findAllRegistersByTodoTeamId(todoTeamId)).willReturn(registerList); - given(userQueryService.findUserMapByIds(userIds)).willReturn(Map.of(mockFindUser.getId(), mockFindUser)); + given(userQueryService.findMapWithUserIdKeyByIds(userIds)).willReturn(Map.of(mockFindUser.getId(), mockFindUser)); // when ListResponse registerInfoListResponse = registersGetUseCase.getRegisters(todoTeamId); // then diff --git a/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/AssignQueryService.java b/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/AssignQueryService.java index db9aaec4..74078918 100644 --- a/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/AssignQueryService.java +++ b/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/AssignQueryService.java @@ -2,6 +2,7 @@ import com.pawith.commonmodule.annotation.DomainService; import com.pawith.tododomain.entity.Assign; +import com.pawith.tododomain.entity.Todo; import com.pawith.tododomain.exception.AssignNotFoundException; import com.pawith.tododomain.exception.TodoError; import com.pawith.tododomain.repository.AssignRepository; @@ -9,7 +10,10 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @DomainService @Transactional(readOnly = true) @@ -22,6 +26,12 @@ public List findAllAssignByCategoryIdAndScheduledDate(Long categoryId, L return assignRepository.findAllByCategoryIdAndScheduledDateQuery(categoryId, scheduledDate); } + public Map> findMapWithTodoKeyAndAssignListValueByCategoryIdAndScheduledDate(Long categoryId, LocalDate scheduledDate) { + return assignRepository.findAllByCategoryIdAndScheduledDateQuery(categoryId, scheduledDate) + .stream() + .collect(Collectors.groupingBy(Assign::getTodo, LinkedHashMap::new, Collectors.toList())); + } + public List findAllByUserIdAndTodoTeamIdAndScheduledDate(Long userId, Long todoTeamId) { final LocalDate now = LocalDate.now(); return assignRepository.findAllByUserIdAndTodoTeamIdAndScheduledDateQuery(userId, todoTeamId, now); diff --git a/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/TodoNotificationQueryService.java b/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/TodoNotificationQueryService.java index a18acb53..efa04aa7 100644 --- a/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/TodoNotificationQueryService.java +++ b/Domain-Module/Todo-Module/Todo-Domain/src/main/java/com/pawith/tododomain/service/TodoNotificationQueryService.java @@ -1,12 +1,16 @@ package com.pawith.tododomain.service; import com.pawith.commonmodule.annotation.DomainService; +import com.pawith.tododomain.entity.Assign; +import com.pawith.tododomain.entity.Todo; import com.pawith.tododomain.entity.TodoNotification; import com.pawith.tododomain.repository.TodoNotificationRepository; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @DomainService @RequiredArgsConstructor @@ -15,7 +19,14 @@ public class TodoNotificationQueryService { private final TodoNotificationRepository todoNotificationRepository; - public List findAllByTodoIdsWithIncompleteAssign(List todoIds, Long userId) { - return todoNotificationRepository.findAllByTodoIdsAndUserIdWithInCompleteAssignQuery(todoIds, userId); + public Map findMapTodoIdKeyAndTodoNotificationValueByTodoIdsAndUserId(List todoList, Long userId) { + final List todoIds = todoList.stream().map(Todo::getId).collect(Collectors.toList()); + return todoNotificationRepository.findAllByTodoIdsAndUserIdWithInCompleteAssignQuery(todoIds, userId) + .stream() + .collect(Collectors.toMap(todoNotification -> { + final Assign assign = todoNotification.getAssign(); + final Todo todo = assign.getTodo(); + return todo.getId(); + }, todoNotification -> todoNotification)); } } diff --git a/Domain-Module/Todo-Module/Todo-Presentation/src/main/java/com/pawith/todopresentation/TodoController.java b/Domain-Module/Todo-Module/Todo-Presentation/src/main/java/com/pawith/todopresentation/TodoController.java index 48f4fa32..8f80ab7e 100644 --- a/Domain-Module/Todo-Module/Todo-Presentation/src/main/java/com/pawith/todopresentation/TodoController.java +++ b/Domain-Module/Todo-Module/Todo-Presentation/src/main/java/com/pawith/todopresentation/TodoController.java @@ -31,6 +31,7 @@ public class TodoController { private final TodoValidationUseCase todoValidationUseCase; private final TodoNotificationCreateUseCase todoNotificationCreateUseCase; private final TodoWithdrawGetUseCase todoWithdrawGetUseCase; + private final TodoCompleteGetUseCase todoCompleteGetUseCase; @GetMapping("/{todoTeamId}/todos/progress") public TodoProgressResponse getTodoProgress(@PathVariable Long todoTeamId) { @@ -80,7 +81,7 @@ public void putAssign(@PathVariable Long todoId, @RequestBody AssignChangeReques @GetMapping("/todos/{todoId}/completion") public TodoCompletionResponse getTodoCompletion(@PathVariable Long todoId){ - return todoGetUseCase.getTodoCompletion(todoId); + return todoCompleteGetUseCase.getTodoCompletion(todoId); } @DeleteMapping("/todos/{todoId}") diff --git a/Domain-Module/Todo-Module/Todo-Presentation/src/test/java/com/pawith/todopresentation/TodoControllerTest.java b/Domain-Module/Todo-Module/Todo-Presentation/src/test/java/com/pawith/todopresentation/TodoControllerTest.java index bb117fdc..480aff1e 100644 --- a/Domain-Module/Todo-Module/Todo-Presentation/src/test/java/com/pawith/todopresentation/TodoControllerTest.java +++ b/Domain-Module/Todo-Module/Todo-Presentation/src/test/java/com/pawith/todopresentation/TodoControllerTest.java @@ -57,6 +57,8 @@ public class TodoControllerTest extends BaseRestDocsTest { private TodoNotificationCreateUseCase todoNotificationCreateUseCase; @MockBean private TodoWithdrawGetUseCase todoWithdrawGetUseCase; + @MockBean + private TodoCompleteGetUseCase todoCompleteGetUseCase; private static final String TODO_REQUEST_URL = "/teams"; @@ -302,7 +304,7 @@ void getTodoCompletion() throws Exception { //given final Long testTodoId = FixtureMonkeyUtils.getJavaTypeBasedFixtureMonkey().giveMeOne(Long.class); final TodoCompletionResponse todoCompletionResponse = FixtureMonkeyUtils.getConstructBasedFixtureMonkey().giveMeOne(TodoCompletionResponse.class); - given(todoGetUseCase.getTodoCompletion(testTodoId)).willReturn(todoCompletionResponse); + given(todoCompleteGetUseCase.getTodoCompletion(testTodoId)).willReturn(todoCompletionResponse); MockHttpServletRequestBuilder request = get(TODO_REQUEST_URL + "/todos/{todoId}/completion", testTodoId) .header("Authorization", "Bearer accessToken"); //when diff --git a/Domain-Module/User-Module/User-Domain/src/main/java/com/pawith/userdomain/service/UserQueryService.java b/Domain-Module/User-Module/User-Domain/src/main/java/com/pawith/userdomain/service/UserQueryService.java index 948e8012..5f52d7b6 100644 --- a/Domain-Module/User-Module/User-Domain/src/main/java/com/pawith/userdomain/service/UserQueryService.java +++ b/Domain-Module/User-Module/User-Domain/src/main/java/com/pawith/userdomain/service/UserQueryService.java @@ -37,13 +37,13 @@ public User findById(Long userId){ return findUser(() -> userRepository.findById(userId)); } - public Map findUserMapByIds(List userIds){ + public Map findMapWithUserIdKeyByIds(List userIds){ return userRepository.findAllByIds(userIds) .stream() .collect(Collectors.toMap(User::getId, Function.identity())); } - private User findUser(Supplier> method){ + private User findUser(Supplier> method){ return method.get() .orElseThrow(() -> new UserNotFoundException(UserError.USER_NOT_FOUND)); }