Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package clap.server.adapter.inbound.web.dto.admin;

import java.util.List;

public record FindManagersResponse(
Long memberId,
String nickname,
String imageUrl,
int remainingTasks
) {

public static List<FindManagersResponse> emptyListResponse() {
return List.of();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package clap.server.adapter.inbound.web.member;

import clap.server.application.port.inbound.domain.FindManagersUsecase;
import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/manager")
@RequiredArgsConstructor
public class ManagerController {

private final FindManagersUsecase findManagersUsecase;

@GetMapping
public ResponseEntity<List<FindManagersResponse>> findManagers() {

List<FindManagersResponse> managers = findManagersUsecase.execute();

if (managers.isEmpty()) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(FindManagersResponse.emptyListResponse());
}

return ResponseEntity.ok(managers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,37 @@

import clap.server.adapter.inbound.web.dto.admin.FindMemberRequest;
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 com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@PersistenceAdapter
@RequiredArgsConstructor
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
private final MemberRepository memberRepository;
private final MemberPersistenceMapper memberPersistenceMapper;
private final TaskRepository taskRepository;
private final TaskPersistenceMapper taskPersistenceMapper;
private final JPAQueryFactory jpaQueryFactory;

@Override
public Optional<Member> findById(final Long id) {
Expand Down Expand Up @@ -62,6 +73,28 @@ public void save(final Member member) {
memberRepository.save(memberEntity);
}

@Override
public List<Member> findActiveManagers() {
List<MemberEntity> 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<TaskStatus> targetStatuses = List.of(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED);
return findTasksByMemberIdAndStatus(memberId, targetStatuses).size();
}

@Override
public List<Task> findTasksByMemberIdAndStatus(Long memberId, List<TaskStatus> taskStatuses) {
List<TaskEntity> taskEntities = taskRepository.findByProcessor_MemberIdAndTaskStatusIn(memberId, taskStatuses);
return taskEntities.stream()
.map(taskPersistenceMapper::toDomain)
.collect(Collectors.toList());
}

@Override
public Page<Member> findAllMembers(Pageable pageable) {
return memberRepository.findAllMembers(pageable).map(memberPersistenceMapper::toDomain);
Expand All @@ -74,4 +107,3 @@ public Page<Member> findMembersWithFilter(Pageable pageable, FindMemberRequest f
}
}


Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package clap.server.adapter.outbound.persistense.mapper;

import clap.server.adapter.outbound.persistense.entity.task.TaskHistoryEntity;
import clap.server.adapter.outbound.persistense.entity.task.TaskModificationInfo;
import clap.server.adapter.outbound.persistense.mapper.common.PersistenceMapper;
import clap.server.domain.model.task.TaskHistory;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring", uses = {CommentPersistenceMapper.class, TaskPersistenceMapper.class, MemberPersistenceMapper.class})
public interface TaskHistoryPersistenceMapper extends PersistenceMapper<TaskHistoryEntity, TaskHistory> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package clap.server.adapter.outbound.persistense.repository.task;


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.domain.Pageable;
import org.springframework.data.domain.Slice;
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;
import java.util.Optional;

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


List<TaskEntity> findByProcessor_MemberIdAndTaskStatusIn(Long memberId, Collection<TaskStatus> taskStatuses);


@Query("SELECT t FROM TaskEntity t " +
"WHERE t.processor.memberId = :processorId " +
"AND t.taskStatus IN :taskStatus " +
Expand All @@ -45,12 +50,4 @@ Slice<TaskEntity> findTasksWithTaskStatusAndCompletedAt(
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderDesc(
Long processorId, TaskStatus taskStatus, Long processorOrder);

}








}
27 changes: 27 additions & 0 deletions src/main/java/clap/server/application/mapper/ManagersMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package clap.server.application.mapper;

import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
import clap.server.domain.model.member.Member;
import clap.server.application.port.inbound.domain.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ManagersMapper {

private final MemberService memberService;

public FindManagersResponse mapToFindManagersResponse(Member 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
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package clap.server.application.port.inbound.domain;

import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
import java.util.List;

public interface FindManagersUsecase {
List<FindManagersResponse> execute();
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@ public Member findActiveMember(Long memberId) {
() -> new ApplicationException(MemberErrorCode.ACTIVE_MEMBER_NOT_FOUND));
}

public int getRemainingTasks(Long memberId) {
List<TaskStatus> 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<Member> findActiveManagers() {
List<Member> activeManagers = loadMemberPort.findActiveManagers();

if (activeManagers.isEmpty()) {
return List.of();
}
return activeManagers;
}

public Member findReviewer(Long memberId) {
return loadMemberPort.findReviewerById(memberId).orElseThrow(
()-> new ApplicationException(MemberErrorCode.NOT_A_REVIEWER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@
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;
// Task 클래스 임포트 확인
// TaskStatus 임포트
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

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

Optional<Member> findActiveMemberById(Long id);

List<Member> findActiveManagers();

List<Task> findTasksByMemberIdAndStatus(Long memberId, List<TaskStatus> taskStatuses);

int getRemainingTasks(Long memberId);

Optional<Member> findReviewerById(Long id);

Optional<Member> findByNickname(String nickname);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package clap.server.application.service;

import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse;
import clap.server.domain.model.member.Member;
import clap.server.application.port.inbound.domain.MemberService;
import clap.server.application.mapper.ManagersMapper;
import clap.server.application.port.inbound.domain.FindManagersUsecase;
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 FindActiveManagersService implements FindManagersUsecase {

private final MemberService memberService;
private final ManagersMapper findManagersResponseMapper;

@Transactional
@Override
public List<FindManagersResponse> execute() {

List<Member> managers = memberService.findActiveManagers();

// managers를 FindManagersResponse로 매핑
return managers.stream()
.map(findManagersResponseMapper::mapToFindManagersResponse)
.collect(Collectors.toList());
}
}