Skip to content

Commit df80537

Browse files
Merge pull request #50 from TaskFlow-CLAP/CLAP-92
CLAP-92 기간별 작업 처리량 조회
2 parents 252dd12 + a76ec0f commit df80537

File tree

15 files changed

+288
-92
lines changed

15 files changed

+288
-92
lines changed
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package clap.server.adapter.inbound.web.statistics;
22

3+
import clap.server.application.port.inbound.statistics.CategoryTaskRequestUsecase;
34
import clap.server.application.port.inbound.statistics.PeriodTaskProcessUsecase;
45
import clap.server.application.port.inbound.statistics.PeriodTaskRequestUsecase;
6+
import clap.server.application.port.inbound.statistics.SubCategoryTaskRequestUsecase;
57
import clap.server.common.annotation.architecture.WebAdapter;
68
import lombok.RequiredArgsConstructor;
79
import org.springframework.web.bind.annotation.GetMapping;
@@ -13,21 +15,28 @@
1315
@RequiredArgsConstructor
1416
public class StatisticsFindController {
1517
private final PeriodTaskRequestUsecase periodTaskRequestUsecase;
16-
// private final PeriodTaskProcessUsecase periodTaskProcessUsecase;
17-
// private final CategoryTaskRequestUsecase categoryTaskRequestUsecase;
18-
// private final SubCategoryTaskRequestUsecase subCategoryTaskRequestUsecase;
18+
private final PeriodTaskProcessUsecase periodTaskProcessUsecase;
19+
private final CategoryTaskRequestUsecase categoryTaskRequestUsecase;
20+
private final SubCategoryTaskRequestUsecase subCategoryTaskRequestUsecase;
1921
// private final ManagerTaskProcessUsecase managerTaskProcessUsecase;
2022

2123
@GetMapping(value = "/task/statistics/task-requests-by-period")
2224
public Map<String, Long> aggregatePeriodTaskRequest(@RequestParam String period) {
2325
return periodTaskRequestUsecase.periodTaskRequestAggregate(period);
2426
}
2527

26-
// @GetMapping("/task/statistics/task-processed-by-period")
27-
//
28-
// @GetMapping("/task/statistics/task-requests-by-category")
29-
//
30-
// @GetMapping("/task/statistics/task-requests-by-subcategory")
31-
//
28+
@GetMapping("/task/statistics/task-processed-by-period")
29+
public Map<String, Long> aggregatePeriodTaskProcess(@RequestParam String period) {
30+
return periodTaskProcessUsecase.periodTaskProcessAggregate(period);
31+
}
32+
@GetMapping("/task/statistics/task-requests-by-category")
33+
public Map<String, Long> aggregateCategoryTaskRequest(@RequestParam String period) {
34+
return categoryTaskRequestUsecase.categoryTaskRequestAggregate(period);
35+
}
36+
37+
@GetMapping("/task/statistics/task-requests-by-subcategory")
38+
public Map<String, Long> aggregateSubCategoryTaskRequest(@RequestParam String period, @RequestParam String mainCategory) {
39+
return subCategoryTaskRequestUsecase.subCategoryTaskRequestAggregate(period, mainCategory);
40+
}
3241
// @GetMapping("/task/statistics/tasks-processed-by-manager")
3342
}

src/main/java/clap/server/adapter/outbound/infrastructure/elastic/ElasticTaskAdapter.java

Lines changed: 114 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package clap.server.adapter.outbound.infrastructure.elastic;
22

3-
import clap.server.adapter.outbound.infrastructure.elastic.dto.PeriodConfig;
43
import clap.server.adapter.outbound.infrastructure.elastic.entity.ElasticTask;
54
import clap.server.adapter.outbound.infrastructure.elastic.repository.TaskElasticRepository;
65
import clap.server.application.port.outbound.task.ElasticTaskPort;
76
import clap.server.common.annotation.architecture.InfrastructureAdapter;
87
import co.elastic.clients.elasticsearch._types.aggregations.AggregationBuilders;
9-
import co.elastic.clients.elasticsearch._types.aggregations.CalendarInterval;
108
import co.elastic.clients.elasticsearch._types.aggregations.MultiBucketBase;
119
import lombok.RequiredArgsConstructor;
1210
import org.springframework.data.elasticsearch.client.elc.ElasticsearchAggregations;
@@ -32,30 +30,111 @@ public void saveStatistics(List<ElasticTask> statistics) {
3230

3331
@Override
3432
public Map<String, Long> findPeriodTaskRequestByPeriod(String period) {
35-
PeriodConfig periodConfig = getPeriodConfig(period);
33+
PeriodConfig periodConfig = PeriodConfig.valueOf(period.toUpperCase());
3634

37-
NativeQuery query = buildQuery(periodConfig);
38-
ElasticsearchAggregations result = executeQuery(query);
39-
return processResults(result, periodConfig);
35+
NativeQuery query = buildPeriodTaskRequestQuery(periodConfig);
36+
return getPeriodTaskResults(executeQuery(query), periodConfig);
4037
}
4138

42-
private PeriodConfig getPeriodConfig(String period) {
43-
if (period.equals("week")) {
44-
return new PeriodConfig(14, CalendarInterval.Day, 0, 10);
45-
}
46-
return new PeriodConfig(1, CalendarInterval.Hour, 11, 19);
39+
@Override
40+
public Map<String, Long> findPeriodTaskProcessByPeriod(String period) {
41+
PeriodConfig periodConfig = PeriodConfig.valueOf(period.toUpperCase());
42+
43+
NativeQuery query = buildPeriodTaskProcessQuery(periodConfig);
44+
return getPeriodTaskResults(executeQuery(query), periodConfig);
45+
}
46+
47+
@Override
48+
public Map<String, Long> findCategoryTaskRequestByPeriod(String period) {
49+
PeriodConfig periodConfig = PeriodConfig.valueOf(period.toUpperCase());
50+
51+
NativeQuery query = buildCategoryTaskRequestQuery(periodConfig);
52+
return getCategoryTaskResults(executeQuery(query));
4753
}
4854

49-
private NativeQuery buildQuery(PeriodConfig config) {
55+
@Override
56+
public Map<String, Long> findSubCategoryTaskRequestByPeriod(String period, String mainCategory) {
57+
PeriodConfig periodConfig = PeriodConfig.valueOf(period.toUpperCase());
58+
59+
NativeQuery query = buildSubCategoryTaskRequestQuery(periodConfig, mainCategory);
60+
return getCategoryTaskResults(executeQuery(query));
61+
}
62+
63+
private NativeQuery buildPeriodTaskRequestQuery(PeriodConfig config) {
5064
return NativeQuery.builder()
5165
.withQuery(q -> q
5266
.range(r -> r
5367
.date(d -> d
5468
.field("created_at")
55-
.gte(String.valueOf(LocalDate.now().minusDays(config.daysToSubtract()))))))
56-
.withAggregation("period_task_request", AggregationBuilders.dateHistogram()
69+
.gte(String.valueOf(LocalDate.now().minusDays(config.getDaysToSubtract()))))))
70+
.withAggregation("period_task", AggregationBuilders.dateHistogram()
71+
.field("created_at")
72+
.calendarInterval(config.getCalendarInterval())
73+
.build()._toAggregation())
74+
.withMaxResults(0)
75+
.build();
76+
}
77+
78+
private NativeQuery buildPeriodTaskProcessQuery(PeriodConfig config) {
79+
NativeQuery rangeQuery = NativeQuery.builder()
80+
.withQuery(q -> q
81+
.range(r -> r
82+
.date(d -> d
83+
.field("created_at")
84+
.gte(String.valueOf(LocalDate.now().minusDays(config.getDaysToSubtract())))))).build();
85+
NativeQuery statusQuery = NativeQuery.builder()
86+
.withQuery(q -> q
87+
.term(v -> v
88+
.field("status")
89+
.value("completed"))).build();
90+
91+
return NativeQuery.builder()
92+
.withQuery(q -> q
93+
.bool(b -> b
94+
.must(rangeQuery.getQuery(), statusQuery.getQuery()))
95+
)
96+
.withAggregation("period_task", AggregationBuilders.dateHistogram()
5797
.field("created_at")
58-
.calendarInterval(config.calendarInterval())
98+
.calendarInterval(config.getCalendarInterval())
99+
.build()._toAggregation())
100+
.withMaxResults(0)
101+
.build();
102+
}
103+
104+
private NativeQuery buildCategoryTaskRequestQuery(PeriodConfig config) {
105+
return NativeQuery.builder()
106+
.withQuery(q -> q
107+
.range(r -> r
108+
.date(d -> d
109+
.field("created_at")
110+
.gte(String.valueOf(LocalDate.now().minusDays(config.getDaysToSubtract()))))))
111+
.withAggregation("category_task", AggregationBuilders.terms()
112+
.field("main_category")
113+
.build()._toAggregation())
114+
.withMaxResults(0)
115+
.build();
116+
}
117+
118+
private NativeQuery buildSubCategoryTaskRequestQuery(PeriodConfig config, String mainCategory) {
119+
NativeQuery rangeQuery = NativeQuery.builder()
120+
.withQuery(q -> q
121+
.range(r -> r
122+
.date(d -> d
123+
.field("created_at")
124+
.gte(String.valueOf(LocalDate.now().minusDays(config.getDaysToSubtract())))))).build();
125+
NativeQuery categoryQuery = NativeQuery.builder()
126+
.withQuery(q -> q
127+
.term(v -> v
128+
.field("main_category")
129+
.value(mainCategory))).build();
130+
131+
return NativeQuery.builder()
132+
.withQuery(q -> q
133+
.bool(b -> b
134+
.must(rangeQuery.getQuery(), categoryQuery.getQuery()))
135+
)
136+
.withAggregation("category_task", AggregationBuilders.terms()
137+
.field("sub_category")
59138
.build()._toAggregation())
60139
.withMaxResults(0)
61140
.build();
@@ -67,9 +146,9 @@ private ElasticsearchAggregations executeQuery(NativeQuery query) {
67146
.getAggregations();
68147
}
69148

70-
private Map<String, Long> processResults(ElasticsearchAggregations aggregations, PeriodConfig config) {
149+
private Map<String, Long> getPeriodTaskResults(ElasticsearchAggregations aggregations, PeriodConfig config) {
71150
return new TreeMap<>(
72-
aggregations.get("period_task_request")
151+
aggregations.get("period_task")
73152
.aggregation()
74153
.getAggregate()
75154
.dateHistogram()
@@ -78,11 +157,27 @@ private Map<String, Long> processResults(ElasticsearchAggregations aggregations,
78157
.stream()
79158
.collect(Collectors.toMap(
80159
bucket -> bucket.keyAsString().substring(
81-
config.substringStart(),
82-
config.substringEnd()
160+
config.getSubstringStart(),
161+
config.getSubstringEnd()
83162
),
84163
MultiBucketBase::docCount
85164
))
86165
);
87166
}
167+
168+
private Map<String, Long> getCategoryTaskResults(ElasticsearchAggregations aggregations) {
169+
return new TreeMap<>(
170+
aggregations.get("category_task")
171+
.aggregation()
172+
.getAggregate()
173+
.sterms()
174+
.buckets()
175+
.array()
176+
.stream()
177+
.collect(Collectors.toMap(
178+
bucket -> bucket.key().stringValue(),
179+
MultiBucketBase::docCount
180+
))
181+
);
182+
}
88183
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package clap.server.adapter.outbound.infrastructure.elastic;
2+
3+
import co.elastic.clients.elasticsearch._types.aggregations.CalendarInterval;
4+
import lombok.Getter;
5+
import lombok.RequiredArgsConstructor;
6+
7+
@Getter
8+
@RequiredArgsConstructor
9+
public enum PeriodConfig {
10+
DAY(1, CalendarInterval.Hour, 11, 19),
11+
WEEK(14, CalendarInterval.Day, 0, 10);
12+
13+
private final long daysToSubtract;
14+
private final CalendarInterval calendarInterval;
15+
private final int substringStart;
16+
private final int substringEnd;
17+
18+
}

src/main/java/clap/server/adapter/outbound/infrastructure/elastic/dto/PeriodConfig.java

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/main/java/clap/server/adapter/outbound/infrastructure/elastic/entity/ElasticTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public ElasticTask(TaskEntity taskEntity) {
3333
this.taskCode = taskEntity.getTaskCode();
3434
this.mainCategory = taskEntity.getCategory().getMainCategory().getName();
3535
this.subCategory = taskEntity.getCategory().getName();
36-
this.status = taskEntity.getStatus().getName();
36+
this.status = taskEntity.getStatus().getStatusName().name().toLowerCase();
3737
this.processor = taskEntity.getProcessor().getNickname();
3838
this.createdAt = taskEntity.getCreatedAt().toLocalDate();
3939
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
55
import clap.server.adapter.outbound.persistense.mapper.MemberPersistenceMapper;
66
import clap.server.adapter.outbound.persistense.repository.member.MemberRepository;
7-
import clap.server.application.port.outbound.member.LoadMemberPort;
87
import clap.server.application.port.outbound.member.CommandMemberPort;
8+
import clap.server.application.port.outbound.member.LoadMemberPort;
99
import clap.server.common.annotation.architecture.PersistenceAdapter;
1010
import clap.server.domain.model.member.Member;
1111
import lombok.RequiredArgsConstructor;
@@ -26,7 +26,7 @@ public Optional<Member> findById(final Long id) {
2626

2727
@Override
2828
public Optional<Member> findActiveMemberById(final Long id) {
29-
Optional<MemberEntity> memberEntity = memberRepository.findByMemberStatusAndMemberId(MemberStatus.ACTIVE, id);
29+
Optional<MemberEntity> memberEntity = memberRepository.findByStatusAndMemberId(MemberStatus.ACTIVE, id);
3030
return memberEntity.map(memberPersistenceMapper::toDomain);
3131
}
3232

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99

1010
@Repository
1111
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
12-
Optional<MemberEntity> findByMemberStatusAndMemberId(MemberStatus memberStatus, Long memberId);
12+
Optional<MemberEntity> findByStatusAndMemberId(MemberStatus Status, Long memberId);
1313
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package clap.server.application.port.inbound.statistics;
2+
3+
import java.util.Map;
4+
5+
public interface CategoryTaskRequestUsecase {
6+
Map<String, Long> categoryTaskRequestAggregate(String period);
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package clap.server.application.port.inbound.statistics;
2+
3+
import java.util.Map;
4+
5+
public interface PeriodTaskProcessUsecase {
6+
Map<String, Long> periodTaskProcessAggregate(String period);
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package clap.server.application.port.inbound.statistics;
2+
3+
import java.util.Map;
4+
5+
public interface SubCategoryTaskRequestUsecase {
6+
Map<String, Long> subCategoryTaskRequestAggregate(String period, String mainCategory);
7+
}

0 commit comments

Comments
 (0)