Skip to content

Commit c64c6ae

Browse files
authored
Merge pull request #288 from TaskFlow-CLAP/CLAP-256-팀-작업-현황-에러-수정
CLAP-256 팀 작업 현황 API 수정 및 예외 처리
2 parents f7c1c65 + 39d2bda commit c64c6ae

File tree

10 files changed

+78
-40
lines changed

10 files changed

+78
-40
lines changed

src/main/java/clap/server/adapter/inbound/web/dto/task/request/FilterTeamStatusRequest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,4 @@ public record FilterTeamStatusRequest(
2424
taskTitle = taskTitle == null ? "" : taskTitle;
2525
}
2626

27-
// 카테고리 유효성 검사
28-
public boolean isValid() {
29-
// 1차 카테고리가 없으면 2차 카테고리는 선택할 수 없으므로
30-
return mainCategoryIds.isEmpty() || !categoryIds.isEmpty();
31-
}
3227
}

src/main/java/clap/server/adapter/inbound/web/dto/task/response/TaskItemResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor;
44
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
5+
import clap.server.domain.model.task.Label;
56

67
import java.time.LocalDateTime;
78

src/main/java/clap/server/adapter/inbound/web/dto/task/response/TeamStatusResponse.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,23 @@
33
import java.util.List;
44

55
public record TeamStatusResponse(
6-
List<TeamTaskResponse> members
6+
List<TeamTaskResponse> members,
7+
int totalInProgressTaskCount,
8+
int totalPendingTaskCount,
9+
int totalTaskCount
710
) {
11+
// 기존 생성자 (3개 파라미터)
12+
public TeamStatusResponse(List<TeamTaskResponse> members, int totalInProgressTaskCount, int totalPendingTaskCount) {
13+
this(
14+
(members == null) ? List.of() : members,
15+
totalInProgressTaskCount,
16+
totalPendingTaskCount,
17+
totalInProgressTaskCount + totalPendingTaskCount
18+
);
19+
}
20+
21+
// 추가된 생성자 (List만 받음)
822
public TeamStatusResponse(List<TeamTaskResponse> members) {
9-
this.members = (members == null) ? List.of() : members;
23+
this(members, 0, 0); // 기본값을 사용하여 생성
1024
}
1125
}

src/main/java/clap/server/adapter/inbound/web/dto/task/response/TeamTaskItemResponse.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package clap.server.adapter.inbound.web.dto.task.response;
22

3+
import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor;
34
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
45

56
import java.time.LocalDateTime;
@@ -10,11 +11,18 @@ public record TeamTaskItemResponse(
1011
String title,
1112
String mainCategoryName,
1213
String categoryName,
14+
LabelInfo labelInfo,
1315
String requesterNickname,
1416
String requesterImageUrl,
1517
String requesterDepartment,
1618
long processorOrder,
1719
TaskStatus taskStatus,
1820
LocalDateTime createdAt
1921
) {
20-
}
22+
public static record LabelInfo(
23+
String labelName,
24+
LabelColor labelColor
25+
) {
26+
}
27+
28+
}

src/main/java/clap/server/adapter/inbound/web/dto/task/response/TeamTaskResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package clap.server.adapter.inbound.web.dto.task.response;
22

3+
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
34
import com.querydsl.core.annotations.QueryProjection;
45

56
import java.util.List;

src/main/java/clap/server/adapter/inbound/web/task/TeamStatusController.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@
55
import clap.server.adapter.inbound.web.dto.task.response.TeamStatusResponse;
66
import clap.server.application.service.task.TeamStatusService;
77
import clap.server.common.annotation.architecture.WebAdapter;
8+
import io.swagger.v3.oas.annotations.Operation;
89
import io.swagger.v3.oas.annotations.tags.Tag;
9-
import jakarta.validation.Valid;
1010
import lombok.RequiredArgsConstructor;
11-
import org.springframework.data.domain.Pageable;
1211
import org.springframework.http.ResponseEntity;
12+
import org.springframework.validation.annotation.Validated;
1313
import org.springframework.web.bind.annotation.*;
1414

15+
@Tag(name = "02. Task [담당자]")
16+
@WebAdapter
1517
@RestController
16-
@RequestMapping("/api/team-status")
1718
@RequiredArgsConstructor
18-
@Tag(name = "팀 현황 조회 API")
19-
@WebAdapter
20-
public class TeamStatusController {
21-
19+
@RequestMapping("/api/team-status")
20+
public class TeamStatusController {
21+
2222
private final TeamStatusService teamStatusService;
23-
23+
@Operation(summary = "팀 현황 필터링 조회 API")
2424
@GetMapping("/filter")
25-
public ResponseEntity<TeamStatusResponse> filterTeamStatus(@Valid@ModelAttribute FilterTeamStatusRequest filter) {
25+
public ResponseEntity<TeamStatusResponse> filterTeamStatus(@Validated @ModelAttribute FilterTeamStatusRequest filter) {
2626
TeamStatusResponse response = teamStatusService.filterTeamStatus(filter);
2727
return ResponseEntity.ok(response);
2828
}
29-
}
29+
}

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

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import clap.server.adapter.inbound.web.dto.task.request.FilterTaskBoardRequest;
44
import clap.server.adapter.inbound.web.dto.task.request.FilterTaskListRequest;
55
import clap.server.adapter.inbound.web.dto.task.request.FilterTeamStatusRequest;
6+
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskResponse;
7+
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskItemResponse;
68
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskItemResponse;
79
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskResponse;
810
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
@@ -56,30 +58,37 @@ public Page<TaskEntity> findTasksAssignedByManager(Long processorId, Pageable pa
5658

5759
@Override
5860
public List<TeamTaskResponse> findTeamStatus(Long memberId, FilterTeamStatusRequest filter) {
61+
// filter가 null인 경우에도 기본적으로 모든 데이터를 조회하도록 처리
5962
BooleanBuilder builder = new BooleanBuilder();
6063

61-
// 담당자 ID 필터링
62-
if (memberId != null) {
63-
builder.and(taskEntity.processor.memberId.eq(memberId));
64-
}
64+
// 필터가 null인 경우, 기본적으로 모든 데이터 조회
65+
if (filter != null) {
66+
// 진행 중 또는 완료 대기 상태 필터링
67+
builder.and(taskEntity.taskStatus.in(TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED));
6568

66-
// 작업 타이틀 필터링
67-
if (filter.taskTitle() != null && !filter.taskTitle().isEmpty()) {
68-
builder.and(taskEntity.title.containsIgnoreCase(filter.taskTitle()));
69-
}
69+
// 담당자 ID 필터링
70+
if (memberId != null) {
71+
builder.and(taskEntity.processor.memberId.eq(memberId));
72+
}
7073

71-
// 1차 카테고리 필터링
72-
if (!filter.mainCategoryIds().isEmpty()) {
73-
builder.and(taskEntity.category.mainCategory.categoryId.in(filter.mainCategoryIds()));
74-
}
74+
// 작업 타이틀 필터링
75+
if (filter.taskTitle() != null && !filter.taskTitle().isEmpty()) {
76+
builder.and(taskEntity.title.containsIgnoreCase(filter.taskTitle()));
77+
}
7578

76-
// 2차 카테고리 필터링
77-
if (!filter.categoryIds().isEmpty()) {
78-
builder.and(taskEntity.category.categoryId.in(filter.categoryIds()));
79+
// 1차 카테고리 필터링 (빈 배열인 경우, 필터링하지 않음)
80+
if (filter.mainCategoryIds() != null && !filter.mainCategoryIds().isEmpty()) {
81+
builder.and(taskEntity.category.mainCategory.categoryId.in(filter.mainCategoryIds()));
82+
}
83+
84+
// 2차 카테고리 필터링 (빈 배열인 경우, 필터링하지 않음)
85+
if (filter.categoryIds() != null && !filter.categoryIds().isEmpty()) {
86+
builder.and(taskEntity.category.categoryId.in(filter.categoryIds()));
87+
}
7988
}
8089

8190
// 정렬 조건 적용
82-
OrderSpecifier<?> orderBy = "기여도순".equals(filter.sortBy())
91+
OrderSpecifier<?> orderBy = "기여도순".equals(filter != null ? filter.sortBy() : "")
8392
? new CaseBuilder()
8493
.when(taskEntity.taskStatus.eq(TaskStatus.IN_PROGRESS)
8594
.or(taskEntity.taskStatus.eq(TaskStatus.PENDING_COMPLETED)))
@@ -106,6 +115,11 @@ public List<TeamTaskResponse> findTeamStatus(Long memberId, FilterTeamStatusRequ
106115
taskEntity.getTitle(),
107116
taskEntity.getCategory().getMainCategory().getName(),
108117
taskEntity.getCategory().getName(),
118+
taskEntity.getLabel() != null ?
119+
new TeamTaskItemResponse.LabelInfo(
120+
taskEntity.getLabel().getLabelName(),
121+
taskEntity.getLabel().getLabelColor()
122+
) : null,
109123
taskEntity.getRequester().getNickname(),
110124
taskEntity.getRequester().getImageUrl(),
111125
taskEntity.getRequester().getDepartment().getName(),
@@ -114,6 +128,10 @@ public List<TeamTaskResponse> findTeamStatus(Long memberId, FilterTeamStatusRequ
114128
taskEntity.getCreatedAt()
115129
)).collect(Collectors.toList());
116130

131+
int inProgressTaskCount = (int) entry.getValue().stream().filter(t -> t.getTaskStatus() == TaskStatus.IN_PROGRESS).count();
132+
int pendingTaskCount = (int) entry.getValue().stream().filter(t -> t.getTaskStatus() == TaskStatus.PENDING_COMPLETED).count();
133+
int totalTaskCount = inProgressTaskCount + pendingTaskCount;
134+
117135
return new TeamTaskResponse(
118136
entry.getKey(),
119137
entry.getValue().get(0).getProcessor().getNickname(),
@@ -125,8 +143,11 @@ public List<TeamTaskResponse> findTeamStatus(Long memberId, FilterTeamStatusRequ
125143
taskResponses
126144
);
127145
}).collect(Collectors.toList());
146+
128147
}
129148

149+
150+
130151
private boolean isValidTitle(FilterTeamStatusRequest filter) {
131152
return filter.taskTitle() != null && !filter.taskTitle().isEmpty();
132153
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
77
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
88
import io.lettuce.core.dynamic.annotation.Param;
9-
import org.springframework.data.domain.Page;
109
import org.springframework.data.domain.Pageable;
1110
import org.springframework.data.jpa.repository.JpaRepository;
1211
import org.springframework.data.jpa.repository.Query;
@@ -54,7 +53,7 @@ Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAf
5453
Long processorId, TaskStatus taskStatus, Long processorOrder);
5554

5655
@Query("SELECT t FROM TaskEntity t JOIN FETCH t.processor p WHERE (:memberId IS NULL OR p.memberId = :memberId) ")
57-
Page<TeamTaskResponse> findTeamStatus(@Param("memberId") Long memberId, FilterTeamStatusRequest filter, Pageable pageable);
56+
List<TeamTaskResponse> findTeamStatus(@Param("memberId") Long memberId, FilterTeamStatusRequest filter);
5857

5958
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndTaskIdLessThanOrderByTaskIdDesc(Long processorId, TaskStatus taskStatus, Long taskId);
6059

src/main/java/clap/server/application/port/inbound/task/LoadTeamStatusUsecase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
import org.springframework.data.domain.Pageable;
66

77
public interface LoadTeamStatusUsecase {
8-
TeamStatusResponse getTeamStatus(Long memberId, FilterTeamStatusRequest filter, Pageable pageable);
8+
TeamStatusResponse getTeamStatus(Long memberId, FilterTeamStatusRequest filter);
99
}
1010

src/main/java/clap/server/application/service/task/TeamStatusService.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import clap.server.application.port.inbound.task.FilterTeamStatusUsecase;
77
import clap.server.application.port.inbound.task.LoadTeamStatusUsecase;
88
import clap.server.application.port.outbound.task.LoadTaskPort;
9-
import org.springframework.data.domain.Pageable;
109
import org.springframework.stereotype.Service;
1110

1211
import java.util.List;
@@ -21,8 +20,8 @@ public TeamStatusService(LoadTaskPort loadTaskPort) {
2120
}
2221

2322
@Override
24-
public TeamStatusResponse getTeamStatus(Long memberId, FilterTeamStatusRequest filter, Pageable pageable) {
25-
List<TeamTaskResponse> members = loadTaskPort.findTeamStatus(memberId, filter); // 페이징 처리
23+
public TeamStatusResponse getTeamStatus(Long memberId, FilterTeamStatusRequest filter) {
24+
List<TeamTaskResponse> members = loadTaskPort.findTeamStatus(memberId, filter);
2625
return new TeamStatusResponse(members);
2726
}
2827

0 commit comments

Comments
 (0)