Skip to content

Commit 6219cff

Browse files
authored
Merge pull request #405 from depromeet/develop
v1.3.82
2 parents e90226d + 0c5ba26 commit 6219cff

File tree

6 files changed

+78
-8
lines changed

6 files changed

+78
-8
lines changed

layer-admin/src/main/java/org/layer/admin/retrospect/controller/AdminRetrospectController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import org.layer.admin.retrospect.controller.dto.CumulativeRetrospectCountResponse;
77
import org.layer.admin.retrospect.controller.dto.MeaningfulRetrospectMemberResponse;
8+
import org.layer.admin.retrospect.controller.dto.RetrospectCompletionRateResponse;
89
import org.layer.admin.retrospect.controller.dto.RetrospectRetentionResponse;
910
import org.layer.admin.retrospect.controller.dto.RetrospectStayTimeResponse;
1011
import org.layer.admin.retrospect.service.AdminRetrospectService;
@@ -63,4 +64,14 @@ public ResponseEntity<CumulativeRetrospectCountResponse> getCumulativeRetrospect
6364

6465
return ResponseEntity.ok().body(response);
6566
}
67+
68+
@GetMapping("/admin/retrospect/completion-rate")
69+
public ResponseEntity<RetrospectCompletionRateResponse> getRetrospectCompletionRate(
70+
@RequestParam(name = "startDate") LocalDateTime startDate,
71+
@RequestParam(name = "endDate") LocalDateTime endDate) {
72+
73+
RetrospectCompletionRateResponse response = adminRetrospectService.getRetrospectCompletionRate(startDate,
74+
endDate);
75+
return ResponseEntity.ok().body(response);
76+
}
6677
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.layer.admin.retrospect.controller.dto;
22

33
public record CumulativeRetrospectCountResponse(
4-
long averageCumulativeCount
4+
double averageCumulativeCount
55
) {
66
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.layer.admin.retrospect.controller.dto;
2+
3+
public record RetrospectCompletionRateResponse(
4+
double completionRate
5+
) {
6+
}

layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectAnswerRepository.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Optional;
66

77
import org.layer.admin.retrospect.entity.AdminRetrospectAnswerHistory;
8+
import org.layer.admin.retrospect.repository.dto.RetrospectAnswerCompletionDto;
89
import org.springframework.data.jpa.repository.JpaRepository;
910
import org.springframework.data.jpa.repository.Query;
1011
import org.springframework.data.repository.query.Param;
@@ -15,19 +16,34 @@ Optional<AdminRetrospectAnswerHistory> findTopByMemberIdAndSpaceIdAndRetrospectI
1516
Long memberId, Long spaceId, Long retrospectId);
1617

1718
@Query("""
18-
SELECT a.memberId
19-
FROM AdminRetrospectAnswerHistory a
20-
WHERE LENGTH(a.answerContent) >= :minLength
21-
AND a.eventTime BETWEEN :start AND :end
22-
GROUP BY a.memberId
23-
HAVING COUNT(a) >= :minCount
19+
SELECT a.memberId
20+
FROM AdminRetrospectAnswerHistory a
21+
WHERE LENGTH(a.answerContent) >= :minLength
22+
AND a.eventTime BETWEEN :start AND :end
23+
GROUP BY a.memberId
24+
HAVING COUNT(a) >= :minCount
2425
""")
2526
List<Long> findMeaningfulMemberIds(
2627
@Param("start") LocalDateTime start,
2728
@Param("end") LocalDateTime end,
2829
@Param("minLength") int minLength,
2930
@Param("minCount") int minCount);
3031

32+
@Query("""
33+
SELECT new org.layer.admin.retrospect.repository.dto.RetrospectAnswerCompletionDto(
34+
a.retrospectId,
35+
MIN(r.targetAnswerCount),
36+
COUNT(*)
37+
)
38+
FROM AdminRetrospectAnswerHistory a
39+
JOIN AdminRetrospectHistory r ON a.retrospectId = r.retrospectId
40+
WHERE a.eventTime BETWEEN :start AND :end
41+
GROUP BY a.retrospectId
42+
""")
43+
List<RetrospectAnswerCompletionDto> findRetrospectAnswerCompletionStatsBetween(
44+
@Param("start") LocalDateTime startTime,
45+
@Param("end") LocalDateTime endTime);
46+
3147
// 엣지 케이스로 답변 종료시간이 없는 경우도 있을 수 있기에 필터링한다.
3248
List<AdminRetrospectAnswerHistory> findAllByEventTimeBetweenAndAnswerEndTimeIsNotNull(
3349
LocalDateTime startTime, LocalDateTime endTime);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.layer.admin.retrospect.repository.dto;
2+
3+
public record RetrospectAnswerCompletionDto(
4+
Long retrospectId,
5+
Long targetAnswerCount,
6+
Long actualAnswerCount
7+
) {
8+
public RetrospectAnswerCompletionDto(Long retrospectId, Long targetAnswerCount, Long actualAnswerCount) {
9+
this.retrospectId = retrospectId;
10+
this.targetAnswerCount = targetAnswerCount;
11+
this.actualAnswerCount = actualAnswerCount;
12+
}
13+
}
14+

layer-admin/src/main/java/org/layer/admin/retrospect/service/AdminRetrospectService.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import org.layer.admin.member.repository.AdminMemberRepository;
1919
import org.layer.admin.retrospect.controller.dto.CumulativeRetrospectCountResponse;
2020
import org.layer.admin.retrospect.controller.dto.MeaningfulRetrospectMemberResponse;
21+
import org.layer.admin.retrospect.controller.dto.RetrospectCompletionRateResponse;
2122
import org.layer.admin.retrospect.controller.dto.RetrospectRetentionResponse;
2223
import org.layer.admin.retrospect.controller.dto.RetrospectStayTimeResponse;
2324
import org.layer.admin.retrospect.entity.AdminRetrospectAnswerHistory;
2425
import org.layer.admin.retrospect.entity.AdminRetrospectHistory;
2526
import org.layer.admin.retrospect.enums.AnswerTimeRange;
2627
import org.layer.admin.retrospect.repository.AdminRetrospectAnswerRepository;
2728
import org.layer.admin.retrospect.repository.AdminRetrospectRepository;
29+
import org.layer.admin.retrospect.repository.dto.RetrospectAnswerCompletionDto;
2830
import org.layer.admin.retrospect.repository.dto.SpaceRetrospectCountDto;
2931
import org.layer.admin.space.repository.AdminSpaceRepository;
3032
import org.layer.event.retrospect.CreateRetrospectEvent;
@@ -181,10 +183,31 @@ public CumulativeRetrospectCountResponse getCumulativeRetrospectCount(
181183
.sum();
182184

183185
Long totalSpaceCount = adminSpaceRepository.countAllByEventTimeBetween(startTime, endTime);
184-
long averageCumulativeCount = totalSpaceCount == 0 ? 0 : totalRetrospectCount / totalSpaceCount;
186+
double averageCumulativeCount = totalSpaceCount == 0 ? 0.0 : (double)totalRetrospectCount / totalSpaceCount;
185187
return new CumulativeRetrospectCountResponse(averageCumulativeCount);
186188
}
187189

190+
public RetrospectCompletionRateResponse getRetrospectCompletionRate(LocalDateTime startTime, LocalDateTime endTime) {
191+
List<RetrospectAnswerCompletionDto> answerHistories = adminRetrospectAnswerRepository.findRetrospectAnswerCompletionStatsBetween(
192+
startTime, endTime);
193+
194+
// 회고별 완수율 계산 (단위: %)
195+
List<Double> completionRates = answerHistories.stream()
196+
.filter(dto -> dto.targetAnswerCount() > 0) // division by zero 방지
197+
.map(dto -> (double) dto.actualAnswerCount() / dto.targetAnswerCount() * 100.0)
198+
.toList();
199+
200+
// 평균 완수율 계산
201+
double averageCompletionRate = completionRates.isEmpty()
202+
? 0.0
203+
: completionRates.stream()
204+
.mapToDouble(Double::doubleValue)
205+
.average()
206+
.orElse(0.0);
207+
208+
return new RetrospectCompletionRateResponse(averageCompletionRate);
209+
}
210+
188211
@Transactional(propagation = REQUIRES_NEW)
189212
@Async
190213
public void saveRetrospectAnswerHistory(AnswerRetrospectStartEvent event) {

0 commit comments

Comments
 (0)