From 6126e2e39020d4840fa8e643c81e0055c68d1a63 Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Tue, 26 Aug 2025 17:00:00 -0300 Subject: [PATCH 1/3] fix: correct quota amount variable names and add quotaInBytes and quotaRequestInBytes --- .../member/DefaultMemberGateway.java | 14 ++++- .../member/persistence/MemberJpaEntity.java | 57 ++++++++++++++----- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/DefaultMemberGateway.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/DefaultMemberGateway.java index b38105c2..75ae3f86 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/DefaultMemberGateway.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/DefaultMemberGateway.java @@ -42,6 +42,11 @@ public Member create(final Member member) { return this.memberJpaRepository.save(MemberJpaEntity.fromDomain(member)).toDomain(); } + @Override + public Long count() { + return memberJpaRepository.count(); + } + @Override public Page findAll(SearchQuery searchQuery) { @@ -83,9 +88,9 @@ public Member update(final Member member) { memberJpa.getId(), memberJpa.getUsername(), memberJpa.getNickname(), - memberJpa.getQuotaAmmount(), + memberJpa.getQuotaAmount(), memberJpa.getQuotaUnit(), - memberJpa.getQuotaRequestAmmount(), + memberJpa.getQuotaRequestAmount(), memberJpa.getQuotaRequestUnit(), memberJpa.getQuotaRequestedAt(), memberJpa.getCreatedAt(), @@ -118,4 +123,9 @@ public Boolean existsById(MemberID id) { return this.memberJpaRepository.existsById(id.getValue()); } + @Override + public Long sumAllQuota() { + return this.memberJpaRepository.sumAllQuota(); + } + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java index ddb197c9..0536c298 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java @@ -29,13 +29,18 @@ public class MemberJpaEntity { private String nickname; @Column(nullable = false) - private Long quotaAmmount; + private Long quotaInBytes; + + @Column(nullable = false) + private Long quotaAmount; @Enumerated(EnumType.STRING) @Column(nullable = false) private QuotaUnit quotaUnit; - private Long quotaRequestAmmount; + private Long quotaRequestInBytes; + + private Long quotaRequestAmount; @Enumerated(EnumType.STRING) private QuotaUnit quotaRequestUnit; @@ -55,8 +60,10 @@ public MemberJpaEntity( final String id, final String username, final String nickname, + final Long quotaInBytes, final Long quotaAmmount, final QuotaUnit quotaUnit, + final Long quotaRequestInBytes, final Long quotaRequestAmmount, final QuotaUnit quotaRequestUnit, final Instant quotaRequestedAt, @@ -67,9 +74,11 @@ public MemberJpaEntity( this.id = id; this.username = username; this.nickname = nickname; - this.quotaAmmount = quotaAmmount; + this.quotaInBytes = quotaInBytes; + this.quotaAmount = quotaAmmount; this.quotaUnit = quotaUnit; - this.quotaRequestAmmount = quotaRequestAmmount; + this.quotaRequestInBytes = quotaRequestInBytes; + this.quotaRequestAmount = quotaRequestAmmount; this.quotaRequestUnit = quotaRequestUnit; this.quotaRequestedAt = quotaRequestedAt; this.hasSystemAccess = hasSystemAccess == null ? false : hasSystemAccess; @@ -84,16 +93,16 @@ public MemberJpaEntity() { public Member toDomain() { QuotaRequest quotaRequest = null; - if (getQuotaRequestAmmount() != null && getQuotaRequestUnit() != null && getQuotaRequestedAt() != null) + if (getQuotaRequestAmount() != null && getQuotaRequestUnit() != null && getQuotaRequestedAt() != null) quotaRequest = QuotaRequest.of( - Quota.of(getQuotaRequestAmmount(), getQuotaRequestUnit()), + Quota.of(getQuotaRequestAmount(), getQuotaRequestUnit()), getQuotaRequestedAt()); return Member.with( MemberID.of(getId()), Username.of(getUsername()), Nickname.of(getNickname()), - Quota.of(getQuotaAmmount(), getQuotaUnit()), + Quota.of(getQuotaAmount(), getQuotaUnit()), quotaRequest, getHasSystemAccess(), getCreatedAt(), @@ -106,8 +115,10 @@ public static MemberJpaEntity fromDomain(final Member member) { member.getId().getValue(), member.getUsername().value(), member.getNickname().value(), + member.getQuota().sizeInBytes(), member.getQuota().amount(), member.getQuota().unit(), + member.getQuotaRequest().map(QuotaRequest::quota).map(Quota::sizeInBytes).orElse(null), member.getQuotaRequest().map(QuotaRequest::quota).map(Quota::amount).orElse(null), member.getQuotaRequest().map(QuotaRequest::quota).map(Quota::unit).orElse(null), member.getQuotaRequest().map(QuotaRequest::requesteddAt).orElse(null), @@ -141,12 +152,20 @@ public void setNickname(String nickname) { this.nickname = nickname; } - public Long getQuotaAmmount() { - return quotaAmmount; + public Long getQuotaInBytes() { + return quotaInBytes; } - public void setQuotaAmmount(Long quotaAmmount) { - this.quotaAmmount = quotaAmmount; + public void setQuotaInBytes(Long quotaInBytes) { + this.quotaInBytes = quotaInBytes; + } + + public Long getQuotaAmount() { + return quotaAmount; + } + + public void setQuotaAmount(Long quotaAmmount) { + this.quotaAmount = quotaAmmount; } public QuotaUnit getQuotaUnit() { @@ -157,12 +176,20 @@ public void setQuotaUnit(QuotaUnit quotaUnit) { this.quotaUnit = quotaUnit; } - public Long getQuotaRequestAmmount() { - return quotaRequestAmmount; + public Long getQuotaRequestInBytes() { + return quotaRequestInBytes; + } + + public void setQuotaRequestInBytes(Long quotaRequestInBytes) { + this.quotaRequestInBytes = quotaRequestInBytes; + } + + public Long getQuotaRequestAmount() { + return quotaRequestAmount; } - public void setQuotaRequestAmmount(Long quotaRequestAmmount) { - this.quotaRequestAmmount = quotaRequestAmmount; + public void setQuotaRequestAmount(Long quotaRequestAmmount) { + this.quotaRequestAmount = quotaRequestAmmount; } public QuotaUnit getQuotaRequestUnit() { From b02a8fe95159d7b2aea5cd0b171a3a421916d5af Mon Sep 17 00:00:00 2001 From: jhonatapers Date: Tue, 26 Aug 2025 17:06:02 -0300 Subject: [PATCH 2/3] fix: correct spelling of 'amount' in quota-related classes and API descriptions --- .../request/create/CreateRequestQuotaInput.java | 2 +- .../create/DefaultCreateRequestQuotaUseCase.java | 2 +- .../drive/infrastructure/api/MemberAPI.java | 4 ++-- .../drive/infrastructure/api/MemberAdminAPI.java | 4 ++-- .../member/persistence/MemberJpaEntity.java | 16 ++++++++-------- .../member/persistence/MemberJpaRepository.java | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/application/src/main/java/com/callv2/drive/application/member/quota/request/create/CreateRequestQuotaInput.java b/application/src/main/java/com/callv2/drive/application/member/quota/request/create/CreateRequestQuotaInput.java index 6665b923..4b5131b6 100644 --- a/application/src/main/java/com/callv2/drive/application/member/quota/request/create/CreateRequestQuotaInput.java +++ b/application/src/main/java/com/callv2/drive/application/member/quota/request/create/CreateRequestQuotaInput.java @@ -2,7 +2,7 @@ import com.callv2.drive.domain.member.QuotaUnit; -public record CreateRequestQuotaInput(String memberId, Long ammount, QuotaUnit unit) { +public record CreateRequestQuotaInput(String memberId, Long amount, QuotaUnit unit) { public static CreateRequestQuotaInput of(String memberId, Long amount, QuotaUnit unit) { return new CreateRequestQuotaInput(memberId, amount, unit); diff --git a/application/src/main/java/com/callv2/drive/application/member/quota/request/create/DefaultCreateRequestQuotaUseCase.java b/application/src/main/java/com/callv2/drive/application/member/quota/request/create/DefaultCreateRequestQuotaUseCase.java index 53f56acb..f5976d6e 100644 --- a/application/src/main/java/com/callv2/drive/application/member/quota/request/create/DefaultCreateRequestQuotaUseCase.java +++ b/application/src/main/java/com/callv2/drive/application/member/quota/request/create/DefaultCreateRequestQuotaUseCase.java @@ -28,7 +28,7 @@ public void execute(final CreateRequestQuotaInput input) { .orElseThrow(() -> NotFoundException.with(Member.class, input.memberId())); final Notification notification = Notification.create(); - notification.validate(() -> member.requestQuota(Quota.of(input.ammount(), input.unit()))); + notification.validate(() -> member.requestQuota(Quota.of(input.amount(), input.unit()))); if (notification.hasError()) throw ValidationException.with("Request Quota Error", notification); diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAPI.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAPI.java index da733ae1..9af64fda 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAPI.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAPI.java @@ -21,7 +21,7 @@ @RequestMapping("members") public interface MemberAPI { - @Operation(summary = "Request drive quota", description = "This method request a drive ammount quota", security = @SecurityRequirement(name = "bearerAuth")) + @Operation(summary = "Request drive quota", description = "This method request a drive amount quota", security = @SecurityRequirement(name = "bearerAuth")) @ApiResponse(responseCode = "204", description = "Requested successfuly") @ApiResponse(responseCode = "404", description = "Member not found", content = @Content(schema = @Schema(implementation = Void.class))) @PostMapping("quotas/requests/{amount}") @@ -29,7 +29,7 @@ ResponseEntity requestQuota( @PathVariable(value = "amount", required = true) long amount, @RequestParam(value = "unit", defaultValue = "GIGABYTE") QuotaUnit unit); - @Operation(summary = "Retrieve actual drive quota", description = "This method retrieve a drive ammount quota", security = @SecurityRequirement(name = "bearerAuth")) + @Operation(summary = "Retrieve actual drive quota", description = "This method retrieve a drive amount quota", security = @SecurityRequirement(name = "bearerAuth")) @ApiResponse(responseCode = "200", description = "Retrieve successfuly") @ApiResponse(responseCode = "404", description = "Member not found", content = @Content(schema = @Schema(implementation = Void.class))) @GetMapping("quotas") diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java index d11ae5d1..a875df92 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java @@ -28,13 +28,13 @@ @RequestMapping("admin/members") public interface MemberAdminAPI { - @Operation(summary = "Request drive quota", description = "This method request a drive ammount quota", security = @SecurityRequirement(name = "bearerAuth")) + @Operation(summary = "Request drive quota", description = "This method request a drive amount quota", security = @SecurityRequirement(name = "bearerAuth")) @ApiResponse(responseCode = "200", description = "Retrieve successfuly") @ApiResponse(responseCode = "404", description = "Member not found", content = @Content(schema = @Schema(implementation = Void.class))) @GetMapping("{id}/quotas") ResponseEntity getQuota(@PathVariable(value = "id", required = true) String id); - @Operation(summary = "Approve drive quota request", description = "This method approve a drive ammount quota request", security = @SecurityRequirement(name = "bearerAuth")) + @Operation(summary = "Approve drive quota request", description = "This method approve a drive amount quota request", security = @SecurityRequirement(name = "bearerAuth")) @ApiResponse(responseCode = "204", description = "Approved successfuly") @ApiResponse(responseCode = "404", description = "Member not found", content = @Content(schema = @Schema(implementation = Void.class))) @PatchMapping("{id}/quotas/requests") diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java index 0536c298..f255a9c2 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaEntity.java @@ -61,10 +61,10 @@ public MemberJpaEntity( final String username, final String nickname, final Long quotaInBytes, - final Long quotaAmmount, + final Long quotaAmount, final QuotaUnit quotaUnit, final Long quotaRequestInBytes, - final Long quotaRequestAmmount, + final Long quotaRequestAmount, final QuotaUnit quotaRequestUnit, final Instant quotaRequestedAt, final Boolean hasSystemAccess, @@ -75,10 +75,10 @@ public MemberJpaEntity( this.username = username; this.nickname = nickname; this.quotaInBytes = quotaInBytes; - this.quotaAmount = quotaAmmount; + this.quotaAmount = quotaAmount; this.quotaUnit = quotaUnit; this.quotaRequestInBytes = quotaRequestInBytes; - this.quotaRequestAmount = quotaRequestAmmount; + this.quotaRequestAmount = quotaRequestAmount; this.quotaRequestUnit = quotaRequestUnit; this.quotaRequestedAt = quotaRequestedAt; this.hasSystemAccess = hasSystemAccess == null ? false : hasSystemAccess; @@ -164,8 +164,8 @@ public Long getQuotaAmount() { return quotaAmount; } - public void setQuotaAmount(Long quotaAmmount) { - this.quotaAmount = quotaAmmount; + public void setQuotaAmount(Long quotaAmount) { + this.quotaAmount = quotaAmount; } public QuotaUnit getQuotaUnit() { @@ -188,8 +188,8 @@ public Long getQuotaRequestAmount() { return quotaRequestAmount; } - public void setQuotaRequestAmount(Long quotaRequestAmmount) { - this.quotaRequestAmount = quotaRequestAmmount; + public void setQuotaRequestAmount(Long quotaRequestAmount) { + this.quotaRequestAmount = quotaRequestAmount; } public QuotaUnit getQuotaRequestUnit() { diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java index cd9572c7..a64a098e 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java @@ -22,7 +22,7 @@ public interface MemberJpaRepository extends JpaRepository Date: Tue, 26 Aug 2025 17:35:20 -0300 Subject: [PATCH 3/3] feat: implement quota summary feature with new use case and API endpoint --- .../DefaultGetQuotasSummaryUseCase.java | 33 +++++++++++++++++++ .../summary/GetQuotasSummaryOutput.java | 9 +++++ .../summary/GetQuotasSummaryUseCase.java | 7 ++++ .../callv2/drive/domain/file/FileGateway.java | 2 ++ .../drive/domain/member/MemberGateway.java | 4 +++ .../infrastructure/api/MemberAdminAPI.java | 7 ++++ .../api/controller/MemberAdminController.java | 12 ++++++- .../usecase/MemberUseCaseConfig.java | 7 ++++ .../infrastructure/file/FileJPAGateway.java | 5 +++ .../file/persistence/FileJpaRepository.java | 4 +++ .../member/model/QuotaSummaryResponse.java | 9 +++++ .../persistence/MemberJpaRepository.java | 3 ++ .../member/presenter/MemberPresenter.java | 10 ++++++ 13 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/DefaultGetQuotasSummaryUseCase.java create mode 100644 application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryOutput.java create mode 100644 application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryUseCase.java create mode 100644 infrastructure/src/main/java/com/callv2/drive/infrastructure/member/model/QuotaSummaryResponse.java diff --git a/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/DefaultGetQuotasSummaryUseCase.java b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/DefaultGetQuotasSummaryUseCase.java new file mode 100644 index 00000000..82422c10 --- /dev/null +++ b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/DefaultGetQuotasSummaryUseCase.java @@ -0,0 +1,33 @@ +package com.callv2.drive.application.member.quota.retrieve.summary; + +import com.callv2.drive.domain.file.FileGateway; +import com.callv2.drive.domain.member.MemberGateway; + +public class DefaultGetQuotasSummaryUseCase extends GetQuotasSummaryUseCase { + + private final MemberGateway memberGateway; + private final FileGateway fileGateway; + + public DefaultGetQuotasSummaryUseCase( + final MemberGateway memberGateway, + final FileGateway fileGateway) { + this.memberGateway = memberGateway; + this.fileGateway = fileGateway; + } + + @Override + public GetQuotasSummaryOutput execute() { + + final Long totalMembers = this.memberGateway.count(); + final Long totalAllocatedQuota = this.memberGateway.sumAllQuota(); + final Long totalUsedStorage = this.fileGateway.sumAllContentSize(); + + return new GetQuotasSummaryOutput( + totalMembers, + totalAllocatedQuota, + totalUsedStorage, + totalAllocatedQuota - totalUsedStorage); + + } + +} diff --git a/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryOutput.java b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryOutput.java new file mode 100644 index 00000000..9629d624 --- /dev/null +++ b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryOutput.java @@ -0,0 +1,9 @@ +package com.callv2.drive.application.member.quota.retrieve.summary; + +public record GetQuotasSummaryOutput( + Long membersCount, + Long totalAllocatedQuota, + Long totalUsedQuota, + Long totalAvailableQuota) { + +} diff --git a/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryUseCase.java b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryUseCase.java new file mode 100644 index 00000000..843ca1f9 --- /dev/null +++ b/application/src/main/java/com/callv2/drive/application/member/quota/retrieve/summary/GetQuotasSummaryUseCase.java @@ -0,0 +1,7 @@ +package com.callv2.drive.application.member.quota.retrieve.summary; + +import com.callv2.drive.application.NullaryUseCase; + +public abstract class GetQuotasSummaryUseCase extends NullaryUseCase { + +} diff --git a/domain/src/main/java/com/callv2/drive/domain/file/FileGateway.java b/domain/src/main/java/com/callv2/drive/domain/file/FileGateway.java index 46064f11..be1886aa 100644 --- a/domain/src/main/java/com/callv2/drive/domain/file/FileGateway.java +++ b/domain/src/main/java/com/callv2/drive/domain/file/FileGateway.java @@ -22,4 +22,6 @@ public interface FileGateway { void deleteById(FileID id); + Long sumAllContentSize(); + } diff --git a/domain/src/main/java/com/callv2/drive/domain/member/MemberGateway.java b/domain/src/main/java/com/callv2/drive/domain/member/MemberGateway.java index 40630fb7..9e7a0ffc 100644 --- a/domain/src/main/java/com/callv2/drive/domain/member/MemberGateway.java +++ b/domain/src/main/java/com/callv2/drive/domain/member/MemberGateway.java @@ -9,6 +9,8 @@ public interface MemberGateway { Member create(Member member); + Long count(); + Page findAll(SearchQuery searchQuery); Optional findById(MemberID id); @@ -19,4 +21,6 @@ public interface MemberGateway { Boolean existsById(MemberID id); + Long sumAllQuota(); + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java index a875df92..629699a2 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/MemberAdminAPI.java @@ -16,6 +16,7 @@ import com.callv2.drive.infrastructure.member.model.MemberQuotaListResponse; import com.callv2.drive.infrastructure.member.model.MemberQuotaResponse; import com.callv2.drive.infrastructure.member.model.QuotaRequestListResponse; +import com.callv2.drive.infrastructure.member.model.QuotaSummaryResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -66,4 +67,10 @@ ResponseEntity> listQuotas( @RequestParam(name = "filterOperator", required = false, defaultValue = "AND") Filter.Operator filterOperator, @RequestParam(name = "filters", required = false) List filters); + @Operation(summary = "Get quota summary", description = "Returns an aggregated summary of quotas, including total allocated quota, used quota, available quota, and total members.", security = @SecurityRequirement(name = "bearerAuth")) + @ApiResponse(responseCode = "200", description = "Quota summary retrieved successfully", content = @Content(schema = @Schema(implementation = QuotaSummaryResponse.class))) + @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = ApiError.class))) + @GetMapping("quotas/summary") + ResponseEntity quotaSummary(); + } \ No newline at end of file diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/controller/MemberAdminController.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/controller/MemberAdminController.java index db18743f..a9666ec3 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/controller/MemberAdminController.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/api/controller/MemberAdminController.java @@ -11,6 +11,7 @@ import com.callv2.drive.application.member.quota.retrieve.get.GetQuotaInput; import com.callv2.drive.application.member.quota.retrieve.get.GetQuotaUseCase; import com.callv2.drive.application.member.quota.retrieve.list.ListQuotasUseCase; +import com.callv2.drive.application.member.quota.retrieve.summary.GetQuotasSummaryUseCase; import com.callv2.drive.domain.pagination.Filter; import com.callv2.drive.domain.pagination.Filter.Operator; import com.callv2.drive.domain.pagination.Page; @@ -22,6 +23,7 @@ import com.callv2.drive.infrastructure.member.model.MemberQuotaListResponse; import com.callv2.drive.infrastructure.member.model.MemberQuotaResponse; import com.callv2.drive.infrastructure.member.model.QuotaRequestListResponse; +import com.callv2.drive.infrastructure.member.model.QuotaSummaryResponse; import com.callv2.drive.infrastructure.member.presenter.MemberPresenter; @Controller @@ -31,16 +33,19 @@ public class MemberAdminController implements MemberAdminAPI { private final ListRequestQuotaUseCase listRequestQuotaUseCase; private final GetQuotaUseCase getQuotaUseCase; private final ListQuotasUseCase listQuotasUseCase; + private final GetQuotasSummaryUseCase getQuotasSummaryUseCase; public MemberAdminController( final ApproveRequestQuotaUseCase approveRequestQuotaUseCase, final ListRequestQuotaUseCase listRequestQuotaUseCase, final GetQuotaUseCase getQuotaUseCase, - final ListQuotasUseCase listQuotasUseCase) { + final ListQuotasUseCase listQuotasUseCase, + final GetQuotasSummaryUseCase getQuotasSummaryUseCase) { this.approveRequestQuotaUseCase = approveRequestQuotaUseCase; this.listRequestQuotaUseCase = listRequestQuotaUseCase; this.getQuotaUseCase = getQuotaUseCase; this.listQuotasUseCase = listQuotasUseCase; + this.getQuotasSummaryUseCase = getQuotasSummaryUseCase; } @Override @@ -94,4 +99,9 @@ public ResponseEntity> listQuotas( } + @Override + public ResponseEntity quotaSummary() { + return ResponseEntity.ok(MemberPresenter.present(getQuotasSummaryUseCase.execute())); + } + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/usecase/MemberUseCaseConfig.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/usecase/MemberUseCaseConfig.java index 93aba9e6..60c58e9b 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/usecase/MemberUseCaseConfig.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/configuration/usecase/MemberUseCaseConfig.java @@ -13,6 +13,8 @@ import com.callv2.drive.application.member.quota.retrieve.get.GetQuotaUseCase; import com.callv2.drive.application.member.quota.retrieve.list.DefaultListQuotasUseCase; import com.callv2.drive.application.member.quota.retrieve.list.ListQuotasUseCase; +import com.callv2.drive.application.member.quota.retrieve.summary.DefaultGetQuotasSummaryUseCase; +import com.callv2.drive.application.member.quota.retrieve.summary.GetQuotasSummaryUseCase; import com.callv2.drive.application.member.synchronize.DefaultSynchronizeMemberUseCase; import com.callv2.drive.application.member.synchronize.SynchronizeMemberUseCase; import com.callv2.drive.domain.file.FileGateway; @@ -59,4 +61,9 @@ ListQuotasUseCase listQuotasUseCase() { return new DefaultListQuotasUseCase(memberGateway); } + @Bean + GetQuotasSummaryUseCase getQuotasSummaryUseCase() { + return new DefaultGetQuotasSummaryUseCase(memberGateway, fileGateway); + } + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/FileJPAGateway.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/FileJPAGateway.java index 825302a8..befd43f0 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/FileJPAGateway.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/FileJPAGateway.java @@ -86,4 +86,9 @@ public void deleteById(final FileID id) { this.fileRepository.deleteById(id.getValue()); } + @Override + public Long sumAllContentSize() { + return this.fileRepository.sumAllContentSize(); + } + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaRepository.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaRepository.java index b4e94043..4b3e1084 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaRepository.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/file/persistence/FileJpaRepository.java @@ -7,6 +7,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; public interface FileJpaRepository extends JpaRepository { @@ -16,4 +17,7 @@ public interface FileJpaRepository extends JpaRepository { List findByOwnerId(String ownerId); + @Query("select coalesce(sum(f.contentSize), 0) from File f") + Long sumAllContentSize(); + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/model/QuotaSummaryResponse.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/model/QuotaSummaryResponse.java new file mode 100644 index 00000000..14f55b3b --- /dev/null +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/model/QuotaSummaryResponse.java @@ -0,0 +1,9 @@ +package com.callv2.drive.infrastructure.member.model; + +public record QuotaSummaryResponse( + Long membersCount, + Long totalAllocatedQuota, + Long totalUsedQuota, + Long totalAvailableQuota) { + +} diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java index a64a098e..c7496cd0 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/persistence/MemberJpaRepository.java @@ -62,4 +62,7 @@ Integer update( @Param("updatedAt") Instant updatedAt, @Param("synchronizedVersion") Long synchronizedVersion); + @Query("select coalesce(sum(m.quotaInBytes), 0) from Member m") + Long sumAllQuota(); + } diff --git a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/presenter/MemberPresenter.java b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/presenter/MemberPresenter.java index a31038ed..7657f0fd 100644 --- a/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/presenter/MemberPresenter.java +++ b/infrastructure/src/main/java/com/callv2/drive/infrastructure/member/presenter/MemberPresenter.java @@ -3,9 +3,11 @@ import com.callv2.drive.application.member.quota.request.list.ListRequestQuotaOutput; import com.callv2.drive.application.member.quota.retrieve.get.GetQuotaOutput; import com.callv2.drive.application.member.quota.retrieve.list.ListQuotaOutput; +import com.callv2.drive.application.member.quota.retrieve.summary.GetQuotasSummaryOutput; import com.callv2.drive.infrastructure.member.model.MemberQuotaListResponse; import com.callv2.drive.infrastructure.member.model.MemberQuotaResponse; import com.callv2.drive.infrastructure.member.model.QuotaRequestListResponse; +import com.callv2.drive.infrastructure.member.model.QuotaSummaryResponse; public interface MemberPresenter { @@ -35,4 +37,12 @@ static MemberQuotaListResponse present(final ListQuotaOutput output) { output.total()); } + static QuotaSummaryResponse present(final GetQuotasSummaryOutput output) { + return new QuotaSummaryResponse( + output.membersCount(), + output.totalAllocatedQuota(), + output.totalUsedQuota(), + output.totalAvailableQuota()); + } + }