From a92a76e25bcdafcec39fd9f99a9975bfe4dcd67f Mon Sep 17 00:00:00 2001 From: Sejeong Kim <64718002+clean2001@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:31:33 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B0=B1=EC=98=A4=ED=94=BC=EC=8A=A4?= =?UTF-8?q?=EC=9A=A9=20API=20(#211)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 스페이스 개수 조회 API 작성 * feat: 회고 개수 조회 API 작성 * feat: 특정 스페이스 내 회고 개수 API 작성 * feat: 특정 기간 내에 진행된 회고 개수 스페이스 별로 보는 API * fix: 파일 삭제 --- gradle/wrapper/gradle-wrapper.properties | 7 --- .../domain/admin/controller/AdminApi.java | 55 ++++++++++++++++--- .../admin/controller/AdminController.java | 51 ++++++++++++++--- .../dto/AdminRetrospectCountGetResponse.java | 9 +++ .../dto/AdminSpaceCountGetResponse.java | 9 +++ .../domain/admin/service/AdminService.java | 47 ++++++++++++++-- .../src/main/resources/application-local.yml | 1 + ...etrospectCountGroupBySpaceGetResponse.java | 42 ++++++++++++++ .../repository/RetrospectAdminRepository.java | 45 +++++++++++++-- .../repository/SpaceAdminRepository.java | 20 ++++++- 10 files changed, 249 insertions(+), 37 deletions(-) delete mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminRetrospectCountGetResponse.java create mode 100644 layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminSpaceCountGetResponse.java create mode 100644 layer-domain/src/main/java/org/layer/domain/retrospect/dto/AdminRetrospectCountGroupBySpaceGetResponse.java diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a4413138..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/layer-api/src/main/java/org/layer/domain/admin/controller/AdminApi.java b/layer-api/src/main/java/org/layer/domain/admin/controller/AdminApi.java index 2e55654c..213e8949 100644 --- a/layer-api/src/main/java/org/layer/domain/admin/controller/AdminApi.java +++ b/layer-api/src/main/java/org/layer/domain/admin/controller/AdminApi.java @@ -1,18 +1,20 @@ package org.layer.domain.admin.controller; -import java.time.LocalDateTime; - -import org.layer.domain.admin.controller.dto.AdminRetrospectsGetResponse; -import org.layer.domain.admin.controller.dto.AdminSpacesGetResponse; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; +import org.layer.domain.admin.controller.dto.AdminRetrospectCountGetResponse; +import org.layer.domain.admin.controller.dto.AdminRetrospectsGetResponse; +import org.layer.domain.admin.controller.dto.AdminSpaceCountGetResponse; +import org.layer.domain.admin.controller.dto.AdminSpacesGetResponse; +import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestParam; + +import java.time.LocalDateTime; +import java.util.List; @Tag(name = "어드민", description = "어드민 관련 API") public interface AdminApi { @@ -32,4 +34,41 @@ ResponseEntity getSpaceData(@RequestParam("startDate") L @Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))}) ResponseEntity getRetrospectData(@RequestParam("startDate") LocalDateTime startDate, @RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password); + + @Operation(summary = "스페이스 개수 조회", description = "특정 기간내에 만들어진 스페이스 개수를 조회합니다. (우리 팀원이 만든 스페이스는 제외)") + @Parameters({ + @Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))}) + ResponseEntity getSpaceCount(@RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password); + + @Operation(summary = "회고 개수 조회", description = "특정 기간내에 시작된 회고 개수를 조회합니다. (우리 팀원이 만든 스페이스에서 진행된 회고는 제외)") + @Parameters({ + @Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))}) + ResponseEntity getRetrospectCount(@RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, @RequestParam("password") String password); + + + @Operation(summary = "특정 스페이스 내 회고 개수 조회", description = "특정 기간내에 특정 스페이스 안에서 시작된 회고 개수를 조회합니다.") + @Parameters({ + @Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))}) + ResponseEntity getRetrospectCountInSpace(@RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, + @RequestParam("spaceId") Long spaceId, + @RequestParam("password") String password); + + + @Operation(summary = "특정 기간 내 회고 개수 스페이스 별로 보기", description = "특정 기간내에 시작된 회고 개수를 스페이스 별로 조회합니다. (우리 팀원이 만든 스페이스는 제외)") + @Parameters({ + @Parameter(name = "startDate", description = "검색 시작 시간", example = "2024-09-05T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "endDate", description = "검색 종료 시간", example = "2024-09-13T15:30:45", required = true, schema = @Schema(type = "string")), + @Parameter(name = "password", description = "비밀번호 [카톡방으로 공유]", example = "[카톡방으로 공유]", required = true, schema = @Schema(type = "string", format = "string"))}) + ResponseEntity> getRetrospectCountGroupBySpace (@RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, + @RequestParam("password") String password); } diff --git a/layer-api/src/main/java/org/layer/domain/admin/controller/AdminController.java b/layer-api/src/main/java/org/layer/domain/admin/controller/AdminController.java index 31a04c7c..3a3dd4d8 100644 --- a/layer-api/src/main/java/org/layer/domain/admin/controller/AdminController.java +++ b/layer-api/src/main/java/org/layer/domain/admin/controller/AdminController.java @@ -1,19 +1,17 @@ package org.layer.domain.admin.controller; -import java.time.LocalDateTime; - -import org.layer.common.annotation.MemberId; +import lombok.RequiredArgsConstructor; +import org.layer.domain.admin.controller.dto.AdminRetrospectCountGetResponse; import org.layer.domain.admin.controller.dto.AdminRetrospectsGetResponse; +import org.layer.domain.admin.controller.dto.AdminSpaceCountGetResponse; import org.layer.domain.admin.controller.dto.AdminSpacesGetResponse; import org.layer.domain.admin.service.AdminService; +import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; -import lombok.RequiredArgsConstructor; +import java.time.LocalDateTime; +import java.util.List; @RestController @RequiredArgsConstructor @@ -40,4 +38,39 @@ public ResponseEntity getRetrospectData( return ResponseEntity.ok(adminService.getRetrospectData(startDate, endDate, password)); } + + @Override + @GetMapping("/space/count/user-only") + public ResponseEntity getSpaceCount( + @RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, + @RequestParam("password") String password) { + return ResponseEntity.ok(adminService.getSpaceCount(startDate, endDate, password)); + } + + @Override + @GetMapping("/retrospect/count/user-only") + public ResponseEntity getRetrospectCount( + @RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, + @RequestParam("password") String password) { + + return ResponseEntity.ok(adminService.getRetrospectCount(startDate, endDate, password)); + } + + @Override + @GetMapping("space/{spaceId}/retrospect/count") + public ResponseEntity getRetrospectCountInSpace(@RequestParam("startDate") LocalDateTime startDate, + @RequestParam("endDate") LocalDateTime endDate, + @PathVariable("spaceId") Long spaceId, + @RequestParam("password") String password) { + return ResponseEntity.ok(adminService.getRetrospectCountInSpace(startDate, endDate, spaceId, password)); + } + + @Override + @GetMapping("/retrospect/count/group-by-space") + public ResponseEntity> getRetrospectCountGroupBySpace(LocalDateTime startDate, LocalDateTime endDate, String password) { + return ResponseEntity.ok(adminService.getRetrospectCountGroupSpace(startDate, endDate, password)); + } + } diff --git a/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminRetrospectCountGetResponse.java b/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminRetrospectCountGetResponse.java new file mode 100644 index 00000000..d746e8d1 --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminRetrospectCountGetResponse.java @@ -0,0 +1,9 @@ +package org.layer.domain.admin.controller.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "AdminSpaceCountGetResponse", description = "우리 팀이 만든 스페이스에서 진행된 회고를 제외하고 기간 내에 시작된 회고 수를 리턴합니다.") +public record AdminRetrospectCountGetResponse( + @Schema(description = "기간 내에 만들어진 회고 개수", example = "20") + Long retrospectCount) { +} \ No newline at end of file diff --git a/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminSpaceCountGetResponse.java b/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminSpaceCountGetResponse.java new file mode 100644 index 00000000..3f25b895 --- /dev/null +++ b/layer-api/src/main/java/org/layer/domain/admin/controller/dto/AdminSpaceCountGetResponse.java @@ -0,0 +1,9 @@ +package org.layer.domain.admin.controller.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "AdminSpaceCountGetResponse", description = "우리 팀이 만든 스페이스를 제외하고 기간 내에 만들어진 스페이스 개수를 리턴합니다.") +public record AdminSpaceCountGetResponse( + @Schema(description = "기간 내에 만들어진 스페이스 개수", example = "11") + Long spaceCount) { +} diff --git a/layer-api/src/main/java/org/layer/domain/admin/service/AdminService.java b/layer-api/src/main/java/org/layer/domain/admin/service/AdminService.java index 38321163..d2e563bd 100644 --- a/layer-api/src/main/java/org/layer/domain/admin/service/AdminService.java +++ b/layer-api/src/main/java/org/layer/domain/admin/service/AdminService.java @@ -1,21 +1,21 @@ package org.layer.domain.admin.service; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - +import lombok.RequiredArgsConstructor; +import org.layer.domain.admin.controller.dto.AdminRetrospectCountGetResponse; import org.layer.domain.admin.controller.dto.AdminRetrospectsGetResponse; +import org.layer.domain.admin.controller.dto.AdminSpaceCountGetResponse; import org.layer.domain.admin.controller.dto.AdminSpacesGetResponse; +import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse; import org.layer.domain.retrospect.dto.AdminRetrospectGetResponse; import org.layer.domain.retrospect.repository.RetrospectAdminRepository; import org.layer.domain.space.dto.AdminSpaceGetResponse; -import org.layer.domain.space.entity.Space; import org.layer.domain.space.repository.SpaceAdminRepository; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import lombok.RequiredArgsConstructor; +import java.time.LocalDateTime; +import java.util.List; @Service @RequiredArgsConstructor @@ -49,4 +49,39 @@ public AdminRetrospectsGetResponse getRetrospectData(LocalDateTime startDate, Lo return new AdminRetrospectsGetResponse(retrospects, retrospects.size()); } + + public AdminSpaceCountGetResponse getSpaceCount(LocalDateTime startDate, LocalDateTime endDate, String requestPassword) { + if(!requestPassword.equals(password)) { + throw new IllegalArgumentException("비밀번호가 틀렸습니다."); + } + + Long count = spaceAdminRepository.countSpacesExceptForAdminSpace(startDate, endDate); + return new AdminSpaceCountGetResponse(count); + } + + public AdminRetrospectCountGetResponse getRetrospectCount(LocalDateTime startDate, LocalDateTime endDate, String requestPassword) { + if(!requestPassword.equals(password)) { + throw new IllegalArgumentException("비밀번호가 틀렸습니다."); + } + + Long count = retrospectAdminRepository.countRetrospectsExceptForAdminSpace(startDate, endDate); + return new AdminRetrospectCountGetResponse(count); + } + + public AdminRetrospectCountGetResponse getRetrospectCountInSpace(LocalDateTime startDate, LocalDateTime endDate, Long spaceId, String requestPassword) { + if(!requestPassword.equals(password)) { + throw new IllegalArgumentException("비밀번호가 틀렸습니다."); + } + + Long count = retrospectAdminRepository.countRetrospectsBySpaceId(spaceId, startDate, endDate); + return new AdminRetrospectCountGetResponse(count); + } + + public List getRetrospectCountGroupSpace(LocalDateTime startDate, LocalDateTime endDate, String requestPassword) { + if(!requestPassword.equals(password)) { + throw new IllegalArgumentException("비밀번호가 틀렸습니다."); + } + + return retrospectAdminRepository.countRetrospectsGroupBySpace(startDate, endDate); + } } diff --git a/layer-api/src/main/resources/application-local.yml b/layer-api/src/main/resources/application-local.yml index 3f3257a0..c8fe1029 100644 --- a/layer-api/src/main/resources/application-local.yml +++ b/layer-api/src/main/resources/application-local.yml @@ -54,6 +54,7 @@ google: sheet: id: ${GOOGLE_SHEET_ID} token_path: ${LOCAL_GOOGLE_TOKEN_PATH} + credential_path: ${PROD_GOOGLE_CREDENTIAL_PATH} apple: login: diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/dto/AdminRetrospectCountGroupBySpaceGetResponse.java b/layer-domain/src/main/java/org/layer/domain/retrospect/dto/AdminRetrospectCountGroupBySpaceGetResponse.java new file mode 100644 index 00000000..fed539e3 --- /dev/null +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/dto/AdminRetrospectCountGroupBySpaceGetResponse.java @@ -0,0 +1,42 @@ +package org.layer.domain.retrospect.dto; + +import lombok.*; +import org.layer.domain.member.entity.Member; +import org.layer.domain.space.entity.Space; + +import java.time.LocalDateTime; + +@Builder +@Getter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AdminRetrospectCountGroupBySpaceGetResponse { + private Long spaceId; + private String spaceName; + private LocalDateTime spaceCreatedAt; + private Long leaderId; + private String leaderEmail; + private String leaderName; + private Long retrospectCount; + public AdminRetrospectCountGroupBySpaceGetResponse of(Space space, Member leader, Long retrospectCount) { + return AdminRetrospectCountGroupBySpaceGetResponse.builder() + .spaceId(space.getId()) + .spaceName(space.getName()) + .leaderId(leader.getId()) + .leaderEmail(leader.getEmail()) + .spaceCreatedAt(space.getCreatedAt()) + .leaderName(leader.getName()) + .retrospectCount(retrospectCount) + .build(); + } + + public AdminRetrospectCountGroupBySpaceGetResponse(Space space, Member member, Long retrospectCount) { + this.spaceId = space.getId(); + this.spaceName = space.getName(); + this.spaceCreatedAt = space.getCreatedAt(); + this.leaderId = member.getId(); + this.leaderName = member.getName(); + this.leaderEmail = member.getEmail(); + this.retrospectCount = retrospectCount; + } +} diff --git a/layer-domain/src/main/java/org/layer/domain/retrospect/repository/RetrospectAdminRepository.java b/layer-domain/src/main/java/org/layer/domain/retrospect/repository/RetrospectAdminRepository.java index 3f7c97f6..bd692e5d 100644 --- a/layer-domain/src/main/java/org/layer/domain/retrospect/repository/RetrospectAdminRepository.java +++ b/layer-domain/src/main/java/org/layer/domain/retrospect/repository/RetrospectAdminRepository.java @@ -1,15 +1,15 @@ package org.layer.domain.retrospect.repository; -import java.time.LocalDateTime; -import java.util.List; - +import org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse; import org.layer.domain.retrospect.dto.AdminRetrospectGetResponse; import org.layer.domain.retrospect.entity.Retrospect; -import org.layer.domain.space.dto.AdminSpaceGetResponse; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; +import java.util.List; + public interface RetrospectAdminRepository extends JpaRepository { @Query @@ -23,4 +23,41 @@ public interface RetrospectAdminRepository extends JpaRepository findAllByCreatedAtAfterAndCreatedAtBefore( @Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate); + + // ADMIN 유저가 만든 스페이스에서 진행된 회고 제외 + @Query("SELECT count(*)" + + "FROM Retrospect r " + + "JOIN Space s ON r.spaceId = s.id " + + "JOIN Member m ON s.leaderId = m.id " + + "WHERE r.createdAt >= :startDate " + + "AND r.createdAt <= :endDate " + + "AND m.memberRole = 'USER'" + ) + Long countRetrospectsExceptForAdminSpace(@Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate); + + + @Query("SELECT count(*)" + + "FROM Retrospect r " + + "JOIN Space s ON r.spaceId = s.id " + + "JOIN Member m ON s.leaderId = m.id " + + "WHERE r.spaceId = :spaceId " + + "AND r.createdAt >= :startDate " + + "AND r.createdAt <= :endDate" + ) + Long countRetrospectsBySpaceId(@Param("spaceId") Long spaceId, + @Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate); + + @Query("SELECT new org.layer.domain.retrospect.dto.AdminRetrospectCountGroupBySpaceGetResponse(s, m, COUNT(r)) " + + "FROM Retrospect r " + + "JOIN Space s ON r.spaceId = s.id " + + "JOIN Member m ON s.leaderId = m.id " + + "WHERE r.createdAt >= :startDate " + + "AND r.createdAt <= :endDate " + + "AND m.memberRole = 'USER' " + + "GROUP BY s" + ) + List countRetrospectsGroupBySpace(@Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate); } diff --git a/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceAdminRepository.java b/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceAdminRepository.java index 2b91c1a8..9ae2f302 100644 --- a/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceAdminRepository.java +++ b/layer-domain/src/main/java/org/layer/domain/space/repository/SpaceAdminRepository.java @@ -1,14 +1,14 @@ package org.layer.domain.space.repository; -import java.time.LocalDateTime; -import java.util.List; - import org.layer.domain.space.dto.AdminSpaceGetResponse; import org.layer.domain.space.entity.Space; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; +import java.util.List; + public interface SpaceAdminRepository extends JpaRepository { @Query @@ -22,4 +22,18 @@ List findAllByCreatedAtAfterAndCreatedAtBefore( @Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate ); + + + // ADMIN 유저가 만든 스페이스 제외 + @Query("SELECT count(*)" + + "FROM Space s " + + "JOIN Member m ON s.leaderId = m.id " + + "WHERE s.createdAt >= :startDate " + + "AND s.createdAt <= :endDate " + + "AND m.memberRole = 'USER'" + ) + Long countSpacesExceptForAdminSpace( + @Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate + ); }