Skip to content

Commit 8581b2b

Browse files
authored
Merge pull request #83 from TaskFlow-CLAP/feature/CLAP-76
CLAP-76 담당자 조회 api 구현
2 parents 5cece05 + d2962e5 commit 8581b2b

File tree

10 files changed

+194
-18
lines changed

10 files changed

+194
-18
lines changed
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.admin;
2+
3+
import java.util.List;
4+
5+
public record FindManagersResponse(
6+
Long memberId,
7+
String nickname,
8+
String imageUrl,
9+
int remainingTasks
10+
) {
11+
12+
public static List<FindManagersResponse> emptyListResponse() {
13+
return List.of();
14+
}
15+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package clap.server.adapter.inbound.web.member;
2+
3+
import clap.server.application.port.inbound.domain.FindManagersUsecase;
4+
import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
5+
import lombok.RequiredArgsConstructor;
6+
import org.springframework.http.HttpStatus;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RestController;
11+
12+
import java.util.List;
13+
14+
@RestController
15+
@RequestMapping("/manager")
16+
@RequiredArgsConstructor
17+
public class ManagerController {
18+
19+
private final FindManagersUsecase findManagersUsecase;
20+
21+
@GetMapping
22+
public ResponseEntity<List<FindManagersResponse>> findManagers() {
23+
24+
List<FindManagersResponse> managers = findManagersUsecase.execute();
25+
26+
if (managers.isEmpty()) {
27+
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(FindManagersResponse.emptyListResponse());
28+
}
29+
30+
return ResponseEntity.ok(managers);
31+
}
32+
}

src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,37 @@
22

33
import clap.server.adapter.inbound.web.dto.admin.FindMemberRequest;
44
import clap.server.adapter.outbound.persistense.entity.member.MemberEntity;
5+
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole;
56
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
67
import clap.server.adapter.outbound.persistense.mapper.MemberPersistenceMapper;
78
import clap.server.adapter.outbound.persistense.repository.member.MemberRepository;
89
import clap.server.application.port.outbound.member.CommandMemberPort;
910
import clap.server.application.port.outbound.member.LoadMemberPort;
1011
import clap.server.common.annotation.architecture.PersistenceAdapter;
12+
import clap.server.domain.model.task.Task;
13+
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus ;
14+
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
15+
import clap.server.adapter.outbound.persistense.repository.task.TaskRepository;
16+
import clap.server.adapter.outbound.persistense.mapper.TaskPersistenceMapper;
17+
import java.util.stream.Collectors;
18+
import java.util.List;
19+
1120
import clap.server.domain.model.member.Member;
21+
import com.querydsl.jpa.impl.JPAQueryFactory;
1222
import lombok.RequiredArgsConstructor;
1323
import org.springframework.data.domain.Page;
1424
import org.springframework.data.domain.Pageable;
1525

16-
import java.util.List;
1726
import java.util.Optional;
18-
import java.util.stream.Collectors;
1927

2028
@PersistenceAdapter
2129
@RequiredArgsConstructor
22-
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
30+
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
2331
private final MemberRepository memberRepository;
2432
private final MemberPersistenceMapper memberPersistenceMapper;
33+
private final TaskRepository taskRepository;
34+
private final TaskPersistenceMapper taskPersistenceMapper;
35+
private final JPAQueryFactory jpaQueryFactory;
2536

2637
@Override
2738
public Optional<Member> findById(final Long id) {
@@ -62,6 +73,28 @@ public void save(final Member member) {
6273
memberRepository.save(memberEntity);
6374
}
6475

76+
@Override
77+
public List<Member> findActiveManagers() {
78+
List<MemberEntity> memberEntities = memberRepository.findByRoleAndStatus(MemberRole.valueOf("ROLE_MANAGER"), MemberStatus.ACTIVE);
79+
return memberEntities.stream()
80+
.map(memberPersistenceMapper::toDomain)
81+
.collect(Collectors.toList());
82+
}
83+
84+
@Override
85+
public int getRemainingTasks(Long memberId) {
86+
List<TaskStatus> targetStatuses = List.of(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED);
87+
return findTasksByMemberIdAndStatus(memberId, targetStatuses).size();
88+
}
89+
90+
@Override
91+
public List<Task> findTasksByMemberIdAndStatus(Long memberId, List<TaskStatus> taskStatuses) {
92+
List<TaskEntity> taskEntities = taskRepository.findByProcessor_MemberIdAndTaskStatusIn(memberId, taskStatuses);
93+
return taskEntities.stream()
94+
.map(taskPersistenceMapper::toDomain)
95+
.collect(Collectors.toList());
96+
}
97+
6598
@Override
6699
public Page<Member> findAllMembers(Pageable pageable) {
67100
return memberRepository.findAllMembers(pageable).map(memberPersistenceMapper::toDomain);
@@ -74,4 +107,3 @@ public Page<Member> findMembersWithFilter(Pageable pageable, FindMemberRequest f
74107
}
75108
}
76109

77-

src/main/java/clap/server/adapter/outbound/persistense/mapper/TaskHistoryPersistenceMapper.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package clap.server.adapter.outbound.persistense.mapper;
22

33
import clap.server.adapter.outbound.persistense.entity.task.TaskHistoryEntity;
4-
import clap.server.adapter.outbound.persistense.entity.task.TaskModificationInfo;
54
import clap.server.adapter.outbound.persistense.mapper.common.PersistenceMapper;
65
import clap.server.domain.model.task.TaskHistory;
76
import org.mapstruct.Mapper;
8-
import org.mapstruct.Mapping;
9-
import org.mapstruct.Mappings;
107

118
@Mapper(componentModel = "spring", uses = {CommentPersistenceMapper.class, TaskPersistenceMapper.class, MemberPersistenceMapper.class})
129
public interface TaskHistoryPersistenceMapper extends PersistenceMapper<TaskHistoryEntity, TaskHistory> {

src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package clap.server.adapter.outbound.persistense.repository.task;
22

3-
43
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
54
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
65
import io.lettuce.core.dynamic.annotation.Param;
76
import org.springframework.data.domain.Pageable;
87
import org.springframework.data.domain.Slice;
98
import org.springframework.data.jpa.repository.JpaRepository;
109
import org.springframework.data.jpa.repository.Query;
10+
1111
import org.springframework.stereotype.Repository;
1212

1313
import java.time.LocalDateTime;
14+
import java.util.Collection;
15+
1416
import java.util.List;
1517
import java.util.Optional;
1618

@@ -26,6 +28,9 @@ List<TaskEntity> findYesterdayTaskByUpdatedAtIsBetween(
2628
);
2729

2830

31+
List<TaskEntity> findByProcessor_MemberIdAndTaskStatusIn(Long memberId, Collection<TaskStatus> taskStatuses);
32+
33+
2934
@Query("SELECT t FROM TaskEntity t " +
3035
"WHERE t.processor.memberId = :processorId " +
3136
"AND t.taskStatus IN :taskStatus " +
@@ -45,12 +50,4 @@ Slice<TaskEntity> findTasksWithTaskStatusAndCompletedAt(
4550
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderDesc(
4651
Long processorId, TaskStatus taskStatus, Long processorOrder);
4752

48-
}
49-
50-
51-
52-
53-
54-
55-
56-
53+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package clap.server.application.mapper;
2+
3+
import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
4+
import clap.server.domain.model.member.Member;
5+
import clap.server.application.port.inbound.domain.MemberService;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.stereotype.Component;
8+
9+
@Component
10+
@RequiredArgsConstructor
11+
public class ManagersMapper {
12+
13+
private final MemberService memberService;
14+
15+
public FindManagersResponse mapToFindManagersResponse(Member manager) {
16+
int remainingTasks = memberService.getRemainingTasks(manager.getMemberId());
17+
String nickname = memberService.getMemberNickname(manager.getMemberId());
18+
String imageUrl = memberService.getMemberImageUrl(manager.getMemberId());
19+
20+
return new FindManagersResponse(
21+
manager.getMemberId(),
22+
nickname,
23+
imageUrl,
24+
remainingTasks
25+
);
26+
}
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package clap.server.application.port.inbound.domain;
2+
3+
import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
4+
import java.util.List;
5+
6+
public interface FindManagersUsecase {
7+
List<FindManagersResponse> execute();
8+
}

src/main/java/clap/server/application/port/inbound/domain/MemberService.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,33 @@ public Member findActiveMember(Long memberId) {
2525
() -> new ApplicationException(MemberErrorCode.ACTIVE_MEMBER_NOT_FOUND));
2626
}
2727

28+
public int getRemainingTasks(Long memberId) {
29+
List<TaskStatus> targetStatuses = List.of(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED);
30+
return loadMemberPort.findTasksByMemberIdAndStatus(memberId, targetStatuses).size();
31+
}
32+
33+
public String getMemberNickname(Long memberId) {
34+
Member member = findById(memberId);
35+
if (member.getMemberInfo() == null) {
36+
throw new ApplicationException(MemberErrorCode.MEMBER_NOT_FOUND);
37+
}
38+
return member.getMemberInfo().getNickname();
39+
}
40+
41+
public String getMemberImageUrl(Long memberId) {
42+
Member member = findById(memberId);
43+
return member.getImageUrl() != null ? member.getImageUrl() : "default-image-url";
44+
}
45+
46+
public List<Member> findActiveManagers() {
47+
List<Member> activeManagers = loadMemberPort.findActiveManagers();
48+
49+
if (activeManagers.isEmpty()) {
50+
return List.of();
51+
}
52+
return activeManagers;
53+
}
54+
2855
public Member findReviewer(Long memberId) {
2956
return loadMemberPort.findReviewerById(memberId).orElseThrow(
3057
()-> new ApplicationException(MemberErrorCode.NOT_A_REVIEWER)

src/main/java/clap/server/application/port/outbound/member/LoadMemberPort.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,25 @@
44
import clap.server.domain.model.member.Member;
55
import clap.server.domain.model.task.Task; // Task 클래스 임포트 확인
66
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; // TaskStatus 임포트
7+
import java.util.List;
8+
// Task 클래스 임포트 확인
9+
// TaskStatus 임포트
710
import org.springframework.data.domain.Page;
811
import org.springframework.data.domain.Pageable;
912

10-
import java.util.List;
1113
import java.util.Optional;
1214

1315
public interface LoadMemberPort {
1416
Optional<Member> findById(Long id);
1517

1618
Optional<Member> findActiveMemberById(Long id);
1719

20+
List<Member> findActiveManagers();
21+
22+
List<Task> findTasksByMemberIdAndStatus(Long memberId, List<TaskStatus> taskStatuses);
23+
24+
int getRemainingTasks(Long memberId);
25+
1826
Optional<Member> findReviewerById(Long id);
1927

2028
Optional<Member> findByNickname(String nickname);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package clap.server.application.service;
2+
3+
import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
4+
import clap.server.domain.model.member.Member;
5+
import clap.server.application.port.inbound.domain.MemberService;
6+
import clap.server.application.mapper.ManagersMapper;
7+
import clap.server.application.port.inbound.domain.FindManagersUsecase;
8+
import jakarta.transaction.Transactional;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.stereotype.Service;
11+
12+
import java.util.List;
13+
import java.util.stream.Collectors;
14+
15+
@Service // 여기 추가
16+
@RequiredArgsConstructor
17+
public class FindActiveManagersService implements FindManagersUsecase {
18+
19+
private final MemberService memberService;
20+
private final ManagersMapper findManagersResponseMapper;
21+
22+
@Transactional
23+
@Override
24+
public List<FindManagersResponse> execute() {
25+
26+
List<Member> managers = memberService.findActiveManagers();
27+
28+
// managers를 FindManagersResponse로 매핑
29+
return managers.stream()
30+
.map(findManagersResponseMapper::mapToFindManagersResponse)
31+
.collect(Collectors.toList());
32+
}
33+
}

0 commit comments

Comments
 (0)