Skip to content

Commit 57e07e7

Browse files
authored
Merge pull request #235 from TaskFlow-CLAP/CLAP-213
CLAP-213 작업 도메인 레이어의 비즈니스 규칙과 정책을 분리
2 parents 788fe87 + a40647e commit 57e07e7

33 files changed

+434
-329
lines changed

src/main/java/clap/server/adapter/inbound/web/admin/FindMemberController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import clap.server.adapter.inbound.web.dto.admin.FindMemberRequest;
44
import clap.server.adapter.inbound.web.dto.admin.RetrieveAllMemberResponse;
55
import clap.server.application.mapper.RetrieveAllMemberMapper;
6-
import clap.server.application.port.inbound.management.FindAllMembersUsecase;
7-
import clap.server.application.port.inbound.management.FindMembersWithFilterUsecase;
6+
import clap.server.application.port.inbound.admin.FindAllMembersUsecase;
7+
import clap.server.application.port.inbound.admin.FindMembersWithFilterUsecase;
88
import clap.server.domain.model.member.Member;
99
import clap.server.exception.ApplicationException;
1010
import clap.server.exception.code.MemberErrorCode;

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import clap.server.application.port.inbound.task.FilterTaskBoardUsecase;
99
import clap.server.application.port.inbound.task.UpdateTaskBoardUsecase;
1010
import clap.server.application.port.inbound.task.GetTaskBoardUsecase;
11+
import clap.server.application.port.inbound.task.UpdateTaskOrderAndStatusUsecase;
1112
import clap.server.common.annotation.architecture.WebAdapter;
1213
import io.swagger.v3.oas.annotations.Operation;
1314
import io.swagger.v3.oas.annotations.Parameter;
@@ -35,15 +36,16 @@ public class TaskBoardController {
3536
private final GetTaskBoardUsecase getTaskBoardUsecase;
3637
private final FilterTaskBoardUsecase filterTaskBoardUsecase;
3738
private final UpdateTaskBoardUsecase updateTaskBoardUsecase;
39+
private final UpdateTaskOrderAndStatusUsecase updateTaskOrderAndStatus;
3840

3941
@Operation(summary = "작업 보드 조회 API")
4042
@Secured({"ROLE_MANAGER"})
41-
@PostMapping
43+
@GetMapping
4244
public ResponseEntity<TaskBoardResponse> getTaskBoard(@RequestParam(defaultValue = "0") int page,
4345
@RequestParam(defaultValue = "20") int pageSize,
44-
@Parameter(description = "완료 일자 조회 기준, yyyy-mm-dd 형식으로 입력합니다.") @RequestParam(required = false)
46+
@Parameter(description = "작업 완료 일자 조회 기준, yyyy-mm-dd 형식으로 입력합니다.") @RequestParam(required = false)
4547
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate untilDate,
46-
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "필터링 조회 request") @RequestBody(required = false) FilterTaskBoardRequest request,
48+
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "필터링 조회 request") @ModelAttribute FilterTaskBoardRequest request,
4749
@AuthenticationPrincipal SecurityUserDetails userInfo) {
4850
Pageable pageable = PageRequest.of(page, pageSize);
4951
if (request != null) {
@@ -62,7 +64,7 @@ public void updateTaskBoard(@Parameter(description = "전환될 작업의 상태
6264
if (status == null) {
6365
updateTaskBoardUsecase.updateTaskOrder(userInfo.getUserId(), request);
6466
} else {
65-
updateTaskBoardUsecase.updateTaskOrderAndStatus(userInfo.getUserId(), request, status);
67+
updateTaskOrderAndStatus.updateTaskOrderAndStatus(userInfo.getUserId(), request, status);
6668
}
6769
}
6870

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

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,20 @@
88
import clap.server.application.port.outbound.member.CommandMemberPort;
99
import clap.server.application.port.outbound.member.LoadMemberPort;
1010
import clap.server.common.annotation.architecture.PersistenceAdapter;
11-
import clap.server.domain.model.task.Task;
12-
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus ;
13-
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
14-
import clap.server.adapter.outbound.persistense.repository.task.TaskRepository;
15-
import clap.server.adapter.outbound.persistense.mapper.TaskPersistenceMapper;
16-
17-
import java.util.stream.Collectors;
18-
import java.util.List;
19-
2011
import clap.server.domain.model.member.Member;
21-
import com.querydsl.core.BooleanBuilder;
22-
import com.querydsl.jpa.impl.JPAQueryFactory;
2312
import lombok.RequiredArgsConstructor;
2413
import org.springframework.data.domain.Page;
25-
import org.springframework.data.domain.PageImpl;
2614
import org.springframework.data.domain.Pageable;
2715

2816
import java.util.List;
2917
import java.util.Optional;
3018
import java.util.stream.Collectors;
3119

32-
import static clap.server.adapter.outbound.persistense.entity.member.QMemberEntity.memberEntity;
33-
3420
@PersistenceAdapter
3521
@RequiredArgsConstructor
36-
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
22+
public class MemberPersistenceAdapter implements LoadMemberPort, CommandMemberPort {
3723
private final MemberRepository memberRepository;
3824
private final MemberPersistenceMapper memberPersistenceMapper;
39-
private final TaskRepository taskRepository;
40-
private final TaskPersistenceMapper taskPersistenceMapper;
41-
private final JPAQueryFactory jpaQueryFactory;
42-
4325

4426
@Override
4527
public Optional<Member> findById(final Long id) {
@@ -82,61 +64,13 @@ public void save(final Member member) {
8264

8365
@Override
8466
public Page<Member> findAllMembers(Pageable pageable) {
85-
return executeQueryWithPageable(pageable, new BooleanBuilder().and(memberEntity.status.ne(MemberStatus.DELETED)));
67+
return memberRepository.findAllMembers(pageable).map(memberPersistenceMapper::toDomain);
8668
}
8769

8870
@Override
8971
public Page<Member> findMembersWithFilter(Pageable pageable, FindMemberRequest filterRequest) {
90-
BooleanBuilder whereClause = createMemberFilter(filterRequest);
91-
return executeQueryWithPageable(pageable, whereClause);
92-
}
93-
94-
// 공통 쿼리 처리
95-
private Page<Member> executeQueryWithPageable(Pageable pageable, BooleanBuilder whereClause) {
96-
List<MemberEntity> entities = jpaQueryFactory
97-
.selectFrom(memberEntity)
98-
.where(whereClause)
99-
.offset(pageable.getOffset())
100-
.limit(pageable.getPageSize())
101-
.fetch();
102-
103-
long total = jpaQueryFactory
104-
.select(memberEntity.count())
105-
.from(memberEntity)
106-
.where(whereClause)
107-
.fetchOne();
108-
109-
return new PageImpl<>(
110-
entities.stream()
111-
.map(memberPersistenceMapper::toDomain)
112-
.toList(),
113-
pageable,
114-
total
115-
);
116-
}
117-
118-
// 필터 조건 생성
119-
private BooleanBuilder createMemberFilter(FindMemberRequest filterRequest) {
120-
BooleanBuilder whereClause = new BooleanBuilder();
121-
whereClause.and(memberEntity.status.ne(MemberStatus.DELETED));
122-
123-
if (filterRequest.name() != null) {
124-
whereClause.and(memberEntity.name.containsIgnoreCase(filterRequest.name()));
125-
}
126-
if (filterRequest.email() != null) {
127-
whereClause.and(memberEntity.email.containsIgnoreCase(filterRequest.email()));
128-
}
129-
if (filterRequest.nickName() != null) {
130-
whereClause.and(memberEntity.nickname.containsIgnoreCase(filterRequest.nickName()));
131-
}
132-
if (filterRequest.departmentName() != null) {
133-
whereClause.and(memberEntity.department.name.containsIgnoreCase(filterRequest.departmentName()));
134-
}
135-
if (filterRequest.role() != null) {
136-
whereClause.and(memberEntity.role.eq(filterRequest.role()));
137-
}
72+
return memberRepository.findMembersWithFilter(pageable, filterRequest).map(memberPersistenceMapper::toDomain);
13873

139-
return whereClause;
14074
}
14175
}
14276

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package clap.server.adapter.outbound.persistense.entity.task.constant;
22

3-
import com.fasterxml.jackson.annotation.JsonCreator;
43
import lombok.Getter;
54
import lombok.RequiredArgsConstructor;
65

7-
import java.util.List;
8-
96
@Getter
107
@RequiredArgsConstructor
118
public enum TaskStatus {
@@ -16,11 +13,4 @@ public enum TaskStatus {
1613
TERMINATED("종료");
1714

1815
private final String description;
19-
20-
public static List<TaskStatus> getTaskBoardStatusList() {
21-
return List.of(
22-
TaskStatus.IN_PROGRESS,
23-
TaskStatus.PENDING_COMPLETED,
24-
TaskStatus.COMPLETED);
25-
}
2616
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package clap.server.adapter.outbound.persistense.repository.member;
2+
3+
import clap.server.adapter.inbound.web.dto.admin.FindMemberRequest;
4+
import clap.server.adapter.outbound.persistense.entity.member.MemberEntity;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface MemberCustomRepository {
9+
Page<MemberEntity> findAllMembers(Pageable pageable);
10+
Page<MemberEntity> findMembersWithFilter(Pageable pageable, FindMemberRequest filterRequest) ;
11+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package clap.server.adapter.outbound.persistense.repository.member;
2+
3+
import clap.server.adapter.inbound.web.dto.admin.FindMemberRequest;
4+
import clap.server.adapter.outbound.persistense.entity.member.MemberEntity;
5+
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
6+
import com.querydsl.core.BooleanBuilder;
7+
import com.querydsl.jpa.impl.JPAQueryFactory;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.data.domain.Page;
10+
import org.springframework.data.domain.PageImpl;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.stereotype.Repository;
13+
14+
import java.util.List;
15+
16+
import static clap.server.adapter.outbound.persistense.entity.member.QMemberEntity.memberEntity;
17+
18+
@Repository
19+
@RequiredArgsConstructor
20+
public class MemberCustomRepositoryImpl implements MemberCustomRepository {
21+
private final JPAQueryFactory queryFactory;
22+
23+
private Page<MemberEntity> executeQueryWithPageable(Pageable pageable, BooleanBuilder whereClause) {
24+
List<MemberEntity> result = queryFactory
25+
.selectFrom(memberEntity)
26+
.where(whereClause)
27+
.offset(pageable.getOffset())
28+
.limit(pageable.getPageSize())
29+
.fetch();
30+
31+
long total = queryFactory
32+
.select(memberEntity.count())
33+
.from(memberEntity)
34+
.where(whereClause)
35+
.fetch().size();
36+
37+
return new PageImpl<>(
38+
result,
39+
pageable,
40+
total
41+
);
42+
}
43+
44+
// 필터 조건 생성
45+
private BooleanBuilder createMemberFilter(FindMemberRequest filterRequest) {
46+
BooleanBuilder whereClause = new BooleanBuilder();
47+
whereClause.and(memberEntity.status.ne(MemberStatus.DELETED));
48+
49+
if (filterRequest.name() != null) {
50+
whereClause.and(memberEntity.name.containsIgnoreCase(filterRequest.name()));
51+
}
52+
if (filterRequest.email() != null) {
53+
whereClause.and(memberEntity.email.containsIgnoreCase(filterRequest.email()));
54+
}
55+
if (filterRequest.nickName() != null) {
56+
whereClause.and(memberEntity.nickname.containsIgnoreCase(filterRequest.nickName()));
57+
}
58+
if (filterRequest.departmentName() != null) {
59+
whereClause.and(memberEntity.department.name.eq(filterRequest.departmentName()));
60+
}
61+
if (filterRequest.role() != null) {
62+
whereClause.and(memberEntity.role.eq(filterRequest.role()));
63+
}
64+
65+
return whereClause;
66+
}
67+
68+
@Override
69+
public Page<MemberEntity> findAllMembers(Pageable pageable) {
70+
return executeQueryWithPageable(pageable, new BooleanBuilder().and(memberEntity.status.ne(MemberStatus.DELETED)));
71+
}
72+
73+
@Override
74+
public Page<MemberEntity> findMembersWithFilter(Pageable pageable, FindMemberRequest filterRequest) {
75+
BooleanBuilder whereClause = createMemberFilter(filterRequest);
76+
return executeQueryWithPageable(pageable, whereClause);
77+
}
78+
}

src/main/java/clap/server/adapter/outbound/persistense/repository/member/MemberRepository.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole;
55
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
66
import org.springframework.data.jpa.repository.JpaRepository;
7-
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
87
import org.springframework.stereotype.Repository;
98

109
import java.util.List;
1110
import java.util.Optional;
1211

1312
@Repository
14-
public interface MemberRepository extends JpaRepository<MemberEntity, Long>, JpaSpecificationExecutor<MemberEntity> {
13+
public interface MemberRepository extends JpaRepository<MemberEntity, Long>, MemberCustomRepository {
1514

1615

1716
List<MemberEntity> findByRoleAndStatus(MemberRole role, MemberStatus status);
@@ -23,6 +22,9 @@ public interface MemberRepository extends JpaRepository<MemberEntity, Long>, Jpa
2322

2423
List<MemberEntity> findByIsReviewerTrue();
2524

25+
List<MemberEntity> findAll(); // 전체 회원 조회
26+
27+
2628
Optional<MemberEntity> findByMemberIdAndIsReviewerTrue(Long memberId);
2729
}
2830

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
import java.util.List;
1919

2020
import static clap.server.adapter.outbound.persistense.entity.task.QTaskEntity.taskEntity;
21-
import static com.querydsl.core.types.Order.*;
21+
import static com.querydsl.core.types.Order.ASC;
22+
import static com.querydsl.core.types.Order.DESC;
2223

2324
@Repository
2425
@RequiredArgsConstructor

src/main/java/clap/server/application/mapper/AttachmentMapper.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,6 @@ public static List<Attachment> toTaskAttachments(Task task, List<MultipartFile>
2828
.toList();
2929
}
3030

31-
public static List<Attachment> toCommentAttachments(Task task, Comment comment, List<MultipartFile> files, List<String> fileUrls) {
32-
return IntStream.range(0, files.size())
33-
.mapToObj(i -> createCommentAttachment(
34-
task,
35-
comment,
36-
files.get(i).getOriginalFilename(),
37-
fileUrls.get(i),
38-
files.get(i).getSize()
39-
))
40-
.toList();
41-
}
42-
4331

4432
public static List<AttachmentResponse> toAttachmentResponseList(List<Attachment> attachments) {
4533
return attachments.stream()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package clap.server.application.port.inbound.admin;
2+
3+
import clap.server.domain.model.member.Member;
4+
import org.springframework.data.domain.Page;
5+
import org.springframework.data.domain.Pageable;
6+
7+
public interface FindAllMembersUsecase {
8+
Page<Member> findAllMembers(Pageable pageable);
9+
}

0 commit comments

Comments
 (0)