diff --git a/layer-admin/src/main/java/org/layer/admin/retrospect/controller/AdminRetrospectController.java b/layer-admin/src/main/java/org/layer/admin/retrospect/controller/AdminRetrospectController.java index 6b0a8882..0629a596 100644 --- a/layer-admin/src/main/java/org/layer/admin/retrospect/controller/AdminRetrospectController.java +++ b/layer-admin/src/main/java/org/layer/admin/retrospect/controller/AdminRetrospectController.java @@ -6,6 +6,7 @@ import org.layer.admin.retrospect.controller.dto.CumulativeRetrospectCountResponse; import org.layer.admin.retrospect.controller.dto.MeaningfulRetrospectMemberResponse; import org.layer.admin.retrospect.controller.dto.RetrospectCompletionRateResponse; +import org.layer.admin.retrospect.controller.dto.RetrospectOverviewResponse; import org.layer.admin.retrospect.controller.dto.RetrospectRetentionResponse; import org.layer.admin.retrospect.controller.dto.RetrospectStayTimeResponse; import org.layer.admin.retrospect.service.AdminRetrospectService; @@ -23,6 +24,15 @@ public class AdminRetrospectController { private final AdminRetrospectService adminRetrospectService; + @GetMapping("/admin/retrospect/overview") + public ResponseEntity getRetrospectOverview( + @RequestParam(name = "startDate") LocalDateTime startDate, + @RequestParam(name = "endDate") LocalDateTime endDate) { + + RetrospectOverviewResponse response = adminRetrospectService.getRetrospectOverview(startDate, endDate); + return ResponseEntity.ok().body(response); + } + @GetMapping("/admin/retrospect/stay-time") public ResponseEntity> getAllRetrospectStayTime( @RequestParam(name = "startDate") LocalDateTime startDate, diff --git a/layer-admin/src/main/java/org/layer/admin/retrospect/controller/dto/RetrospectOverviewResponse.java b/layer-admin/src/main/java/org/layer/admin/retrospect/controller/dto/RetrospectOverviewResponse.java new file mode 100644 index 00000000..4a78020b --- /dev/null +++ b/layer-admin/src/main/java/org/layer/admin/retrospect/controller/dto/RetrospectOverviewResponse.java @@ -0,0 +1,9 @@ +package org.layer.admin.retrospect.controller.dto; + +public record RetrospectOverviewResponse( + long createdRetrospectCount, + long completedRetrospectCount, + double averageCompletionRate, + double averageRetrospectLength +) { +} diff --git a/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectAnswerRepository.java b/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectAnswerRepository.java index 88e72a51..35b65d41 100644 --- a/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectAnswerRepository.java +++ b/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectAnswerRepository.java @@ -44,6 +44,17 @@ List findRetrospectAnswerCompletionStatsBetween( @Param("start") LocalDateTime startTime, @Param("end") LocalDateTime endTime); + @Query(""" + SELECT COALESCE(AVG(LENGTH(a.answerContent)), 0) + FROM AdminRetrospectAnswerHistory a + WHERE a.answerEndTime IS NOT NULL + AND a.answerEndTime BETWEEN :startTime AND :endTime + """) + double findAverageRetrospectLengthBetween( + @Param("startTime") LocalDateTime startTime, + @Param("endTime") LocalDateTime endTime + ); + // 엣지 케이스로 답변 종료시간이 없는 경우도 있을 수 있기에 필터링한다. List findAllByEventTimeBetweenAndAnswerEndTimeIsNotNull( LocalDateTime startTime, LocalDateTime endTime); diff --git a/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectRepository.java b/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectRepository.java index d287bf6d..a082315e 100644 --- a/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectRepository.java +++ b/layer-admin/src/main/java/org/layer/admin/retrospect/repository/AdminRetrospectRepository.java @@ -20,4 +20,17 @@ List findProceedingSpacesByMember( @Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate ); + + Long countAllByCreatedAtBetween(LocalDateTime startDate, LocalDateTime endDate); + + @Query(""" + SELECT COUNT(r) + FROM AdminRetrospect r + WHERE r.retrospectStatus = 'DONE' + AND r.updatedAt BETWEEN :startDate AND :endDate + """) + Long countCompletedRetrospectBetween( + @Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate + ); } diff --git a/layer-admin/src/main/java/org/layer/admin/retrospect/service/AdminRetrospectService.java b/layer-admin/src/main/java/org/layer/admin/retrospect/service/AdminRetrospectService.java index 3c71dbac..a4d8871d 100644 --- a/layer-admin/src/main/java/org/layer/admin/retrospect/service/AdminRetrospectService.java +++ b/layer-admin/src/main/java/org/layer/admin/retrospect/service/AdminRetrospectService.java @@ -20,6 +20,7 @@ import org.layer.admin.retrospect.controller.dto.MeaningfulRetrospectMemberResponse; import org.layer.admin.retrospect.controller.dto.ProceedingRetrospectCTRAverageResponse; import org.layer.admin.retrospect.controller.dto.RetrospectCompletionRateResponse; +import org.layer.admin.retrospect.controller.dto.RetrospectOverviewResponse; import org.layer.admin.retrospect.controller.dto.RetrospectRetentionResponse; import org.layer.admin.retrospect.controller.dto.RetrospectStayTimeResponse; import org.layer.admin.retrospect.entity.AdminRetrospect; @@ -65,6 +66,25 @@ public class AdminRetrospectService { private final AdminRetrospectRepository retrospectRepository; private final AdminMemberSpaceRelationRepository memberSpaceRelationRepository; + public RetrospectOverviewResponse getRetrospectOverview(LocalDateTime startDate, LocalDateTime endDate) { + long createdRetrospectCount = retrospectRepository.countAllByCreatedAtBetween(startDate, endDate); + long completedRetrospectCount = retrospectRepository.countCompletedRetrospectBetween(startDate, endDate); + + double averageCompletionRate = createdRetrospectCount == 0 + ? 0.0 + : (completedRetrospectCount / (double)createdRetrospectCount) * 100.0; + + double averageRetrospectLength = adminRetrospectAnswerRepository.findAverageRetrospectLengthBetween( + startDate, endDate); + + return new RetrospectOverviewResponse( + createdRetrospectCount, + completedRetrospectCount, + averageCompletionRate, + averageRetrospectLength + ); + } + public MeaningfulRetrospectMemberResponse getAllMeaningfulRetrospect( LocalDateTime startTime, LocalDateTime endTime, int retrospectLength, int retrospectCount) { List meaningfulMemberIds = adminRetrospectAnswerRepository.findMeaningfulMemberIds(