Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5155ff7
CLAP-110 Feature : 담당자별 작업 처리량 조회 API 구현
hyoseong-Choi Jan 23, 2025
b7f2c2a
CLAP-111 Refactor : 통계 조회 API 리팩토링 및 기능 수정
hyoseong-Choi Jan 23, 2025
87d0fdb
내 작업한 내용에 대한 설명
nano-mm Jan 23, 2025
534aa24
담당자 조회 API 구현
nano-mm Jan 24, 2025
2b7f448
CLAP-111 Refactor : 통계 조회 API 주소 통합, 리팩토링, 예외처리
hyoseong-Choi Jan 24, 2025
72a66e4
Bug : 프로퍼티파일 수정
hyoseong-Choi Jan 24, 2025
8458cbd
CLAP-104 CI/CD : CI에서 s3.yml 파일 생성하도록 수정
hyoseong-Choi Jan 26, 2025
eb34ee8
CLAP-146 Feature : 카테고리 목록 조회 API 구현
hyoseong-Choi Jan 26, 2025
8146776
CLAP-147 Feature : 카테고리 수정 API 구현
hyoseong-Choi Jan 26, 2025
d24fdf8
CLAP-147 Feature : 카테고리 추가, 수정 API 리뷰반영 수정
hyoseong-Choi Jan 28, 2025
a0ebd44
CLAP-148 Feature : 카테고리 삭제 API 구현
hyoseong-Choi Jan 28, 2025
5fcc496
Merge branch 'develop' into CLAP-148
hyoseong-Choi Jan 28, 2025
0ff4b3b
CLAP-148 Feature : 카테고리 삭제 API 수정
hyoseong-Choi Jan 28, 2025
eefe6ee
CLAP-148 Docs : 카테고리 API 스웨거 수정
hyoseong-Choi Jan 28, 2025
b30cdde
CLAP-107 Bug : CI test yml파일 key 중복 수정
hyoseong-Choi Jan 29, 2025
c3292fe
CLAP-148 Feature : 카테고리 CUD 리뷰 반영 수정, 조회 반환 양식 수정
hyoseong-Choi Jan 30, 2025
2d63e7e
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Jan 30, 2025
5085370
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 2, 2025
915e6f9
CLAP-214 Cleanup : 통계, 카테고리 미흡한부분 리팩토링
hyoseong-Choi Feb 2, 2025
27e09cc
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 2, 2025
68c9f08
CLAP-214 Fix : 통계조회 API 파라미터 바인딩 오류 수정
hyoseong-Choi Feb 2, 2025
4f338ad
CLAP-214 Fix : addConverter 수정
hyoseong-Choi Feb 2, 2025
51ab7a5
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 2, 2025
67fc667
CLAP-214 Hotfix : 추가한 파일들 제거
hyoseong-Choi Feb 2, 2025
e4dc477
CLAP-214 Hotfix : FindStatisticsController 스위치문 수정
hyoseong-Choi Feb 2, 2025
4875e32
CLAP-214 Hotfix : AddCategoryService 지연로딩 오류 수정
hyoseong-Choi Feb 2, 2025
ebd4bcd
CLAP-214 Hotfix : DeleteCategoryService 카테고리 삭제 로직 수정
hyoseong-Choi Feb 3, 2025
3e2f5ed
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 3, 2025
4a5e4f0
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 3, 2025
a2292c8
CLAP-249 Refactor : 통계 조회 서비스 리팩토링
hyoseong-Choi Feb 3, 2025
520f47f
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 3, 2025
93531b5
CLAP-250 Test : 통계 조회 테스트코드 작성
hyoseong-Choi Feb 3, 2025
280d930
CLAP-214 Hotifx : 카테고리 수정 로직 수정
hyoseong-Choi Feb 4, 2025
7be324a
CLAP-214 Hotifx : 카테고리 수정 로직 수정
hyoseong-Choi Feb 4, 2025
2381888
CLAP-256 fix: 스웨거 명세 추가
nano-mm Feb 4, 2025
e291921
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 5, 2025
efaaee3
CLAP-214 Hotifx : 카테고리 저장 트랜잭션 추가
hyoseong-Choi Feb 5, 2025
0e10e86
CLAP-214 Hotifx : 카테고리 저장 시간 수정
hyoseong-Choi Feb 5, 2025
40bc614
CLAP-285 Hotifx : 모든 카테고리 조회
hyoseong-Choi Feb 5, 2025
876c3ef
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 5, 2025
6ec2bd9
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 5, 2025
14db203
CLAP-214 Hotifx : 카테고리 조회 Secured 설정
hyoseong-Choi Feb 5, 2025
d87498c
CLAP-256 fix: convert 동작 mapper 추가
nano-mm Feb 5, 2025
bad0cef
CLAP-256 fix: conflict 해결
nano-mm Feb 5, 2025
844b838
CLAP-256 fix: 충돌해결
nano-mm Feb 6, 2025
893715e
CLAP-256 fix: 불필요한 테스트 파일 제거
nano-mm Feb 6, 2025
5b0b58e
CLAP-256 fix: 충돌 재해결
nano-mm Feb 6, 2025
0e4b6d7
CLAP-256 fix: mapper statuslabel 수정
nano-mm Feb 6, 2025
06b3279
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 6, 2025
d5c2a68
Merge branch 'CLAP-256-팀-작업-현황-에러-재수정' of https://github.com/TaskFlow…
hyoseong-Choi Feb 6, 2025
edca909
CLAP-256 Fix : 팀 작업 현황 필터링 조회 수정
hyoseong-Choi Feb 6, 2025
5626fd3
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 6, 2025
b6929d6
CLAP-299 Feature : 사용자 작업 취소
hyoseong-Choi Feb 6, 2025
95b1c26
Merge branch 'develop' of https://github.com/TaskFlow-CLAP/TaskFlow-S…
hyoseong-Choi Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package clap.server.adapter.inbound.web.dto.task.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package clap.server.adapter.inbound.web.task;

import clap.server.application.port.inbound.task.CancelTaskUsecase;
import clap.server.common.annotation.architecture.WebAdapter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Tag(name = "02. Task [거부 & 종료]")
@RequestMapping("/api/tasks")
@RequiredArgsConstructor
@WebAdapter
public class CancelTaskController {
private final CancelTaskUsecase cancelTaskUsecase;

@Operation(summary = "작업 취소")
@Secured("ROLE_USER")
@PatchMapping("/{taskId}/cancle")
public void cancelTask(@PathVariable Long taskId) {
cancelTaskUsecase.cancleTask(taskId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
import clap.server.application.port.inbound.task.FindManagersUsecase;
import clap.server.adapter.inbound.web.dto.task.response.FindManagersResponse;
import clap.server.common.annotation.architecture.WebAdapter;
import io.swagger.v3.oas.annotations.Operation;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Tag(name = "02. Task [조회]")
@WebAdapter
@RequestMapping("/api/managers")
@RequiredArgsConstructor
public class ManagerController {
private final FindManagersUsecase findManagersUsecase;

@Operation(summary = "담당자 조회 API")
@GetMapping
public ResponseEntity<List<FindManagersResponse>> findManagers() {
return ResponseEntity.ok(findManagersUsecase.findManagers());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@Tag(name = "02. Task [담당자]")
@WebAdapter
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/team-status")
public class TeamStatusController {

@RequiredArgsConstructor
@WebAdapter
public class TeamStatusController {

private final TeamStatusService teamStatusService;
@Operation(summary = "팀 현황 필터링 조회 API")
@GetMapping("/filter")
public ResponseEntity<TeamStatusResponse> filterTeamStatus(@ModelAttribute FilterTeamStatusRequest filter) {
TeamStatusResponse response = teamStatusService.filterTeamStatus(filter);
return ResponseEntity.ok(response != null ? response : new TeamStatusResponse(List.of(), 0, 0, 0));
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package clap.server.adapter.outbound.persistense;

import clap.server.adapter.inbound.web.dto.task.request.FilterTaskBoardRequest;
import clap.server.adapter.inbound.web.dto.task.request.FilterTaskListRequest;
import clap.server.adapter.inbound.web.dto.task.request.FilterTaskBoardRequest;
import clap.server.adapter.inbound.web.dto.task.request.FilterTeamStatusRequest;
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskResponse;
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
Expand All @@ -23,7 +23,6 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.http.ResponseEntity;

import java.time.LocalDateTime;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public enum TaskStatus {
REQUESTED("요청"),
IN_PROGRESS("진행 중"),
IN_REVIEWING("완료 대기"),
IN_REVIEWING("검토중"),
COMPLETED("완료"),
TERMINATED("종료");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Optional;

import static clap.server.adapter.outbound.persistense.entity.task.QTaskEntity.taskEntity;
import static com.querydsl.core.types.Order.ASC;
Expand Down Expand Up @@ -102,6 +103,11 @@ public List<TeamTaskResponse> findTeamStatus(Long memberId, FilterTeamStatusRequ
.orderBy(orderBy)
.fetch();

// null 또는 빈 리스트 처리
if (taskEntities == null || taskEntities.isEmpty()) {
return List.of(); // 빈 리스트 반환
}

return taskEntities.stream()
.collect(Collectors.groupingBy(t -> t.getProcessor().getMemberId()))
.entrySet().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,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.domain.Pageable;
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 Down Expand Up @@ -52,7 +49,7 @@ List<TaskEntity> findTasksWithTaskStatusAndCompletedAt(
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderAsc(
Long processorId, TaskStatus taskStatus, Long processorOrder);

@Query("SELECT t FROM TaskEntity t JOIN FETCH t.processor p WHERE (:memberId IS NULL OR p.memberId = :memberId) ")
// @Query("SELECT t FROM TaskEntity t JOIN FETCH t.processor p WHERE (:memberId IS NULL OR p.memberId = :memberId) ")
List<TeamTaskResponse> findTeamStatus(@Param("memberId") Long memberId, FilterTeamStatusRequest filter);

Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndTaskIdLessThanOrderByTaskIdDesc(Long processorId, TaskStatus taskStatus, Long taskId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


import clap.server.adapter.inbound.web.dto.task.response.*;
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.TaskStatus;
import clap.server.domain.model.member.Member;
import clap.server.domain.model.task.Attachment;
Expand Down Expand Up @@ -193,4 +195,61 @@ public static FindManagersResponse toFindManagersResponse(Member manager, int re
remainingTasks
);
}

public static TeamStatusResponse toTeamStatusResponse(List<TaskEntity> taskEntities) {
// 담당자별로 그룹화
Map<Long, List<TaskEntity>> tasksByProcessor = taskEntities.stream()
.collect(Collectors.groupingBy(taskEntity -> taskEntity.getProcessor().getMemberId()));

List<TeamTaskResponse> memberResponses = tasksByProcessor.entrySet().stream()
.map(entry -> {
List<TeamTaskItemResponse> teamtaskItemResponses = entry.getValue().stream()
.map(TaskResponseMapper::toTeamTaskItemResponse)
.collect(Collectors.toList());

return new TeamTaskResponse(
entry.getKey(),
entry.getValue().get(0).getProcessor().getNickname(),
entry.getValue().get(0).getProcessor().getImageUrl(),
entry.getValue().get(0).getProcessor().getDepartment().getName(),
(int) entry.getValue().stream().filter(t -> t.getTaskStatus() == TaskStatus.IN_PROGRESS).count(),
(int) entry.getValue().stream().filter(t -> t.getTaskStatus() == TaskStatus.IN_REVIEWING).count(),
entry.getValue().size(),
teamtaskItemResponses
);
})
.collect(Collectors.toList());

return new TeamStatusResponse(memberResponses);
}

public static TeamTaskItemResponse toTeamTaskItemResponse(TaskEntity taskEntity) {
return new TeamTaskItemResponse(
taskEntity.getTaskId(),
taskEntity.getTaskCode(),
taskEntity.getTitle(),
taskEntity.getCategory().getMainCategory().getName(),
taskEntity.getCategory().getName(),
taskEntity.getLabel() != null ? toLabelInfo(taskEntity.getLabel()) : null,
taskEntity.getRequester().getNickname(),
taskEntity.getRequester().getImageUrl(),
taskEntity.getRequester().getDepartment().getName(),
taskEntity.getProcessorOrder(),
taskEntity.getTaskStatus(),
taskEntity.getCreatedAt()
);
}

public static TeamTaskItemResponse.LabelInfo toLabelInfo(LabelEntity label) { // Label → LabelEntity로 변경
return new TeamTaskItemResponse.LabelInfo(
label.getLabelName(),
label.getLabelColor()
);
}






}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package clap.server.application.port.inbound.task;

public interface CancelTaskUsecase {
void cancleTask(Long taskId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package clap.server.application.service.task;

import clap.server.application.port.inbound.domain.TaskService;
import clap.server.application.port.inbound.task.CancelTaskUsecase;
import clap.server.common.annotation.architecture.ApplicationService;
import clap.server.domain.model.task.Task;
import lombok.RequiredArgsConstructor;


@ApplicationService
@RequiredArgsConstructor
public class CancelTaskService implements CancelTaskUsecase {
private final TaskService taskService;

@Override
public void cancleTask(Long taskId) {
Task task = taskService.findById(taskId);
task.cancelTask();
taskService.upsert(task);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package clap.server.application.service.task;

import clap.server.adapter.inbound.web.dto.task.request.FilterTeamStatusRequest;
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskResponse;
import clap.server.adapter.inbound.web.dto.task.response.TeamStatusResponse;
import clap.server.adapter.inbound.web.dto.task.response.TeamTaskResponse;
import clap.server.application.port.inbound.task.FilterTeamStatusUsecase;
import clap.server.application.port.inbound.task.LoadTeamStatusUsecase;
import clap.server.application.port.outbound.task.LoadTaskPort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

Expand All @@ -22,12 +23,19 @@ public TeamStatusService(LoadTaskPort loadTaskPort) {
@Override
public TeamStatusResponse getTeamStatus(Long memberId, FilterTeamStatusRequest filter) {
List<TeamTaskResponse> members = loadTaskPort.findTeamStatus(memberId, filter);
if (members == null) {
members = List.of();
}
return new TeamStatusResponse(members);
}

@Override
@Transactional(readOnly = true)
public TeamStatusResponse filterTeamStatus(FilterTeamStatusRequest filter) {
List<TeamTaskResponse> members = loadTaskPort.findTeamStatus(null, filter);
if (members == null) {
members = List.of();
}
return new TeamStatusResponse(members);
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/clap/server/domain/model/task/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,9 @@ private static String toTaskCode(Category category) {
public void updateProcessorOrder(long newProcessorOrder) {
this.processorOrder = newProcessorOrder;
}

public void cancelTask() {
this.taskStatus = TaskStatus.TERMINATED;
this.finishedAt = LocalDateTime.now();
}
}