From e882ad6ad0007784472614112e54c203ecfb7e25 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 22:49:35 +0900 Subject: [PATCH 01/28] =?UTF-8?q?feat:=20Blacklist=20=EC=84=B1=EA=B3=B5,?= =?UTF-8?q?=20=EC=8B=A4=ED=8C=A8=20Type=20=EA=B5=AC=ED=98=84=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../type/blacklist/BlacklistErrorType.java | 25 +++++++++++++++++++ .../type/blacklist/BlacklistSuccessType.java | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java create mode 100644 module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java new file mode 100644 index 00000000..63ead7eb --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java @@ -0,0 +1,25 @@ +package com.depromeet.type.blacklist; + +import com.depromeet.type.ErrorType; + +public enum BlacklistErrorType implements ErrorType { + ; + + private final String code; + private final String message; + + BlacklistErrorType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java new file mode 100644 index 00000000..9c9c147f --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java @@ -0,0 +1,25 @@ +package com.depromeet.type.blacklist; + +import com.depromeet.type.SuccessType; + +public enum BlacklistSuccessType implements SuccessType { + BLACK_MEMBER_SUCCESS("BLACK_1", "사용자를 성공적으로 차단하였습니다"); + + private final String code; + private final String message; + + BlacklistSuccessType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return null; + } + + @Override + public String getMessage() { + return null; + } +} From 745016dd3124dccc2aee7e56aa1c2c322a5606fb Mon Sep 17 00:00:00 2001 From: penrose15 Date: Fri, 6 Sep 2024 22:54:16 +0900 Subject: [PATCH 02/28] =?UTF-8?q?feat:=20=EB=B8=94=EB=9E=99=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blacklist/port/out/BlacklistPersistencePort.java | 3 +++ .../blacklist/repository/BlacklistJpaRepository.java | 6 ++++++ .../blacklist/repository/BlacklistRepository.java | 11 +++++++++++ 3 files changed, 20 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java create mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java create mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java new file mode 100644 index 00000000..f6d6689a --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java @@ -0,0 +1,3 @@ +package com.depromeet.blacklist.port.out; + +public interface BlacklistPersistencePort {} diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java new file mode 100644 index 00000000..1c1c762d --- /dev/null +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java @@ -0,0 +1,6 @@ +package com.depromeet.blacklist.repository; + +import com.depromeet.blacklist.domain.Blacklist; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BlacklistJpaRepository extends JpaRepository {} diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java new file mode 100644 index 00000000..0040ef68 --- /dev/null +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -0,0 +1,11 @@ +package com.depromeet.blacklist.repository; + +import com.depromeet.blacklist.port.out.BlacklistPersistencePort; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class BlacklistRepository implements BlacklistPersistencePort { + private final BlacklistJpaRepository blacklistJpaRepository; +} From 0386fb78f1feb402d8dcee0019477a6e3876dc37 Mon Sep 17 00:00:00 2001 From: penrose15 Date: Fri, 6 Sep 2024 22:56:38 +0900 Subject: [PATCH 03/28] =?UTF-8?q?feat:=20=EB=B8=94=EB=9E=99=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84=20(#380)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blacklist/port/in/BlacklistGetUseCase.java | 3 +++ .../blacklist/service/BlacklistGetService.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java new file mode 100644 index 00000000..92212cb2 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java @@ -0,0 +1,3 @@ +package com.depromeet.blacklist.port.in; + +public interface BlacklistGetUseCase {} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java new file mode 100644 index 00000000..7d41a277 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java @@ -0,0 +1,14 @@ +package com.depromeet.blacklist.service; + +import com.depromeet.blacklist.port.in.BlacklistGetUseCase; +import com.depromeet.blacklist.port.out.BlacklistPersistencePort; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BlacklistGetService implements BlacklistGetUseCase { + private final BlacklistPersistencePort blacklistPersistencePort; +} From 71aea28a3e78eeb7a80e90cd751999ac84ac3864 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:33:38 +0900 Subject: [PATCH 04/28] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep | 0 .../src/main/java/com/depromeet/blacklist/service/.gitkeep | 0 .../src/main/java/com/depromeet/blacklist/repository/.gitkeep | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep delete mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep b/module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep b/module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 From dc359b81944883216b536d8ef3b2a2c775396d55 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:36:31 +0900 Subject: [PATCH 05/28] =?UTF-8?q?feat:=20Blacklist=20=EC=84=B1=EA=B3=B5,?= =?UTF-8?q?=20=EC=8B=A4=ED=8C=A8=20Type=20=EA=B5=AC=ED=98=84=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/type/blacklist/BlacklistErrorType.java | 2 +- .../com/depromeet/type/blacklist/BlacklistSuccessType.java | 4 ++-- .../main/java/com/depromeet/type/friend/FollowErrorType.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java index 63ead7eb..f659cea8 100644 --- a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java @@ -3,7 +3,7 @@ import com.depromeet.type.ErrorType; public enum BlacklistErrorType implements ErrorType { - ; + ALREADY_BLACKED("BLACK_1", "이미 차단한 사용자입니다"); private final String code; private final String message; diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java index 9c9c147f..a91b047d 100644 --- a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java @@ -15,11 +15,11 @@ public enum BlacklistSuccessType implements SuccessType { @Override public String getCode() { - return null; + return this.code; } @Override public String getMessage() { - return null; + return this.message; } } diff --git a/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java b/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java index caf99679..b21f802d 100644 --- a/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java +++ b/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java @@ -8,7 +8,6 @@ public enum FollowErrorType implements ErrorType { INVALID_FOLLOW_TYPE("FOLLOW_3", "올바르지 않은 팔로우 타입입니다"); private final String code; - private final String message; FollowErrorType(String code, String message) { From 7c93cdf01587437bb55e1c3e5f35318906887b46 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:36:46 +0900 Subject: [PATCH 06/28] =?UTF-8?q?feat:=20Blacklist=20Repository=20?= =?UTF-8?q?=EB=B0=8F=20Port=20=EA=B5=AC=ED=98=84=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/BlacklistPersistencePort.java | 9 ++++++++ .../repository/BlacklistJpaRepository.java | 8 +++++++ .../repository/BlacklistRepository.java | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java create mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java create mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java new file mode 100644 index 00000000..dd3659b8 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java @@ -0,0 +1,9 @@ +package com.depromeet.blacklist.port.out.persistence; + +import com.depromeet.blacklist.domain.Blacklist; + +public interface BlacklistPersistencePort { + Blacklist save(Blacklist blacklist); + + boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); +} diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java new file mode 100644 index 00000000..a449aaa3 --- /dev/null +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java @@ -0,0 +1,8 @@ +package com.depromeet.blacklist.repository; + +import com.depromeet.blacklist.entity.BlacklistEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BlacklistJpaRepository extends JpaRepository { + boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); +} diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java new file mode 100644 index 00000000..ef8ed0e4 --- /dev/null +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -0,0 +1,23 @@ +package com.depromeet.blacklist.repository; + +import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.entity.BlacklistEntity; +import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class BlacklistRepository implements BlacklistPersistencePort { + private final BlacklistJpaRepository blacklistJpaRepository; + + @Override + public Blacklist save(Blacklist blacklist) { + return blacklistJpaRepository.save(BlacklistEntity.from(blacklist)).toModel(); + } + + @Override + public boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId) { + return blacklistJpaRepository.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); + } +} From 8b5bde951dd30e35e52b5f98ee339a2af825bf64 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:37:03 +0900 Subject: [PATCH 07/28] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20API=20=EB=B0=8F=20Service=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/usecase/BlacklistCommandUseCase.java | 7 ++++ .../in/usecase/BlacklistQueryUseCase.java | 5 +++ .../blacklist/service/BlacklistService.java | 32 +++++++++++++++++++ .../blacklist/api/BlacklistController.java | 27 ++++++++++++++++ .../dto/request/BlackMemberRequest.java | 14 ++++++++ .../blacklist/facade/BlacklistFacade.java | 28 ++++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java new file mode 100644 index 00000000..1f96aae9 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java @@ -0,0 +1,7 @@ +package com.depromeet.blacklist.port.in.usecase; + +import com.depromeet.blacklist.domain.Blacklist; + +public interface BlacklistCommandUseCase { + Blacklist blackMember(Long memberId, Long blackMemberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java new file mode 100644 index 00000000..1a2b39b4 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java @@ -0,0 +1,5 @@ +package com.depromeet.blacklist.port.in.usecase; + +public interface BlacklistQueryUseCase { + boolean checkBlackMember(Long memberId, Long blackMemberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java new file mode 100644 index 00000000..7064d492 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -0,0 +1,32 @@ +package com.depromeet.blacklist.service; + +import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; +import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; +import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; +import com.depromeet.member.domain.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BlacklistService implements BlacklistQueryUseCase, BlacklistCommandUseCase { + private final BlacklistPersistencePort blacklistPersistencePort; + + @Override + @Transactional + public Blacklist blackMember(Long memberId, Long blackMemberId) { + return blacklistPersistencePort.save( + Blacklist.builder() + .member(Member.builder().id(memberId).build()) + .blackMember(Member.builder().id(blackMemberId).build()) + .build()); + } + + @Override + public boolean checkBlackMember(Long memberId, Long blackMemberId) { + return blacklistPersistencePort.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java new file mode 100644 index 00000000..cacef814 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java @@ -0,0 +1,27 @@ +package com.depromeet.blacklist.api; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.facade.BlacklistFacade; +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import com.depromeet.type.blacklist.BlacklistSuccessType; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/member/black") +public class BlacklistController implements BlacklistApi { + private final BlacklistFacade blacklistFacade; + + @PostMapping + public ApiResponse blackMember( + @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request) { + blacklistFacade.blackMember(memberId, request); + return ApiResponse.success(BlacklistSuccessType.BLACK_MEMBER_SUCCESS); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java new file mode 100644 index 00000000..36e9bfd9 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java @@ -0,0 +1,14 @@ +package com.depromeet.blacklist.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; + +public record BlackMemberRequest( + @Schema( + description = "차단 대상 사용자 ID", + example = "1", + requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull + @Positive + Long blackMemberId) {} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java new file mode 100644 index 00000000..8096b7b4 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java @@ -0,0 +1,28 @@ +package com.depromeet.blacklist.facade; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; +import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; +import com.depromeet.exception.BadRequestException; +import com.depromeet.type.blacklist.BlacklistErrorType; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class BlacklistFacade { + private final BlacklistQueryUseCase blacklistQueryUseCase; + private final BlacklistCommandUseCase blacklistCommandUseCase; + + public void blackMember(Long memberId, BlackMemberRequest request) { + Long blackMemberId = request.blackMemberId(); + boolean isAlreadyBlacked = blacklistQueryUseCase.checkBlackMember(memberId, blackMemberId); + if (isAlreadyBlacked) { + throw new BadRequestException(BlacklistErrorType.ALREADY_BLACKED); + } + + blacklistCommandUseCase.blackMember(memberId, blackMemberId); + } +} From 7c17b2ce1ca1fc8ec1a55ab9a6eab15a291b9142 Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:37:12 +0900 Subject: [PATCH 08/28] =?UTF-8?q?feat:=20Blacklist=20Swagger=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/blacklist/api/BlacklistApi.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java new file mode 100644 index 00000000..cfc1cf37 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java @@ -0,0 +1,16 @@ +package com.depromeet.blacklist.api; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.RequestBody; + +@Tag(name = "차단(Blacklist)") +public interface BlacklistApi { + @Operation(summary = "사용자 차단") + ApiResponse blackMember( + @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request); +} From f2e1dd3590f7ae947eb35b9bd6b96ecfb0c0832f Mon Sep 17 00:00:00 2001 From: its-sky Date: Fri, 6 Sep 2024 23:47:23 +0900 Subject: [PATCH 09/28] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depromeet/blacklist/dto/request/BlackMemberRequest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java index 36e9bfd9..68e7d9f3 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java @@ -5,10 +5,10 @@ import jakarta.validation.constraints.Positive; public record BlackMemberRequest( - @Schema( + @NotNull + @Positive + @Schema( description = "차단 대상 사용자 ID", example = "1", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull - @Positive Long blackMemberId) {} From bb07c2844e5444a170b59c5fbfc6086127999854 Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 00:12:16 +0900 Subject: [PATCH 10/28] =?UTF-8?q?chore:=20Memory=20Delete=20Logging=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/depromeet/memory/api/MemoryController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java b/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java index 5738698a..51865d5b 100644 --- a/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java +++ b/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java @@ -79,6 +79,7 @@ public ApiResponse getCalendar( } @DeleteMapping("/{memoryId}") + @Logging(item = "Memory", action = "DELETE") public ApiResponse delete( @LoginMember Long memberId, @PathVariable("memoryId") Long memoryId) { memoryFacade.deleteById(memberId, memoryId); From 266222567807a368924f11ef7dcef8777373091f Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 00:12:33 +0900 Subject: [PATCH 11/28] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=ED=95=B4=EC=A0=9C=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../port/in/usecase/BlacklistCommandUseCase.java | 2 ++ .../persistence/BlacklistPersistencePort.java | 2 ++ .../blacklist/service/BlacklistService.java | 6 ++++++ .../type/blacklist/BlacklistSuccessType.java | 3 ++- .../repository/BlacklistJpaRepository.java | 2 ++ .../repository/BlacklistRepository.java | 5 +++++ .../blacklist/api/BlacklistController.java | 16 ++++++++++++++-- .../blacklist/facade/BlacklistFacade.java | 4 ++++ 8 files changed, 37 insertions(+), 3 deletions(-) diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java index 1f96aae9..162a9275 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java @@ -4,4 +4,6 @@ public interface BlacklistCommandUseCase { Blacklist blackMember(Long memberId, Long blackMemberId); + + void unblackMember(Long memberId, Long blackMemberId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java index dd3659b8..25a86d35 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java @@ -6,4 +6,6 @@ public interface BlacklistPersistencePort { Blacklist save(Blacklist blacklist); boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); + + void unblackMember(Long memberId, Long blackMemberId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java index 7064d492..b8c8ef92 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -25,6 +25,12 @@ public Blacklist blackMember(Long memberId, Long blackMemberId) { .build()); } + @Override + @Transactional + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistPersistencePort.unblackMember(memberId, blackMemberId); + } + @Override public boolean checkBlackMember(Long memberId, Long blackMemberId) { return blacklistPersistencePort.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java index a91b047d..deb84c46 100644 --- a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java @@ -3,7 +3,8 @@ import com.depromeet.type.SuccessType; public enum BlacklistSuccessType implements SuccessType { - BLACK_MEMBER_SUCCESS("BLACK_1", "사용자를 성공적으로 차단하였습니다"); + BLACK_MEMBER_SUCCESS("BLACK_1", "사용자를 성공적으로 차단하였습니다"), + UNBLACK_MEMBER_SUCCESS("BLACK_2", "사용자를 차단 해제하였습니다"); private final String code; private final String message; diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java index a449aaa3..c99a7164 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java @@ -5,4 +5,6 @@ public interface BlacklistJpaRepository extends JpaRepository { boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); + + void deleteByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); } diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java index ef8ed0e4..be6c5a99 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -20,4 +20,9 @@ public Blacklist save(Blacklist blacklist) { public boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId) { return blacklistJpaRepository.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); } + + @Override + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistJpaRepository.deleteByMemberIdAndBlackMemberId(memberId, blackMemberId); + } } diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java index cacef814..8e083647 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java @@ -2,11 +2,14 @@ import com.depromeet.blacklist.dto.request.BlackMemberRequest; import com.depromeet.blacklist.facade.BlacklistFacade; +import com.depromeet.config.Logging; import com.depromeet.dto.response.ApiResponse; import com.depromeet.member.annotation.LoginMember; import com.depromeet.type.blacklist.BlacklistSuccessType; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -14,14 +17,23 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/member/black") +@RequestMapping("/member") public class BlacklistController implements BlacklistApi { private final BlacklistFacade blacklistFacade; - @PostMapping + @PostMapping("/black") + @Logging(item = "Blacklist", action = "POST") public ApiResponse blackMember( @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request) { blacklistFacade.blackMember(memberId, request); return ApiResponse.success(BlacklistSuccessType.BLACK_MEMBER_SUCCESS); } + + @DeleteMapping("/{blackMemberId}/black") + @Logging(item = "Blacklist", action = "DELETE") + public ApiResponse unblackMember( + @LoginMember Long memberId, @PathVariable("blackMemberId") Long blackMemberId) { + blacklistFacade.unblackMember(memberId, blackMemberId); + return ApiResponse.success(BlacklistSuccessType.UNBLACK_MEMBER_SUCCESS); + } } diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java index 8096b7b4..711329df 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java @@ -25,4 +25,8 @@ public void blackMember(Long memberId, BlackMemberRequest request) { blacklistCommandUseCase.blackMember(memberId, blackMemberId); } + + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistCommandUseCase.unblackMember(memberId, blackMemberId); + } } From 2685deda8656880801c520ae089509c3f4d67d86 Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 00:12:41 +0900 Subject: [PATCH 12/28] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=ED=95=B4=EC=A0=9C=20API=20Swagger=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/depromeet/blacklist/api/BlacklistApi.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java index cfc1cf37..7c1c99f0 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @Tag(name = "차단(Blacklist)") @@ -13,4 +14,8 @@ public interface BlacklistApi { @Operation(summary = "사용자 차단") ApiResponse blackMember( @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request); + + @Operation(summary = "사용자 차단 해제") + ApiResponse unblackMember( + @LoginMember Long memberId, @PathVariable("blackMemberId") Long blackMemberId); } From b312f513bd6d5e34f5f106b5becb7f5a1703ab4b Mon Sep 17 00:00:00 2001 From: penrose15 Date: Sat, 7 Sep 2024 00:26:44 +0900 Subject: [PATCH 13/28] =?UTF-8?q?feat:=20=ED=8C=94=EB=A1=9C=EC=9A=B0/?= =?UTF-8?q?=ED=8C=94=EB=A1=9C=EC=9E=89=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=ED=95=9C=20=EC=9C=A0=EC=A0=80/=EB=B3=B8?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20=EC=B0=A8=EB=8B=A8=ED=95=9C=20=EC=82=AC?= =?UTF-8?q?=EB=9E=8C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=20(#379)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../port/in/BlacklistGetUseCase.java | 6 +- .../port/out/BlacklistPersistencePort.java | 8 +- .../service/BlacklistGetService.java | 14 --- .../blacklist/service/BlacklistService.java | 34 ++++++ .../friend/domain/vo/FollowSlice.java | 4 +- .../persistence/FriendPersistencePort.java | 4 +- .../friend/service/FollowService.java | 35 +++++- .../mock/friend/FakeFriendRepository.java | 107 +++++------------ .../repository/BlacklistRepository.java | 23 ++++ .../friend/repository/FriendRepository.java | 111 ++++++------------ .../repository/FriendRepositoryTest.java | 21 ++-- .../dto/response/FollowSliceResponse.java | 28 +++-- .../depromeet/friend/facade/FollowFacade.java | 22 +++- 13 files changed, 221 insertions(+), 196 deletions(-) delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java index 92212cb2..20ba2b8d 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/BlacklistGetUseCase.java @@ -1,3 +1,7 @@ package com.depromeet.blacklist.port.in; -public interface BlacklistGetUseCase {} +import java.util.Set; + +public interface BlacklistGetUseCase { + Set getHiddenMemberIds(Long memberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java index f6d6689a..4034b312 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java @@ -1,3 +1,9 @@ package com.depromeet.blacklist.port.out; -public interface BlacklistPersistencePort {} +import java.util.List; + +public interface BlacklistPersistencePort { + List findBlackMemberIdsByMemberId(Long memberId); + + List findMemberIdsByWhoBlockedMe(Long memberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java deleted file mode 100644 index 7d41a277..00000000 --- a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.depromeet.blacklist.service; - -import com.depromeet.blacklist.port.in.BlacklistGetUseCase; -import com.depromeet.blacklist.port.out.BlacklistPersistencePort; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class BlacklistGetService implements BlacklistGetUseCase { - private final BlacklistPersistencePort blacklistPersistencePort; -} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java new file mode 100644 index 00000000..d658fcfd --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -0,0 +1,34 @@ +package com.depromeet.blacklist.service; + +import com.depromeet.blacklist.port.in.BlacklistGetUseCase; +import com.depromeet.blacklist.port.out.BlacklistPersistencePort; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BlacklistService implements BlacklistGetUseCase { + private final BlacklistPersistencePort blacklistPersistencePort; + + public Set getHiddenMemberIds(Long memberId) { + List blackMemberIds = getBlackMemberIdsByMemberId(memberId); + List memberIdsWhoBlockedMe = getMemberIdsWhoBlockedMe(memberId); + + blackMemberIds.addAll(memberIdsWhoBlockedMe); + + return new HashSet<>(blackMemberIds); + } + + private List getBlackMemberIdsByMemberId(Long memberId) { + return blacklistPersistencePort.findBlackMemberIdsByMemberId(memberId); + } + + private List getMemberIdsWhoBlockedMe(Long memberId) { + return blacklistPersistencePort.findMemberIdsByWhoBlockedMe(memberId); + } +} diff --git a/module-domain/src/main/java/com/depromeet/friend/domain/vo/FollowSlice.java b/module-domain/src/main/java/com/depromeet/friend/domain/vo/FollowSlice.java index 21004f14..0ae0ee2c 100644 --- a/module-domain/src/main/java/com/depromeet/friend/domain/vo/FollowSlice.java +++ b/module-domain/src/main/java/com/depromeet/friend/domain/vo/FollowSlice.java @@ -10,14 +10,12 @@ @NoArgsConstructor public class FollowSlice { private List followContents; - private int pageSize; private Long cursorId; private boolean hasNext; @Builder - public FollowSlice(List followContents, int pageSize, Long cursorId, boolean hasNext) { + public FollowSlice(List followContents, Long cursorId, boolean hasNext) { this.followContents = followContents != null ? followContents : new ArrayList<>(); - this.pageSize = pageSize != 0 ? pageSize : 10; this.cursorId = cursorId; this.hasNext = hasNext; } diff --git a/module-domain/src/main/java/com/depromeet/friend/port/out/persistence/FriendPersistencePort.java b/module-domain/src/main/java/com/depromeet/friend/port/out/persistence/FriendPersistencePort.java index 9ce9f36a..f16c76c1 100644 --- a/module-domain/src/main/java/com/depromeet/friend/port/out/persistence/FriendPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/friend/port/out/persistence/FriendPersistencePort.java @@ -14,9 +14,9 @@ public interface FriendPersistencePort { void deleteByMemberIdAndFollowingId(Long memberId, Long followingId); - FollowSlice findFollowingsByMemberIdAndCursorId(Long memberId, Long cursorId); + List findFollowingsByMemberIdAndCursorId(Long memberId, Long cursorId); - FollowSlice findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId); + List findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId); int countFollowingByMemberId(Long memberId); diff --git a/module-domain/src/main/java/com/depromeet/friend/service/FollowService.java b/module-domain/src/main/java/com/depromeet/friend/service/FollowService.java index 5c66aeb4..67e37db5 100644 --- a/module-domain/src/main/java/com/depromeet/friend/service/FollowService.java +++ b/module-domain/src/main/java/com/depromeet/friend/service/FollowService.java @@ -7,6 +7,7 @@ import com.depromeet.friend.port.out.persistence.FriendPersistencePort; import com.depromeet.member.domain.Member; import com.depromeet.type.friend.FollowErrorType; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -39,12 +40,42 @@ public boolean addOrDeleteFollow(Member member, Member following) { @Override public FollowSlice getFollowingByMemberIdAndCursorId(Long memberId, Long cursorId) { - return friendPersistencePort.findFollowingsByMemberIdAndCursorId(memberId, cursorId); + List followings = + friendPersistencePort.findFollowingsByMemberIdAndCursorId(memberId, cursorId); + + boolean hasNext = false; + Long nextCursorId = null; + if (followings.size() > 10) { + followings = new ArrayList<>(followings); + followings.removeLast(); + hasNext = true; + nextCursorId = followings.getLast().getFriendId(); + } + return FollowSlice.builder() + .followContents(followings) + .cursorId(nextCursorId) + .hasNext(hasNext) + .build(); } @Override public FollowSlice getFollowerByMemberIdAndCursorId(Long memberId, Long cursorId) { - return friendPersistencePort.findFollowersByMemberIdAndCursorId(memberId, cursorId); + List followers = + friendPersistencePort.findFollowersByMemberIdAndCursorId(memberId, cursorId); + + boolean hasNext = false; + Long nextCursorId = null; + if (followers.size() > 10) { + followers = new ArrayList<>(followers); + followers.removeLast(); + hasNext = true; + nextCursorId = followers.getLast().getFriendId(); + } + return FollowSlice.builder() + .followContents(followers) + .cursorId(nextCursorId) + .hasNext(hasNext) + .build(); } @Override diff --git a/module-domain/src/test/java/com/depromeet/mock/friend/FakeFriendRepository.java b/module-domain/src/test/java/com/depromeet/mock/friend/FakeFriendRepository.java index 6748a537..dbe16811 100644 --- a/module-domain/src/test/java/com/depromeet/mock/friend/FakeFriendRepository.java +++ b/module-domain/src/test/java/com/depromeet/mock/friend/FakeFriendRepository.java @@ -81,44 +81,22 @@ public void deleteByMemberIdAndFollowingId(Long memberId, Long followingId) { } @Override - public FollowSlice findFollowingsByMemberIdAndCursorId( - Long memberId, Long cursorId) { - List followings = - friends.stream() - .filter( - item -> - item.getMember().getId().equals(memberId) - && ltCursorId(cursorId, item)) - .map( - item -> - Following.builder() - .friendId(item.getId()) - .memberId(item.getFollowing().getId()) - .name(item.getFollowing().getNickname()) - .profileImageUrl( - item.getFollowing().getProfileImageUrl()) - .introduction(item.getFollowing().getIntroduction()) - .build()) - .toList(); - - followings = new ArrayList<>(followings); - - followings.sort( - (follow1, follow2) -> follow2.getFriendId().compareTo(follow1.getFriendId())); - - boolean hasNext = false; - Long nextCursorId = null; - if (followings.size() > 10) { - followings.removeLast(); - hasNext = true; - nextCursorId = followings.getLast().getFriendId(); - } - return FollowSlice.builder() - .followContents(followings) - .pageSize(followings.size()) - .cursorId(nextCursorId) - .hasNext(hasNext) - .build(); + public List findFollowingsByMemberIdAndCursorId(Long memberId, Long cursorId) { + return friends.stream() + .filter( + item -> + item.getMember().getId().equals(memberId) + && ltCursorId(cursorId, item)) + .map( + item -> + Following.builder() + .friendId(item.getId()) + .memberId(item.getFollowing().getId()) + .name(item.getFollowing().getNickname()) + .profileImageUrl(item.getFollowing().getProfileImageUrl()) + .introduction(item.getFollowing().getIntroduction()) + .build()) + .toList(); } public boolean ltCursorId(Long cursorId, Friend friend) { @@ -127,43 +105,22 @@ public boolean ltCursorId(Long cursorId, Friend friend) { } @Override - public FollowSlice findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId) { - List followers = - friends.stream() - .filter( - item -> - item.getFollowing().getId().equals(memberId) - && ltCursorId(cursorId, item)) - .map( - item -> - Follower.builder() - .friendId(item.getId()) - .memberId(item.getMember().getId()) - .name(item.getMember().getNickname()) - .profileImageUrl( - item.getMember().getProfileImageUrl()) - .introduction(item.getMember().getIntroduction()) - .build()) - .toList(); - - followers = new ArrayList<>(followers); - - followers.sort( - (follow1, follow2) -> follow2.getFriendId().compareTo(follow1.getFriendId())); - - boolean hasNext = false; - Long nextCursorId = null; - if (followers.size() > 10) { - followers.removeLast(); - hasNext = true; - nextCursorId = followers.getLast().getFriendId(); - } - return FollowSlice.builder() - .followContents(followers) - .pageSize(followers.size()) - .cursorId(nextCursorId) - .hasNext(hasNext) - .build(); + public List findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId) { + return friends.stream() + .filter( + item -> + item.getFollowing().getId().equals(memberId) + && ltCursorId(cursorId, item)) + .map( + item -> + Follower.builder() + .friendId(item.getId()) + .memberId(item.getMember().getId()) + .name(item.getMember().getNickname()) + .profileImageUrl(item.getMember().getProfileImageUrl()) + .introduction(item.getMember().getIntroduction()) + .build()) + .toList(); } @Override diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java index 0040ef68..7c4af613 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -1,11 +1,34 @@ package com.depromeet.blacklist.repository; +import static com.depromeet.blacklist.entity.QBlacklistEntity.blacklistEntity; + import com.depromeet.blacklist.port.out.BlacklistPersistencePort; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class BlacklistRepository implements BlacklistPersistencePort { + private final JPAQueryFactory queryFactory; private final BlacklistJpaRepository blacklistJpaRepository; + + @Override + public List findBlackMemberIdsByMemberId(Long memberId) { + return queryFactory + .select(blacklistEntity.blackMember.id) + .from(blacklistEntity) + .where(blacklistEntity.member.id.eq(memberId)) + .fetch(); + } + + @Override + public List findMemberIdsByWhoBlockedMe(Long memberId) { + return queryFactory + .select(blacklistEntity.member.id) + .from(blacklistEntity) + .where(blacklistEntity.blackMember.id.eq(memberId)) + .fetch(); + } } diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/friend/repository/FriendRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/friend/repository/FriendRepository.java index 1c453d13..5a1ebd5b 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/friend/repository/FriendRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/friend/repository/FriendRepository.java @@ -16,7 +16,6 @@ import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; @@ -71,82 +70,48 @@ public void deleteByMemberIdAndFollowingId(Long memberId, Long followingId) { } @Override - public FollowSlice findFollowingsByMemberIdAndCursorId( - Long memberId, Long cursorId) { - List content = - queryFactory - .select( - Projections.constructor( - Following.class, - friend.id.as("friendId"), - friend.following.id.as("memberId"), - friend.following.nickname.as("name"), - friend.following.profileImageUrl.as("profileImageUrl"), - friend.following.introduction.as("introduction"))) - .from(friend) - .where(friend.member.id.eq(memberId), ltCursorId(cursorId)) - .limit(11) - .orderBy(friend.id.desc()) - .fetch(); - - boolean hasNext = false; - Long nextCursorId = null; - if (content.size() > 10) { - content = new ArrayList<>(content); - content.removeLast(); - hasNext = true; - nextCursorId = content.getLast().getFriendId(); - } - return FollowSlice.builder() - .followContents(content) - .pageSize(content.size()) - .cursorId(nextCursorId) - .hasNext(hasNext) - .build(); + public List findFollowingsByMemberIdAndCursorId(Long memberId, Long cursorId) { + return queryFactory + .select( + Projections.constructor( + Following.class, + friend.id.as("friendId"), + friend.following.id.as("memberId"), + friend.following.nickname.as("name"), + friend.following.profileImageUrl.as("profileImageUrl"), + friend.following.introduction.as("introduction"))) + .from(friend) + .where(friend.member.id.eq(memberId), ltCursorId(cursorId)) + .limit(11) + .orderBy(friend.id.desc()) + .fetch(); } @Override - public FollowSlice findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId) { + public List findFollowersByMemberIdAndCursorId(Long memberId, Long cursorId) { QFriendEntity subFriend = new QFriendEntity("sub"); - List result = - queryFactory - .select( - Projections.constructor( - Follower.class, - friend.id.as("friendId"), - friend.member.id.as("memberId"), - friend.member.nickname.as("name"), - friend.member.profileImageUrl.as("profileImageUrl"), - friend.member.introduction.as("introduction"), - ExpressionUtils.as( - select(Expressions.constant(true)) - .from(subFriend) - .where( - friend.member.id.eq( - subFriend.following.id), - friend.following.id.eq( - subFriend.member.id)), - "hasFollowedBack"))) - .from(friend) - .where(friend.following.id.eq(memberId), ltCursorId(cursorId)) - .limit(11) - .orderBy(friend.id.desc()) - .fetch(); - - boolean hasNext = false; - Long nextCursorId = null; - if (result.size() > 10) { - result = new ArrayList<>(result); - result.removeLast(); - hasNext = true; - nextCursorId = result.getLast().getFriendId(); - } - return FollowSlice.builder() - .followContents(result) - .pageSize(result.size()) - .cursorId(nextCursorId) - .hasNext(hasNext) - .build(); + return queryFactory + .select( + Projections.constructor( + Follower.class, + friend.id.as("friendId"), + friend.member.id.as("memberId"), + friend.member.nickname.as("name"), + friend.member.profileImageUrl.as("profileImageUrl"), + friend.member.introduction.as("introduction"), + ExpressionUtils.as( + select(Expressions.constant(true)) + .from(subFriend) + .where( + friend.member.id.eq(subFriend.following.id), + friend.following.id.eq( + subFriend.member.id)), + "hasFollowedBack"))) + .from(friend) + .where(friend.following.id.eq(memberId), ltCursorId(cursorId)) + .limit(11) + .orderBy(friend.id.desc()) + .fetch(); } @Override diff --git a/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java b/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java index c027437e..11183b0d 100644 --- a/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java +++ b/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java @@ -5,7 +5,6 @@ import com.depromeet.TestQueryDslConfig; import com.depromeet.fixture.domain.member.MemberFixture; import com.depromeet.friend.domain.Friend; -import com.depromeet.friend.domain.vo.FollowSlice; import com.depromeet.friend.domain.vo.Follower; import com.depromeet.friend.domain.vo.Following; import com.depromeet.member.domain.Member; @@ -121,14 +120,14 @@ private Long saveFriend() { expectedFollowing.stream().map(Following::getName).toList(); // when - FollowSlice result = + List result = friendRepository.findFollowingsByMemberIdAndCursorId(member.getId(), null); - List resultFollowingNames = - result.getFollowContents().stream().map(Following::getName).toList(); + List resultFollowingNames = result.stream().map(Following::getName).toList(); + if (resultFollowingNames.size() > 10) { + resultFollowingNames.removeLast(); + } // then - assertThat(result.getFollowContents()).isNotNull(); - assertThat(result.getFollowContents()).hasSize(10); assertThat(resultFollowingNames) .containsExactlyInAnyOrderElementsOf(expectedFollowingNames); } @@ -157,14 +156,14 @@ private Long saveFriend() { expectedFollowers.stream().map(Follower::getName).toList(); // when - FollowSlice result = + List result = friendRepository.findFollowersByMemberIdAndCursorId(member.getId(), null); - List resultFollowerNames = - result.getFollowContents().stream().map(Follower::getName).toList(); + List resultFollowerNames = result.stream().map(Follower::getName).toList(); + if (resultFollowerNames.size() > 10) { + resultFollowerNames.removeLast(); + } // then - assertThat(result.getFollowContents()).isNotNull(); - assertThat(result.getFollowContents()).hasSize(10); assertThat(resultFollowerNames).containsExactlyInAnyOrderElementsOf(expectedFollowerNames); } diff --git a/module-presentation/src/main/java/com/depromeet/friend/dto/response/FollowSliceResponse.java b/module-presentation/src/main/java/com/depromeet/friend/dto/response/FollowSliceResponse.java index 32384ef0..0a762cb9 100644 --- a/module-presentation/src/main/java/com/depromeet/friend/dto/response/FollowSliceResponse.java +++ b/module-presentation/src/main/java/com/depromeet/friend/dto/response/FollowSliceResponse.java @@ -28,32 +28,36 @@ public record FollowSliceResponse( public FollowSliceResponse {} public static FollowSliceResponse toFollowingSliceResponse( - FollowSlice followingSlice, String profileImageDomain) { + FollowSlice followingSlice, + List filteredFollowings, + String profileImageDomain) { List followingResponses = - getFollowingResponses(followingSlice, profileImageDomain); + getFollowingResponses(filteredFollowings, profileImageDomain); return FollowSliceResponse.builder() .contents(followingResponses) - .pageSize(followingSlice.getPageSize()) + .pageSize(followingResponses.size()) .cursorId(followingSlice.getCursorId()) .hasNext(followingSlice.isHasNext()) .build(); } public static FollowSliceResponse toFollowerSliceResponses( - FollowSlice followingSlice, String profileImageOrigin) { - List followingResponses = - getFollowerResponses(followingSlice, profileImageOrigin); + FollowSlice followingSlice, + List filteredFollowers, + String profileImageOrigin) { + List followerResponses = + getFollowerResponses(filteredFollowers, profileImageOrigin); return FollowSliceResponse.builder() - .contents(followingResponses) - .pageSize(followingSlice.getPageSize()) + .contents(followerResponses) + .pageSize(followerResponses.size()) .cursorId(followingSlice.getCursorId()) .hasNext(followingSlice.isHasNext()) .build(); } private static List getFollowingResponses( - FollowSlice followingSlice, String profileImageOrigin) { - return followingSlice.getFollowContents().stream() + List followings, String profileImageOrigin) { + return followings.stream() .map( following -> FollowingResponse.builder() @@ -67,8 +71,8 @@ private static List getFollowingResponses( } private static List getFollowerResponses( - FollowSlice followingSlice, String profileImageOrigin) { - return followingSlice.getFollowContents().stream() + List followers, String profileImageOrigin) { + return followers.stream() .map( follower -> FollowerResponse.builder() diff --git a/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java b/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java index 97f15e0d..446abba0 100644 --- a/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java +++ b/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java @@ -1,5 +1,6 @@ package com.depromeet.friend.facade; +import com.depromeet.blacklist.port.in.BlacklistGetUseCase; import com.depromeet.friend.domain.vo.FollowCheck; import com.depromeet.friend.domain.vo.FollowSlice; import com.depromeet.friend.domain.vo.Follower; @@ -11,6 +12,7 @@ import com.depromeet.member.port.in.usecase.MemberUseCase; import com.depromeet.notification.event.FollowLogEvent; import java.util.List; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; @@ -23,6 +25,7 @@ public class FollowFacade { private final FollowUseCase followUseCase; private final MemberUseCase memberUseCase; + private final BlacklistGetUseCase blacklistGetUseCase; private final ApplicationEventPublisher eventPublisher; @Value("${cloud-front.domain}") @@ -40,13 +43,28 @@ public boolean addOrDeleteFollow(Long memberId, FollowRequest followRequest) { public FollowSliceResponse findFollowingList(Long memberId, Long cursorId) { FollowSlice followingSlice = followUseCase.getFollowingByMemberIdAndCursorId(memberId, cursorId); - return FollowSliceResponse.toFollowingSliceResponse(followingSlice, profileImageOrigin); + Set hiddenMemberIds = blacklistGetUseCase.getHiddenMemberIds(memberId); + + List filteredFollowings = + followingSlice.getFollowContents().stream() + .filter(following -> !hiddenMemberIds.contains(following.getMemberId())) + .toList(); + + return FollowSliceResponse.toFollowingSliceResponse( + followingSlice, filteredFollowings, profileImageOrigin); } public FollowSliceResponse findFollowerList(Long memberId, Long cursorId) { FollowSlice followerSlice = followUseCase.getFollowerByMemberIdAndCursorId(memberId, cursorId); - return FollowSliceResponse.toFollowerSliceResponses(followerSlice, profileImageOrigin); + Set hiddenMemberIds = blacklistGetUseCase.getHiddenMemberIds(memberId); + List filteredFollowers = + followerSlice.getFollowContents().stream() + .filter(following -> !hiddenMemberIds.contains(following.getMemberId())) + .toList(); + + return FollowSliceResponse.toFollowerSliceResponses( + followerSlice, filteredFollowers, profileImageOrigin); } public FollowingSummaryResponse findFollowingSummary(Long memberId) { From a917e2282cdb2660e2b2313c67515f5d1be1430c Mon Sep 17 00:00:00 2001 From: penrose15 Date: Sat, 7 Sep 2024 00:33:40 +0900 Subject: [PATCH 14/28] =?UTF-8?q?feat:=20=EC=BB=A8=ED=94=8C=EB=A6=AD?= =?UTF-8?q?=ED=8A=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/depromeet/blacklist/port/.gitkeep | 0 .../in/usecase/BlacklistCommandUseCase.java | 9 +++++ .../in/usecase/BlacklistQueryUseCase.java | 5 +++ .../port/out/BlacklistPersistencePort.java | 3 -- .../persistence/BlacklistPersistencePort.java | 11 ++++++ .../com/depromeet/blacklist/service/.gitkeep | 0 .../service/BlacklistGetService.java | 14 ------- .../blacklist/service/BlacklistService.java | 38 ++++++++++++++++++ .../type/blacklist/BlacklistErrorType.java | 25 ++++++++++++ .../type/blacklist/BlacklistSuccessType.java | 26 +++++++++++++ .../type/friend/FollowErrorType.java | 1 - .../depromeet/blacklist/repository/.gitkeep | 0 .../repository/BlacklistJpaRepository.java | 8 +++- .../repository/BlacklistRepository.java | 19 ++++++++- .../depromeet/blacklist/api/BlacklistApi.java | 21 ++++++++++ .../blacklist/api/BlacklistController.java | 39 +++++++++++++++++++ .../dto/request/BlackMemberRequest.java | 14 +++++++ .../blacklist/facade/BlacklistFacade.java | 32 +++++++++++++++ .../memory/api/MemoryController.java | 1 + 19 files changed, 245 insertions(+), 21 deletions(-) delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep delete mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java create mode 100644 module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java create mode 100644 module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java delete mode 100644 module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep b/module-domain/src/main/java/com/depromeet/blacklist/port/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java new file mode 100644 index 00000000..162a9275 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistCommandUseCase.java @@ -0,0 +1,9 @@ +package com.depromeet.blacklist.port.in.usecase; + +import com.depromeet.blacklist.domain.Blacklist; + +public interface BlacklistCommandUseCase { + Blacklist blackMember(Long memberId, Long blackMemberId); + + void unblackMember(Long memberId, Long blackMemberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java new file mode 100644 index 00000000..1a2b39b4 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java @@ -0,0 +1,5 @@ +package com.depromeet.blacklist.port.in.usecase; + +public interface BlacklistQueryUseCase { + boolean checkBlackMember(Long memberId, Long blackMemberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java deleted file mode 100644 index f6d6689a..00000000 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/out/BlacklistPersistencePort.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.depromeet.blacklist.port.out; - -public interface BlacklistPersistencePort {} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java new file mode 100644 index 00000000..25a86d35 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java @@ -0,0 +1,11 @@ +package com.depromeet.blacklist.port.out.persistence; + +import com.depromeet.blacklist.domain.Blacklist; + +public interface BlacklistPersistencePort { + Blacklist save(Blacklist blacklist); + + boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); + + void unblackMember(Long memberId, Long blackMemberId); +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep b/module-domain/src/main/java/com/depromeet/blacklist/service/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java deleted file mode 100644 index 7d41a277..00000000 --- a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistGetService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.depromeet.blacklist.service; - -import com.depromeet.blacklist.port.in.BlacklistGetUseCase; -import com.depromeet.blacklist.port.out.BlacklistPersistencePort; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class BlacklistGetService implements BlacklistGetUseCase { - private final BlacklistPersistencePort blacklistPersistencePort; -} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java new file mode 100644 index 00000000..b8c8ef92 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -0,0 +1,38 @@ +package com.depromeet.blacklist.service; + +import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; +import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; +import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; +import com.depromeet.member.domain.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BlacklistService implements BlacklistQueryUseCase, BlacklistCommandUseCase { + private final BlacklistPersistencePort blacklistPersistencePort; + + @Override + @Transactional + public Blacklist blackMember(Long memberId, Long blackMemberId) { + return blacklistPersistencePort.save( + Blacklist.builder() + .member(Member.builder().id(memberId).build()) + .blackMember(Member.builder().id(blackMemberId).build()) + .build()); + } + + @Override + @Transactional + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistPersistencePort.unblackMember(memberId, blackMemberId); + } + + @Override + public boolean checkBlackMember(Long memberId, Long blackMemberId) { + return blacklistPersistencePort.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); + } +} diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java new file mode 100644 index 00000000..f659cea8 --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java @@ -0,0 +1,25 @@ +package com.depromeet.type.blacklist; + +import com.depromeet.type.ErrorType; + +public enum BlacklistErrorType implements ErrorType { + ALREADY_BLACKED("BLACK_1", "이미 차단한 사용자입니다"); + + private final String code; + private final String message; + + BlacklistErrorType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java new file mode 100644 index 00000000..deb84c46 --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java @@ -0,0 +1,26 @@ +package com.depromeet.type.blacklist; + +import com.depromeet.type.SuccessType; + +public enum BlacklistSuccessType implements SuccessType { + BLACK_MEMBER_SUCCESS("BLACK_1", "사용자를 성공적으로 차단하였습니다"), + UNBLACK_MEMBER_SUCCESS("BLACK_2", "사용자를 차단 해제하였습니다"); + + private final String code; + private final String message; + + BlacklistSuccessType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java b/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java index caf99679..b21f802d 100644 --- a/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java +++ b/module-independent/src/main/java/com/depromeet/type/friend/FollowErrorType.java @@ -8,7 +8,6 @@ public enum FollowErrorType implements ErrorType { INVALID_FOLLOW_TYPE("FOLLOW_3", "올바르지 않은 팔로우 타입입니다"); private final String code; - private final String message; FollowErrorType(String code, String message) { diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java index 1c1c762d..c99a7164 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistJpaRepository.java @@ -1,6 +1,10 @@ package com.depromeet.blacklist.repository; -import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.entity.BlacklistEntity; import org.springframework.data.jpa.repository.JpaRepository; -public interface BlacklistJpaRepository extends JpaRepository {} +public interface BlacklistJpaRepository extends JpaRepository { + boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); + + void deleteByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); +} diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java index 0040ef68..be6c5a99 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -1,6 +1,8 @@ package com.depromeet.blacklist.repository; -import com.depromeet.blacklist.port.out.BlacklistPersistencePort; +import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.entity.BlacklistEntity; +import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -8,4 +10,19 @@ @RequiredArgsConstructor public class BlacklistRepository implements BlacklistPersistencePort { private final BlacklistJpaRepository blacklistJpaRepository; + + @Override + public Blacklist save(Blacklist blacklist) { + return blacklistJpaRepository.save(BlacklistEntity.from(blacklist)).toModel(); + } + + @Override + public boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId) { + return blacklistJpaRepository.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); + } + + @Override + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistJpaRepository.deleteByMemberIdAndBlackMemberId(memberId, blackMemberId); + } } diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java new file mode 100644 index 00000000..7c1c99f0 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java @@ -0,0 +1,21 @@ +package com.depromeet.blacklist.api; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; + +@Tag(name = "차단(Blacklist)") +public interface BlacklistApi { + @Operation(summary = "사용자 차단") + ApiResponse blackMember( + @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request); + + @Operation(summary = "사용자 차단 해제") + ApiResponse unblackMember( + @LoginMember Long memberId, @PathVariable("blackMemberId") Long blackMemberId); +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java new file mode 100644 index 00000000..8e083647 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java @@ -0,0 +1,39 @@ +package com.depromeet.blacklist.api; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.facade.BlacklistFacade; +import com.depromeet.config.Logging; +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import com.depromeet.type.blacklist.BlacklistSuccessType; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/member") +public class BlacklistController implements BlacklistApi { + private final BlacklistFacade blacklistFacade; + + @PostMapping("/black") + @Logging(item = "Blacklist", action = "POST") + public ApiResponse blackMember( + @LoginMember Long memberId, @Valid @RequestBody BlackMemberRequest request) { + blacklistFacade.blackMember(memberId, request); + return ApiResponse.success(BlacklistSuccessType.BLACK_MEMBER_SUCCESS); + } + + @DeleteMapping("/{blackMemberId}/black") + @Logging(item = "Blacklist", action = "DELETE") + public ApiResponse unblackMember( + @LoginMember Long memberId, @PathVariable("blackMemberId") Long blackMemberId) { + blacklistFacade.unblackMember(memberId, blackMemberId); + return ApiResponse.success(BlacklistSuccessType.UNBLACK_MEMBER_SUCCESS); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java new file mode 100644 index 00000000..68e7d9f3 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/request/BlackMemberRequest.java @@ -0,0 +1,14 @@ +package com.depromeet.blacklist.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; + +public record BlackMemberRequest( + @NotNull + @Positive + @Schema( + description = "차단 대상 사용자 ID", + example = "1", + requiredMode = Schema.RequiredMode.REQUIRED) + Long blackMemberId) {} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java new file mode 100644 index 00000000..711329df --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java @@ -0,0 +1,32 @@ +package com.depromeet.blacklist.facade; + +import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; +import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; +import com.depromeet.exception.BadRequestException; +import com.depromeet.type.blacklist.BlacklistErrorType; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class BlacklistFacade { + private final BlacklistQueryUseCase blacklistQueryUseCase; + private final BlacklistCommandUseCase blacklistCommandUseCase; + + public void blackMember(Long memberId, BlackMemberRequest request) { + Long blackMemberId = request.blackMemberId(); + boolean isAlreadyBlacked = blacklistQueryUseCase.checkBlackMember(memberId, blackMemberId); + if (isAlreadyBlacked) { + throw new BadRequestException(BlacklistErrorType.ALREADY_BLACKED); + } + + blacklistCommandUseCase.blackMember(memberId, blackMemberId); + } + + public void unblackMember(Long memberId, Long blackMemberId) { + blacklistCommandUseCase.unblackMember(memberId, blackMemberId); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java b/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java index 5738698a..51865d5b 100644 --- a/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java +++ b/module-presentation/src/main/java/com/depromeet/memory/api/MemoryController.java @@ -79,6 +79,7 @@ public ApiResponse getCalendar( } @DeleteMapping("/{memoryId}") + @Logging(item = "Memory", action = "DELETE") public ApiResponse delete( @LoginMember Long memberId, @PathVariable("memoryId") Long memoryId) { memoryFacade.deleteById(memberId, memoryId); From 07a9548b14628d8cb84c4f87efb1fc407377a652 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 00:54:52 +0900 Subject: [PATCH 15/28] =?UTF-8?q?feat:=20=EC=8B=A0=EA=B3=A0=20=EC=8A=A4?= =?UTF-8?q?=ED=94=84=EB=A0=88=EB=93=9C=EC=8B=9C=ED=8A=B8=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20=EA=B5=AC=ED=98=84=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/SpreadSheetProperties.java | 8 +- .../spreadsheet/GoogleSheetManager.java | 78 +++++++++++++++++-- .../resources/application-spreadsheet.yml | 3 + 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/config/SpreadSheetProperties.java b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/config/SpreadSheetProperties.java index 71bd12a2..6ddab98d 100644 --- a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/config/SpreadSheetProperties.java +++ b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/config/SpreadSheetProperties.java @@ -4,4 +4,10 @@ @ConfigurationProperties(prefix = "google.sheet") public record SpreadSheetProperties( - String credentialsFilePath, String applicationName, String sheetId, String range) {} + String credentialsFilePath, + String applicationName, + String sheetId, + String range, + String reportApplicationName, + String reportSheetId, + String reportRange) {} diff --git a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java index e110a72e..3d37a21e 100644 --- a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java +++ b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java @@ -4,6 +4,9 @@ import com.depromeet.config.SpreadSheetProperties; import com.depromeet.exception.InternalServerException; +import com.depromeet.image.domain.Image; +import com.depromeet.report.port.in.command.CreateReportCommand; +import com.depromeet.report.port.out.persistence.ReportPersistencePort; import com.depromeet.withdrawal.domain.ReasonType; import com.depromeet.withdrawal.port.out.persistence.WithdrawalReasonPort; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; @@ -25,21 +28,25 @@ import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Slf4j @Component @RequiredArgsConstructor -public class GoogleSheetManager implements WithdrawalReasonPort { +public class GoogleSheetManager implements WithdrawalReasonPort, ReportPersistencePort { private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); private static final List SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS); private final SpreadSheetProperties spreadSheetProperties; + @Value("${cloud-front.domain}") + private String domain; + @Override public void writeToSheet(ReasonType reasonType, String feedback) { try { - Sheets sheet = getSheetService(); + Sheets sheet = getSheetService(spreadSheetProperties.applicationName()); List> data = getData(reasonType, feedback); ValueRange valueRange = new ValueRange().setValues(data); @@ -60,7 +67,8 @@ public void writeToSheet(ReasonType reasonType, String feedback) { } } - private Sheets getSheetService() throws IOException, GeneralSecurityException { + private Sheets getSheetService(String sheetApplicationName) + throws IOException, GeneralSecurityException { GoogleCredentials googleCredentials = GoogleCredentials.fromStream( new FileInputStream(spreadSheetProperties.credentialsFilePath())) @@ -69,17 +77,75 @@ private Sheets getSheetService() throws IOException, GeneralSecurityException { GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, new HttpCredentialsAdapter(googleCredentials)) - .setApplicationName(spreadSheetProperties.applicationName()) + .setApplicationName(sheetApplicationName) .build(); } private List> getData(ReasonType reasonType, String feedback) { - String date = - LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + String date = getDateTimeNow(); feedback = feedback != null ? feedback : ""; List> data = new ArrayList<>(); data.add(List.of(reasonType.getCode(), reasonType.getReason(), feedback, date)); return data; } + + @Override + public void writeReportToSheet(CreateReportCommand command) { + try { + Sheets sheet = getSheetService(spreadSheetProperties.reportApplicationName()); + List> data = getReportData(command); + ValueRange valueRange = new ValueRange().setValues(data); + + AppendValuesResponse appendResult = + sheet.spreadsheets() + .values() + .append( + spreadSheetProperties.reportSheetId(), + spreadSheetProperties.reportRange(), + valueRange) + .setValueInputOption("RAW") + .setInsertDataOption("INSERT_ROWS") + .setIncludeValuesInResponse(true) + .execute(); + } catch (Exception e) { + log.error("Error writing to sheet", e); + throw new InternalServerException(FAILED_TO_INSERT_DATA_TO_SPREADSHEET); + } + } + + private List> getReportData(CreateReportCommand command) { + String date = getDateTimeNow(); + String diary = command.reportMemory().diary() == null ? "" : command.reportMemory().diary(); + + List> data = new ArrayList<>(); + data.add( + List.of( + command.member().id(), + command.member().nickname(), + command.reportMemory().member().id(), + command.reportMemory().member().nickname(), + command.reportMemory().id(), + getImagesUrl(command.images()), + diary, + command.reasonCode().name(), + command.reasonCode().getValue(), + date)); + return data; + } + + private static String getDateTimeNow() { + String date = + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + return date; + } + + private String getImagesUrl(List images) { + return images.isEmpty() + ? "" + : images.stream() + .map(image -> domain + "/" + image.getImageName()) + .toList() + .toString(); + } } diff --git a/module-infrastructure/google-spreadsheet/src/main/resources/application-spreadsheet.yml b/module-infrastructure/google-spreadsheet/src/main/resources/application-spreadsheet.yml index 4382beed..274e063a 100644 --- a/module-infrastructure/google-spreadsheet/src/main/resources/application-spreadsheet.yml +++ b/module-infrastructure/google-spreadsheet/src/main/resources/application-spreadsheet.yml @@ -9,3 +9,6 @@ google: application-name: ${GOOGLE_SHEET_APPLICATION_NAME} sheet-id: ${GOOGLE_SHEET_ID} range: ${GOOGLE_SHEET_RANGE} + report-application-name: ${GOOGLE_SHEET_REPORT_APPLICATION_NAME} + report-sheet-id: ${GOOGLE_SHEET_REPORT_ID} + report-range: ${GOOGLE_SHEET_REPORT_RANGE} From eb1feaa117ccf06d5714ab8115042f4477764875 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:04:27 +0900 Subject: [PATCH 16/28] =?UTF-8?q?feat:=20=EC=8B=A0=EA=B3=A0=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=B6=94=EA=B0=80=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../report/domain/ReportReasonCode.java | 30 +++++++++++++++++++ .../type/report/ReportSuccessType.java | 25 ++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/report/domain/ReportReasonCode.java create mode 100644 module-independent/src/main/java/com/depromeet/type/report/ReportSuccessType.java diff --git a/module-domain/src/main/java/com/depromeet/report/domain/ReportReasonCode.java b/module-domain/src/main/java/com/depromeet/report/domain/ReportReasonCode.java new file mode 100644 index 00000000..de630aec --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/report/domain/ReportReasonCode.java @@ -0,0 +1,30 @@ +package com.depromeet.report.domain; + +import com.depromeet.converter.AbstractCodedEnumConverter; +import com.depromeet.converter.CodedEnum; + +public enum ReportReasonCode implements CodedEnum { + REPORT_REASON_1("스팸, 광고"), + REPORT_REASON_2("폭력적인 발언"), + REPORT_REASON_3("음란성, 선정 내용"), + REPORT_REASON_4("개인정보 노출"), + REPORT_REASON_5("주제와 무관"); + + private String value; + + ReportReasonCode(String value) { + this.value = value; + } + + @Override + public String getValue() { + return this.value; + } + + @jakarta.persistence.Converter(autoApply = true) + static class Converter extends AbstractCodedEnumConverter { + public Converter() { + super(ReportReasonCode.class); + } + } +} diff --git a/module-independent/src/main/java/com/depromeet/type/report/ReportSuccessType.java b/module-independent/src/main/java/com/depromeet/type/report/ReportSuccessType.java new file mode 100644 index 00000000..1cd08f93 --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/report/ReportSuccessType.java @@ -0,0 +1,25 @@ +package com.depromeet.type.report; + +import com.depromeet.type.SuccessType; + +public enum ReportSuccessType implements SuccessType { + POST_RESULT_SUCCESS("REPORT_1", "신고 사유 등록에 성공하였습니다"); + + private final String code; + private final String message; + + ReportSuccessType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getMessage() { + return message; + } +} From ba37bfe80957ca44626c4c1f0d86558de7b641d3 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:05:21 +0900 Subject: [PATCH 17/28] =?UTF-8?q?feat:=20=EC=8B=A0=EA=B3=A0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/domain/vo/MemberIdAndNickname.java | 3 ++ .../domain/vo/MemoryIdAndDiaryAndMember.java | 5 +++ .../port/in/command/CreateReportCommand.java | 13 +++++++ .../port/in/usecase/CreateReportUseCase.java | 7 ++++ .../persistence/ReportPersistencePort.java | 7 ++++ .../report/service/ReportService.java | 18 ++++++++++ .../com/depromeet/report/api/ReportApi.java | 14 ++++++++ .../report/api/ReportController.java | 27 ++++++++++++++ .../report/dto/request/ReportRequest.java | 19 ++++++++++ .../depromeet/report/facade/ReportFacade.java | 36 +++++++++++++++++++ .../depromeet/report/mapper/ReportMapper.java | 18 ++++++++++ 11 files changed, 167 insertions(+) create mode 100644 module-domain/src/main/java/com/depromeet/member/domain/vo/MemberIdAndNickname.java create mode 100644 module-domain/src/main/java/com/depromeet/memory/domain/vo/MemoryIdAndDiaryAndMember.java create mode 100644 module-domain/src/main/java/com/depromeet/report/port/in/command/CreateReportCommand.java create mode 100644 module-domain/src/main/java/com/depromeet/report/port/in/usecase/CreateReportUseCase.java create mode 100644 module-domain/src/main/java/com/depromeet/report/port/out/persistence/ReportPersistencePort.java create mode 100644 module-domain/src/main/java/com/depromeet/report/service/ReportService.java create mode 100644 module-presentation/src/main/java/com/depromeet/report/api/ReportApi.java create mode 100644 module-presentation/src/main/java/com/depromeet/report/api/ReportController.java create mode 100644 module-presentation/src/main/java/com/depromeet/report/dto/request/ReportRequest.java create mode 100644 module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java create mode 100644 module-presentation/src/main/java/com/depromeet/report/mapper/ReportMapper.java diff --git a/module-domain/src/main/java/com/depromeet/member/domain/vo/MemberIdAndNickname.java b/module-domain/src/main/java/com/depromeet/member/domain/vo/MemberIdAndNickname.java new file mode 100644 index 00000000..43ac5356 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/member/domain/vo/MemberIdAndNickname.java @@ -0,0 +1,3 @@ +package com.depromeet.member.domain.vo; + +public record MemberIdAndNickname(Long id, String nickname) {} diff --git a/module-domain/src/main/java/com/depromeet/memory/domain/vo/MemoryIdAndDiaryAndMember.java b/module-domain/src/main/java/com/depromeet/memory/domain/vo/MemoryIdAndDiaryAndMember.java new file mode 100644 index 00000000..e1d6cc12 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/memory/domain/vo/MemoryIdAndDiaryAndMember.java @@ -0,0 +1,5 @@ +package com.depromeet.memory.domain.vo; + +import com.depromeet.member.domain.vo.MemberIdAndNickname; + +public record MemoryIdAndDiaryAndMember(Long id, String diary, MemberIdAndNickname member) {} diff --git a/module-domain/src/main/java/com/depromeet/report/port/in/command/CreateReportCommand.java b/module-domain/src/main/java/com/depromeet/report/port/in/command/CreateReportCommand.java new file mode 100644 index 00000000..a0b8d690 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/report/port/in/command/CreateReportCommand.java @@ -0,0 +1,13 @@ +package com.depromeet.report.port.in.command; + +import com.depromeet.image.domain.Image; +import com.depromeet.member.domain.vo.MemberIdAndNickname; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; +import com.depromeet.report.domain.ReportReasonCode; +import java.util.List; + +public record CreateReportCommand( + MemberIdAndNickname member, + MemoryIdAndDiaryAndMember reportMemory, + List images, + ReportReasonCode reasonCode) {} diff --git a/module-domain/src/main/java/com/depromeet/report/port/in/usecase/CreateReportUseCase.java b/module-domain/src/main/java/com/depromeet/report/port/in/usecase/CreateReportUseCase.java new file mode 100644 index 00000000..7f04899f --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/report/port/in/usecase/CreateReportUseCase.java @@ -0,0 +1,7 @@ +package com.depromeet.report.port.in.usecase; + +import com.depromeet.report.port.in.command.CreateReportCommand; + +public interface CreateReportUseCase { + void save(CreateReportCommand command); +} diff --git a/module-domain/src/main/java/com/depromeet/report/port/out/persistence/ReportPersistencePort.java b/module-domain/src/main/java/com/depromeet/report/port/out/persistence/ReportPersistencePort.java new file mode 100644 index 00000000..b7ee0f4f --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/report/port/out/persistence/ReportPersistencePort.java @@ -0,0 +1,7 @@ +package com.depromeet.report.port.out.persistence; + +import com.depromeet.report.port.in.command.CreateReportCommand; + +public interface ReportPersistencePort { + void writeReportToSheet(CreateReportCommand command); +} diff --git a/module-domain/src/main/java/com/depromeet/report/service/ReportService.java b/module-domain/src/main/java/com/depromeet/report/service/ReportService.java new file mode 100644 index 00000000..e1cb4428 --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/report/service/ReportService.java @@ -0,0 +1,18 @@ +package com.depromeet.report.service; + +import com.depromeet.report.port.in.command.CreateReportCommand; +import com.depromeet.report.port.in.usecase.CreateReportUseCase; +import com.depromeet.report.port.out.persistence.ReportPersistencePort; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ReportService implements CreateReportUseCase { + private final ReportPersistencePort reportPersistencePort; + + @Override + public void save(CreateReportCommand command) { + reportPersistencePort.writeReportToSheet(command); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/report/api/ReportApi.java b/module-presentation/src/main/java/com/depromeet/report/api/ReportApi.java new file mode 100644 index 00000000..4f92cf72 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/report/api/ReportApi.java @@ -0,0 +1,14 @@ +package com.depromeet.report.api; + +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import com.depromeet.report.dto.request.ReportRequest; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.RequestBody; + +@Tag(name = "기록 신고(Report)") +public interface ReportApi { + @Operation(description = "기록 신고 제출") + ApiResponse create(@LoginMember Long memberId, @RequestBody ReportRequest request); +} diff --git a/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java b/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java new file mode 100644 index 00000000..eeaceb51 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java @@ -0,0 +1,27 @@ +package com.depromeet.report.api; + +import com.depromeet.config.Logging; +import com.depromeet.dto.response.ApiResponse; +import com.depromeet.member.annotation.LoginMember; +import com.depromeet.report.dto.request.ReportRequest; +import com.depromeet.report.facade.ReportFacade; +import com.depromeet.type.report.ReportSuccessType; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/report") +public class ReportController implements ReportApi { + private final ReportFacade reportFacade; + + @PostMapping + @Logging(item = "Report", action = "POST") + public ApiResponse create(@LoginMember Long memberId, @RequestBody ReportRequest request) { + reportFacade.save(memberId, request); + return ApiResponse.success(ReportSuccessType.POST_RESULT_SUCCESS); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/report/dto/request/ReportRequest.java b/module-presentation/src/main/java/com/depromeet/report/dto/request/ReportRequest.java new file mode 100644 index 00000000..a24fd93a --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/report/dto/request/ReportRequest.java @@ -0,0 +1,19 @@ +package com.depromeet.report.dto.request; + +import com.depromeet.report.domain.ReportReasonCode; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +public record ReportRequest( + @NotNull + @Schema( + description = "신고할 기록 id", + example = "1", + requiredMode = Schema.RequiredMode.REQUIRED) + Long memoryId, + @NotNull + @Schema( + description = "신고 사유 code", + example = "REPORT_REASON_1", + requiredMode = Schema.RequiredMode.REQUIRED) + ReportReasonCode reasonCode) {} diff --git a/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java b/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java new file mode 100644 index 00000000..a3510a09 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java @@ -0,0 +1,36 @@ +package com.depromeet.report.facade; + +import com.depromeet.image.domain.Image; +import com.depromeet.image.port.in.ImageGetUseCase; +import com.depromeet.member.domain.vo.MemberIdAndNickname; +import com.depromeet.member.port.in.usecase.MemberUseCase; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; +import com.depromeet.memory.port.in.usecase.GetMemoryUseCase; +import com.depromeet.report.dto.request.ReportRequest; +import com.depromeet.report.mapper.ReportMapper; +import com.depromeet.report.port.in.command.CreateReportCommand; +import com.depromeet.report.port.in.usecase.CreateReportUseCase; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ReportFacade { + private final MemberUseCase memberUseCase; + private final ImageGetUseCase imageGetUseCase; + private final GetMemoryUseCase getMemoryUseCase; + private final CreateReportUseCase createReportUseCase; + + @Transactional + public void save(Long memberId, ReportRequest request) { + MemberIdAndNickname member = memberUseCase.findIdAndNicknameById(memberId); + MemoryIdAndDiaryAndMember reportMemory = + getMemoryUseCase.findIdAndNicknameById(request.memoryId()); + List images = imageGetUseCase.findImagesByMemoryId(reportMemory.id()); + CreateReportCommand command = + ReportMapper.toCommand(member, reportMemory, images, request.reasonCode()); + createReportUseCase.save(command); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/report/mapper/ReportMapper.java b/module-presentation/src/main/java/com/depromeet/report/mapper/ReportMapper.java new file mode 100644 index 00000000..f9938910 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/report/mapper/ReportMapper.java @@ -0,0 +1,18 @@ +package com.depromeet.report.mapper; + +import com.depromeet.image.domain.Image; +import com.depromeet.member.domain.vo.MemberIdAndNickname; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; +import com.depromeet.report.domain.ReportReasonCode; +import com.depromeet.report.port.in.command.CreateReportCommand; +import java.util.List; + +public class ReportMapper { + public static CreateReportCommand toCommand( + MemberIdAndNickname member, + MemoryIdAndDiaryAndMember reportMemory, + List images, + ReportReasonCode reasonCode) { + return new CreateReportCommand(member, reportMemory, images, reasonCode); + } +} From c0979621f4b41a259c90e01533b160231cc88b18 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:05:37 +0900 Subject: [PATCH 18/28] =?UTF-8?q?feat:=20=EC=8B=A0=EA=B3=A0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=8B=9C=20=EC=A1=B0=ED=9A=8C=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/port/in/usecase/MemberUseCase.java | 3 +++ .../persistence/MemberPersistencePort.java | 3 +++ .../member/service/MemberService.java | 8 +++++++ .../port/in/usecase/GetMemoryUseCase.java | 3 +++ .../persistence/MemoryPersistencePort.java | 3 +++ .../memory/service/MemoryService.java | 8 +++++++ .../member/repository/MemberRepository.java | 17 +++++++++++++++ .../memory/repository/MemoryRepository.java | 21 +++++++++++++++++++ 8 files changed, 66 insertions(+) diff --git a/module-domain/src/main/java/com/depromeet/member/port/in/usecase/MemberUseCase.java b/module-domain/src/main/java/com/depromeet/member/port/in/usecase/MemberUseCase.java index 758ac4a6..cd7b6452 100644 --- a/module-domain/src/main/java/com/depromeet/member/port/in/usecase/MemberUseCase.java +++ b/module-domain/src/main/java/com/depromeet/member/port/in/usecase/MemberUseCase.java @@ -1,6 +1,7 @@ package com.depromeet.member.port.in.usecase; import com.depromeet.member.domain.Member; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.member.domain.vo.MemberSearchPage; import com.depromeet.member.port.in.command.SocialMemberCommand; @@ -16,4 +17,6 @@ public interface MemberUseCase { Member findByProviderId(String providerId); Member createMemberBy(SocialMemberCommand command); + + MemberIdAndNickname findIdAndNicknameById(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/member/port/out/persistence/MemberPersistencePort.java b/module-domain/src/main/java/com/depromeet/member/port/out/persistence/MemberPersistencePort.java index c74f9542..d98f298a 100644 --- a/module-domain/src/main/java/com/depromeet/member/port/out/persistence/MemberPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/member/port/out/persistence/MemberPersistencePort.java @@ -2,6 +2,7 @@ import com.depromeet.member.domain.Member; import com.depromeet.member.domain.MemberGender; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.member.domain.vo.MemberSearchPage; import com.depromeet.member.port.in.command.UpdateMemberCommand; import java.util.Optional; @@ -30,4 +31,6 @@ public interface MemberPersistencePort { Optional update(UpdateMemberCommand command); Optional updateProfileImageUrl(Long memberId, String profileImageUrl); + + Optional findIdAndNicknameById(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/member/service/MemberService.java b/module-domain/src/main/java/com/depromeet/member/service/MemberService.java index cda990f7..94b42d96 100644 --- a/module-domain/src/main/java/com/depromeet/member/service/MemberService.java +++ b/module-domain/src/main/java/com/depromeet/member/service/MemberService.java @@ -7,6 +7,7 @@ import com.depromeet.member.domain.Member; import com.depromeet.member.domain.MemberGender; import com.depromeet.member.domain.MemberRole; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.member.domain.vo.MemberSearchPage; import com.depromeet.member.port.in.command.SocialMemberCommand; import com.depromeet.member.port.in.command.UpdateMemberCommand; @@ -82,6 +83,13 @@ public Member createMemberBy(SocialMemberCommand command) { return memberPersistencePort.save(member); } + @Override + public MemberIdAndNickname findIdAndNicknameById(Long memberId) { + return memberPersistencePort + .findIdAndNicknameById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorType.NOT_FOUND)); + } + @Override public Member update(UpdateMemberCommand command) { if (command.nickname() != null && command.nickname().isBlank()) { diff --git a/module-domain/src/main/java/com/depromeet/memory/port/in/usecase/GetMemoryUseCase.java b/module-domain/src/main/java/com/depromeet/memory/port/in/usecase/GetMemoryUseCase.java index 4507b440..a29c294e 100644 --- a/module-domain/src/main/java/com/depromeet/memory/port/in/usecase/GetMemoryUseCase.java +++ b/module-domain/src/main/java/com/depromeet/memory/port/in/usecase/GetMemoryUseCase.java @@ -2,6 +2,7 @@ import com.depromeet.memory.domain.Memory; import com.depromeet.memory.domain.vo.MemoryAndDetailId; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; import com.depromeet.memory.domain.vo.MemoryInfo; import java.util.List; @@ -17,4 +18,6 @@ public interface GetMemoryUseCase { MemoryInfo findByIdWithPrevNext(Long requestMemberId, Long memoryId); MemoryAndDetailId findMemoryAndDetailIdsByMemberId(Long memberId); + + MemoryIdAndDiaryAndMember findIdAndNicknameById(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/memory/port/out/persistence/MemoryPersistencePort.java b/module-domain/src/main/java/com/depromeet/memory/port/out/persistence/MemoryPersistencePort.java index 439c020d..57611dd0 100644 --- a/module-domain/src/main/java/com/depromeet/memory/port/out/persistence/MemoryPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/memory/port/out/persistence/MemoryPersistencePort.java @@ -2,6 +2,7 @@ import com.depromeet.memory.domain.Memory; import com.depromeet.memory.domain.vo.MemoryAndDetailId; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; import java.time.LocalDate; import java.util.List; import java.util.Optional; @@ -36,4 +37,6 @@ public interface MemoryPersistencePort { MemoryAndDetailId findMemoryAndDetailIdsByMemberId(Long memberId); void deleteById(Long memoryId); + + Optional findIdAndNicknameById(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/memory/service/MemoryService.java b/module-domain/src/main/java/com/depromeet/memory/service/MemoryService.java index b1a1ce3a..435a0f04 100644 --- a/module-domain/src/main/java/com/depromeet/memory/service/MemoryService.java +++ b/module-domain/src/main/java/com/depromeet/memory/service/MemoryService.java @@ -10,6 +10,7 @@ import com.depromeet.memory.domain.MemoryDetail; import com.depromeet.memory.domain.Stroke; import com.depromeet.memory.domain.vo.MemoryAndDetailId; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; import com.depromeet.memory.domain.vo.MemoryInfo; import com.depromeet.memory.port.in.command.CreateMemoryCommand; import com.depromeet.memory.port.in.command.UpdateMemoryCommand; @@ -110,6 +111,13 @@ public MemoryAndDetailId findMemoryAndDetailIdsByMemberId(Long memberId) { return memoryPersistencePort.findMemoryAndDetailIdsByMemberId(memberId); } + @Override + public MemoryIdAndDiaryAndMember findIdAndNicknameById(Long memberId) { + return memoryPersistencePort + .findIdAndNicknameById(memberId) + .orElseThrow(() -> new NotFoundException(MemoryErrorType.NOT_FOUND)); + } + @Override @Transactional public Memory update(Long memoryId, UpdateMemoryCommand command, List strokes) { diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/repository/MemberRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/repository/MemberRepository.java index 9a927b10..a4417e4f 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/repository/MemberRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/repository/MemberRepository.java @@ -3,12 +3,14 @@ import com.depromeet.friend.entity.QFriendEntity; import com.depromeet.member.domain.Member; import com.depromeet.member.domain.MemberGender; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.member.domain.vo.MemberSearchInfo; import com.depromeet.member.domain.vo.MemberSearchPage; import com.depromeet.member.entity.MemberEntity; import com.depromeet.member.entity.QMemberEntity; import com.depromeet.member.port.in.command.UpdateMemberCommand; import com.depromeet.member.port.out.persistence.MemberPersistencePort; +import com.querydsl.core.Tuple; import com.querydsl.core.types.ExpressionUtils; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; @@ -150,6 +152,21 @@ public Optional updateProfileImageUrl(Long memberId, String profileImage .map(memberEntity -> memberEntity.updateProfileImageUrl(profileImageUrl).toModel()); } + @Override + public Optional findIdAndNicknameById(Long memberId) { + Tuple result = + queryFactory + .select(member.id, member.nickname) + .from(member) + .where(member.id.eq(memberId)) + .fetchOne(); + if (result == null) { + return Optional.empty(); + } + return Optional.of( + new MemberIdAndNickname(result.get(0, Long.class), result.get(1, String.class))); + } + @Override public Optional updateGender(Long memberId, MemberGender gender) { return memberJpaRepository diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/memory/repository/MemoryRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/memory/repository/MemoryRepository.java index c24f32f7..2ab9cd5f 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/memory/repository/MemoryRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/memory/repository/MemoryRepository.java @@ -6,8 +6,10 @@ import static com.depromeet.memory.entity.QStrokeEntity.strokeEntity; import static com.depromeet.pool.entity.QPoolEntity.poolEntity; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.memory.domain.Memory; import com.depromeet.memory.domain.vo.MemoryAndDetailId; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; import com.depromeet.memory.entity.MemoryEntity; import com.depromeet.memory.entity.QMemoryEntity; import com.depromeet.memory.port.out.persistence.MemoryPersistencePort; @@ -216,6 +218,25 @@ public void deleteById(Long memoryId) { memoryJpaRepository.deleteById(memoryId); } + @Override + public Optional findIdAndNicknameById(Long memoryId) { + Tuple result = + queryFactory + .select(memory.id, memory.diary, memory.member.id, memory.member.nickname) + .from(memory) + .join(memory.member, memberEntity) + .where(memory.id.eq(memoryId)) + .fetchOne(); + if (result == null) { + return Optional.empty(); + } + MemberIdAndNickname member = + new MemberIdAndNickname(result.get(2, Long.class), result.get(3, String.class)); + return Optional.of( + new MemoryIdAndDiaryAndMember( + result.get(0, Long.class), result.get(1, String.class), member)); + } + private BooleanExpression loeRecordAt(LocalDate recordAt) { if (recordAt == null) { return null; From 987129bfde3ce5d518bbd5a9b4a296a0944a2030 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:05:46 +0900 Subject: [PATCH 19/28] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B5=AC=ED=98=84=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mock/member/FakeMemberRepository.java | 7 +++++++ .../mock/memory/FakeMemoryRepository.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/module-domain/src/test/java/com/depromeet/mock/member/FakeMemberRepository.java b/module-domain/src/test/java/com/depromeet/mock/member/FakeMemberRepository.java index 4f4aad7b..0a46d5a2 100644 --- a/module-domain/src/test/java/com/depromeet/mock/member/FakeMemberRepository.java +++ b/module-domain/src/test/java/com/depromeet/mock/member/FakeMemberRepository.java @@ -2,6 +2,7 @@ import com.depromeet.member.domain.Member; import com.depromeet.member.domain.MemberGender; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.member.domain.vo.MemberSearchPage; import com.depromeet.member.port.in.command.UpdateMemberCommand; import com.depromeet.member.port.out.persistence.MemberPersistencePort; @@ -122,4 +123,10 @@ public Optional updateProfileImageUrl(Long memberId, String profileImage return member; }); } + + @Override + public Optional findIdAndNicknameById(Long memberId) { + return findById(memberId) + .map(item -> new MemberIdAndNickname(item.getId(), item.getNickname())); + } } diff --git a/module-domain/src/test/java/com/depromeet/mock/memory/FakeMemoryRepository.java b/module-domain/src/test/java/com/depromeet/mock/memory/FakeMemoryRepository.java index e1c123f9..137f8754 100644 --- a/module-domain/src/test/java/com/depromeet/mock/memory/FakeMemoryRepository.java +++ b/module-domain/src/test/java/com/depromeet/mock/memory/FakeMemoryRepository.java @@ -1,7 +1,9 @@ package com.depromeet.mock.memory; +import com.depromeet.member.domain.vo.MemberIdAndNickname; import com.depromeet.memory.domain.Memory; import com.depromeet.memory.domain.vo.MemoryAndDetailId; +import com.depromeet.memory.domain.vo.MemoryIdAndDiaryAndMember; import com.depromeet.memory.port.out.persistence.MemoryPersistencePort; import java.time.LocalDate; import java.util.ArrayList; @@ -194,4 +196,17 @@ public MemoryAndDetailId findMemoryAndDetailIdsByMemberId(Long memberId) { public void deleteById(Long memoryId) { data.removeIf(item -> item.getId().equals(memoryId)); } + + @Override + public Optional findIdAndNicknameById(Long memberId) { + return findById(memberId) + .map( + item -> + new MemoryIdAndDiaryAndMember( + item.getId(), + item.getDiary(), + new MemberIdAndNickname( + item.getMember().getId(), + item.getMember().getNickname()))); + } } From abaf7ddfc4869fb4a8c0ac5d29e56250e3c166bc Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:19:46 +0900 Subject: [PATCH 20/28] =?UTF-8?q?feat:=20=EC=9E=90=EC=8B=A0=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=EC=97=90=20=EC=8B=A0=EA=B3=A0=20=EB=B6=88?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../type/report/ReportErrorType.java | 25 +++++++++++++++++++ .../depromeet/report/facade/ReportFacade.java | 5 ++++ 2 files changed, 30 insertions(+) create mode 100644 module-independent/src/main/java/com/depromeet/type/report/ReportErrorType.java diff --git a/module-independent/src/main/java/com/depromeet/type/report/ReportErrorType.java b/module-independent/src/main/java/com/depromeet/type/report/ReportErrorType.java new file mode 100644 index 00000000..bccceba6 --- /dev/null +++ b/module-independent/src/main/java/com/depromeet/type/report/ReportErrorType.java @@ -0,0 +1,25 @@ +package com.depromeet.type.report; + +import com.depromeet.type.ErrorType; + +public enum ReportErrorType implements ErrorType { + CANNOT_REPORT_OWN_MEMORY("REPORT_1", "자신의 기록을 신고할 수 없습니다"); + + private final String code; + private final String message; + + ReportErrorType(String code, String message) { + this.code = code; + this.message = message; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java b/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java index a3510a09..30077884 100644 --- a/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java +++ b/module-presentation/src/main/java/com/depromeet/report/facade/ReportFacade.java @@ -1,5 +1,6 @@ package com.depromeet.report.facade; +import com.depromeet.exception.BadRequestException; import com.depromeet.image.domain.Image; import com.depromeet.image.port.in.ImageGetUseCase; import com.depromeet.member.domain.vo.MemberIdAndNickname; @@ -10,6 +11,7 @@ import com.depromeet.report.mapper.ReportMapper; import com.depromeet.report.port.in.command.CreateReportCommand; import com.depromeet.report.port.in.usecase.CreateReportUseCase; +import com.depromeet.type.report.ReportErrorType; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -28,6 +30,9 @@ public void save(Long memberId, ReportRequest request) { MemberIdAndNickname member = memberUseCase.findIdAndNicknameById(memberId); MemoryIdAndDiaryAndMember reportMemory = getMemoryUseCase.findIdAndNicknameById(request.memoryId()); + if (memberId.equals(reportMemory.member().id())) { + throw new BadRequestException(ReportErrorType.CANNOT_REPORT_OWN_MEMORY); + } List images = imageGetUseCase.findImagesByMemoryId(reportMemory.id()); CreateReportCommand command = ReportMapper.toCommand(member, reportMemory, images, request.reasonCode()); From ba684e03a779271857cbb2bb16e2fbcb9eeda2b7 Mon Sep 17 00:00:00 2001 From: penrose15 Date: Sat, 7 Sep 2024 01:22:18 +0900 Subject: [PATCH 21/28] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/depromeet/friend/repository/FriendRepositoryTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java b/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java index 11183b0d..acbfff5d 100644 --- a/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java +++ b/module-infrastructure/persistence-database/src/test/java/com/depromeet/friend/repository/FriendRepositoryTest.java @@ -125,6 +125,7 @@ private Long saveFriend() { List resultFollowingNames = result.stream().map(Following::getName).toList(); if (resultFollowingNames.size() > 10) { + resultFollowingNames = new ArrayList<>(resultFollowingNames); resultFollowingNames.removeLast(); } // then @@ -160,6 +161,7 @@ private Long saveFriend() { friendRepository.findFollowersByMemberIdAndCursorId(member.getId(), null); List resultFollowerNames = result.stream().map(Follower::getName).toList(); if (resultFollowerNames.size() > 10) { + resultFollowerNames = new ArrayList<>(resultFollowerNames); resultFollowerNames.removeLast(); } From 309aa75881ef479c85650530b42a3ad10ee27b29 Mon Sep 17 00:00:00 2001 From: penrose15 Date: Sat, 7 Sep 2024 01:27:14 +0900 Subject: [PATCH 22/28] =?UTF-8?q?feat:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81=20(#379)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blacklist/port/in/usecase/BlacklistQueryUseCase.java | 2 +- .../port/out/persistence/BlacklistPersistencePort.java | 2 +- .../com/depromeet/blacklist/service/BlacklistService.java | 4 ++-- .../blacklist/repository/BlacklistRepository.java | 2 +- .../java/com/depromeet/friend/facade/FollowFacade.java | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java index 28fa58f5..2b44c3b9 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java @@ -5,5 +5,5 @@ public interface BlacklistQueryUseCase { boolean checkBlackMember(Long memberId, Long blackMemberId); - Set getHiddenMemberIds(Long memberId); + Set getBlackMemberIds(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java index 8c51e66d..dff071d0 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java @@ -12,5 +12,5 @@ public interface BlacklistPersistencePort { List findBlackMemberIdsByMemberId(Long memberId); - List findMemberIdsByWhoBlockedMe(Long memberId); + List findMemberIdsWhoBlockedMe(Long memberId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java index 52a22ee4..73096963 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -40,7 +40,7 @@ public boolean checkBlackMember(Long memberId, Long blackMemberId) { } @Override - public Set getHiddenMemberIds(Long memberId) { + public Set getBlackMemberIds(Long memberId) { List blackMemberIds = getBlackMemberIdsByMemberId(memberId); List memberIdsWhoBlockedMe = getMemberIdsWhoBlockedMe(memberId); @@ -54,6 +54,6 @@ private List getBlackMemberIdsByMemberId(Long memberId) { } private List getMemberIdsWhoBlockedMe(Long memberId) { - return blacklistPersistencePort.findMemberIdsByWhoBlockedMe(memberId); + return blacklistPersistencePort.findMemberIdsWhoBlockedMe(memberId); } } diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java index 7692472f..fd3f0327 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -41,7 +41,7 @@ public List findBlackMemberIdsByMemberId(Long memberId) { } @Override - public List findMemberIdsByWhoBlockedMe(Long memberId) { + public List findMemberIdsWhoBlockedMe(Long memberId) { return queryFactory .select(blacklistEntity.member.id) .from(blacklistEntity) diff --git a/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java b/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java index 04574d11..46326abd 100644 --- a/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java +++ b/module-presentation/src/main/java/com/depromeet/friend/facade/FollowFacade.java @@ -43,11 +43,11 @@ public boolean addOrDeleteFollow(Long memberId, FollowRequest followRequest) { public FollowSliceResponse findFollowingList(Long memberId, Long cursorId) { FollowSlice followingSlice = followUseCase.getFollowingByMemberIdAndCursorId(memberId, cursorId); - Set hiddenMemberIds = blacklistQueryUseCase.getHiddenMemberIds(memberId); + Set blackMemberIds = blacklistQueryUseCase.getBlackMemberIds(memberId); List filteredFollowings = followingSlice.getFollowContents().stream() - .filter(following -> !hiddenMemberIds.contains(following.getMemberId())) + .filter(following -> !blackMemberIds.contains(following.getMemberId())) .toList(); return FollowSliceResponse.toFollowingSliceResponse( @@ -57,10 +57,10 @@ public FollowSliceResponse findFollowingList(Long memberId, L public FollowSliceResponse findFollowerList(Long memberId, Long cursorId) { FollowSlice followerSlice = followUseCase.getFollowerByMemberIdAndCursorId(memberId, cursorId); - Set hiddenMemberIds = blacklistQueryUseCase.getHiddenMemberIds(memberId); + Set blackMemberIds = blacklistQueryUseCase.getBlackMemberIds(memberId); List filteredFollowers = followerSlice.getFollowContents().stream() - .filter(following -> !hiddenMemberIds.contains(following.getMemberId())) + .filter(following -> !blackMemberIds.contains(following.getMemberId())) .toList(); return FollowSliceResponse.toFollowerSliceResponses( From c47e0baa18b6a69e59bb581f2d5a4bf60c13e461 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:35:05 +0900 Subject: [PATCH 23/28] =?UTF-8?q?chore:=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B0=84=EC=86=8C=ED=99=94=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/spreadsheet/GoogleSheetManager.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java index 3d37a21e..e9446f35 100644 --- a/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java +++ b/module-infrastructure/google-spreadsheet/src/main/java/com/depromeet/spreadsheet/GoogleSheetManager.java @@ -135,9 +135,7 @@ private List> getReportData(CreateReportCommand command) { } private static String getDateTimeNow() { - String date = - LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - return date; + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } private String getImagesUrl(List images) { From b6015aec678264b8807a5c58074773cca1120795 Mon Sep 17 00:00:00 2001 From: ywonchae1 Date: Sat, 7 Sep 2024 01:35:19 +0900 Subject: [PATCH 24/28] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=20=EA=B0=92=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80=20(#378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/depromeet/report/api/ReportController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java b/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java index eeaceb51..69f4adb2 100644 --- a/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java +++ b/module-presentation/src/main/java/com/depromeet/report/api/ReportController.java @@ -6,6 +6,7 @@ import com.depromeet.report.dto.request.ReportRequest; import com.depromeet.report.facade.ReportFacade; import com.depromeet.type.report.ReportSuccessType; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -20,7 +21,8 @@ public class ReportController implements ReportApi { @PostMapping @Logging(item = "Report", action = "POST") - public ApiResponse create(@LoginMember Long memberId, @RequestBody ReportRequest request) { + public ApiResponse create( + @LoginMember Long memberId, @Valid @RequestBody ReportRequest request) { reportFacade.save(memberId, request); return ApiResponse.success(ReportSuccessType.POST_RESULT_SUCCESS); } From df8e406ec9d9a7bc202bffa5ca13a92fe36c3d71 Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 01:53:43 +0900 Subject: [PATCH 25/28] =?UTF-8?q?feat:=20=EC=B0=A8=EB=8B=A8=ED=95=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blacklist/domain/vo/BlacklistPage.java | 10 ++++ .../in/usecase/BlacklistQueryUseCase.java | 4 ++ .../persistence/BlacklistPersistencePort.java | 4 ++ .../blacklist/service/BlacklistService.java | 15 +++++ .../com/depromeet/member/domain/Member.java | 7 +++ .../type/blacklist/BlacklistSuccessType.java | 3 +- .../repository/BlacklistRepository.java | 44 +++++++++++++++ .../depromeet/member/entity/MemberEntity.java | 7 +++ .../blacklist/api/BlacklistController.java | 12 ++++ .../response/BlackMemberDetailResponse.java | 56 +++++++++++++++++++ .../dto/response/BlackMemberResponse.java | 28 ++++++++++ .../blacklist/facade/BlacklistFacade.java | 12 ++++ 12 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 module-domain/src/main/java/com/depromeet/blacklist/domain/vo/BlacklistPage.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java create mode 100644 module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberResponse.java diff --git a/module-domain/src/main/java/com/depromeet/blacklist/domain/vo/BlacklistPage.java b/module-domain/src/main/java/com/depromeet/blacklist/domain/vo/BlacklistPage.java new file mode 100644 index 00000000..1f0c493a --- /dev/null +++ b/module-domain/src/main/java/com/depromeet/blacklist/domain/vo/BlacklistPage.java @@ -0,0 +1,10 @@ +package com.depromeet.blacklist.domain.vo; + +import com.depromeet.member.domain.Member; +import java.util.List; + +public record BlacklistPage(List blackMembers, boolean hasNext, Long cursorId) { + public static BlacklistPage of(List blackMembers, boolean hasNext, Long nextCursorId) { + return new BlacklistPage(blackMembers, hasNext, nextCursorId); + } +} diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java index 1a2b39b4..da76a301 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/in/usecase/BlacklistQueryUseCase.java @@ -1,5 +1,9 @@ package com.depromeet.blacklist.port.in.usecase; +import com.depromeet.blacklist.domain.vo.BlacklistPage; + public interface BlacklistQueryUseCase { boolean checkBlackMember(Long memberId, Long blackMemberId); + + BlacklistPage getBlackMembers(Long memberId, Long cursorId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java index 25a86d35..00b76d72 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/port/out/persistence/BlacklistPersistencePort.java @@ -1,6 +1,8 @@ package com.depromeet.blacklist.port.out.persistence; import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.member.domain.Member; +import java.util.List; public interface BlacklistPersistencePort { Blacklist save(Blacklist blacklist); @@ -8,4 +10,6 @@ public interface BlacklistPersistencePort { boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberId); void unblackMember(Long memberId, Long blackMemberId); + + List findBlackMembers(Long memberId, Long cursorId); } diff --git a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java index b8c8ef92..aadaea0a 100644 --- a/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java +++ b/module-domain/src/main/java/com/depromeet/blacklist/service/BlacklistService.java @@ -1,10 +1,12 @@ package com.depromeet.blacklist.service; import com.depromeet.blacklist.domain.Blacklist; +import com.depromeet.blacklist.domain.vo.BlacklistPage; import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; import com.depromeet.member.domain.Member; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,4 +37,17 @@ public void unblackMember(Long memberId, Long blackMemberId) { public boolean checkBlackMember(Long memberId, Long blackMemberId) { return blacklistPersistencePort.existsByMemberIdAndBlackMemberId(memberId, blackMemberId); } + + @Override + public BlacklistPage getBlackMembers(Long memberId, Long cursorId) { + List blackMembers = blacklistPersistencePort.findBlackMembers(memberId, cursorId); + boolean hasNext = false; + Long nextCursorId = null; + if (blackMembers != null && blackMembers.size() > 10) { + hasNext = true; + Member member = blackMembers.removeLast(); + nextCursorId = member.getId(); + } + return BlacklistPage.of(blackMembers, hasNext, nextCursorId); + } } diff --git a/module-domain/src/main/java/com/depromeet/member/domain/Member.java b/module-domain/src/main/java/com/depromeet/member/domain/Member.java index 83dd5162..834b41c0 100644 --- a/module-domain/src/main/java/com/depromeet/member/domain/Member.java +++ b/module-domain/src/main/java/com/depromeet/member/domain/Member.java @@ -43,6 +43,13 @@ public Member( this.lastViewedFollowingLogAt = lastViewedFollowingLogAt; } + public Member(Long id, String nickname, String profileImageUrl, String introduction) { + this.id = id; + this.nickname = nickname; + this.profileImageUrl = profileImageUrl; + this.introduction = introduction; + } + public Member updateGoal(Integer goal) { this.goal = goal; return this; diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java index deb84c46..8351a106 100644 --- a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistSuccessType.java @@ -4,7 +4,8 @@ public enum BlacklistSuccessType implements SuccessType { BLACK_MEMBER_SUCCESS("BLACK_1", "사용자를 성공적으로 차단하였습니다"), - UNBLACK_MEMBER_SUCCESS("BLACK_2", "사용자를 차단 해제하였습니다"); + UNBLACK_MEMBER_SUCCESS("BLACK_2", "사용자를 차단 해제하였습니다"), + GET_BLACK_MEMBERS_SUCCESS("BLACK_3", "사용자의 차단 목록을 성공적으로 조회하였습니다"); private final String code; private final String message; diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java index be6c5a99..b2b0d7d2 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/blacklist/repository/BlacklistRepository.java @@ -1,14 +1,23 @@ package com.depromeet.blacklist.repository; +import static com.depromeet.blacklist.entity.QBlacklistEntity.*; + import com.depromeet.blacklist.domain.Blacklist; import com.depromeet.blacklist.entity.BlacklistEntity; import com.depromeet.blacklist.port.out.persistence.BlacklistPersistencePort; +import com.depromeet.member.domain.Member; +import com.depromeet.member.entity.QMemberEntity; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class BlacklistRepository implements BlacklistPersistencePort { + private final JPAQueryFactory queryFactory; private final BlacklistJpaRepository blacklistJpaRepository; @Override @@ -25,4 +34,39 @@ public boolean existsByMemberIdAndBlackMemberId(Long memberId, Long blackMemberI public void unblackMember(Long memberId, Long blackMemberId) { blacklistJpaRepository.deleteByMemberIdAndBlackMemberId(memberId, blackMemberId); } + + @Override + public List findBlackMembers(Long memberId, Long cursorId) { + QMemberEntity member = new QMemberEntity("member"); // 첫 번째 별칭 "member" + QMemberEntity blackMember = new QMemberEntity("blackMember"); + + return queryFactory + .select( + Projections.constructor( + Member.class, // 원하는 DTO나 엔티티 클래스 지정 + blacklistEntity.blackMember.id, + blacklistEntity.blackMember.nickname, + blacklistEntity.blackMember.profileImageUrl, + blacklistEntity.blackMember.introduction)) + .from(blacklistEntity) + .join(blacklistEntity.blackMember, blackMember) + .where(memberEq(memberId), blacklistIdLoe(cursorId)) + .orderBy(blacklistEntity.blackMember.id.desc()) + .limit(11) + .fetch(); + } + + private static BooleanExpression memberEq(Long memberId) { + if (memberId == null) { + return null; + } + return blacklistEntity.member.id.eq(memberId); + } + + private BooleanExpression blacklistIdLoe(Long cursorId) { + if (cursorId == null) { + return null; + } + return blacklistEntity.blackMember.id.loe(cursorId); + } } diff --git a/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/entity/MemberEntity.java b/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/entity/MemberEntity.java index 9a5fa514..4d2540c2 100644 --- a/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/entity/MemberEntity.java +++ b/module-infrastructure/persistence-database/src/main/java/com/depromeet/member/entity/MemberEntity.java @@ -69,6 +69,13 @@ public MemberEntity( this.lastViewedFollowingLogAt = lastViewedFollowingLogAt; } + public MemberEntity(Long id, String nickname, String profileImageUrl, String introduction) { + this.id = id; + this.nickname = nickname; + this.profileImageUrl = profileImageUrl; + this.introduction = introduction; + } + @PrePersist public void prePersist() { this.goal = 1000; diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java index 8e083647..b3c8eb01 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistController.java @@ -1,6 +1,7 @@ package com.depromeet.blacklist.api; import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.dto.response.BlackMemberResponse; import com.depromeet.blacklist.facade.BlacklistFacade; import com.depromeet.config.Logging; import com.depromeet.dto.response.ApiResponse; @@ -9,10 +10,12 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -36,4 +39,13 @@ public ApiResponse unblackMember( blacklistFacade.unblackMember(memberId, blackMemberId); return ApiResponse.success(BlacklistSuccessType.UNBLACK_MEMBER_SUCCESS); } + + @GetMapping("/black") + @Logging(item = "Blacklist", action = "GET") + public ApiResponse getBlackMembers( + @LoginMember Long memberId, + @RequestParam(value = "cursorId", required = false) Long cursorId) { + BlackMemberResponse response = blacklistFacade.getBlackMembers(memberId, cursorId); + return ApiResponse.success(BlacklistSuccessType.GET_BLACK_MEMBERS_SUCCESS, response); + } } diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java new file mode 100644 index 00000000..e0b56db5 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java @@ -0,0 +1,56 @@ +package com.depromeet.blacklist.dto.response; + +import com.depromeet.member.domain.Member; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public record BlackMemberDetailResponse( + @Schema( + description = "차단한 유저 아이디", + example = "2", + requiredMode = Schema.RequiredMode.REQUIRED) + Long memberId, + @Schema( + description = "차단한 유저 닉네임", + example = "스탑제로", + requiredMode = Schema.RequiredMode.REQUIRED) + String nickname, + @Schema( + description = "차단한 유저 프로필 이미지", + example = "https://example.com/image.jpg OR 기본 이미지(1,2,3,4)", + requiredMode = Schema.RequiredMode.REQUIRED) + String profileImageUrl, + @Schema( + description = "차단한 유저 소개", + example = "안녕하세요", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + String introduction) { + public static List of(List blackMembers, String domain) { + return blackMembers.stream() + .map( + member -> + new BlackMemberDetailResponse( + member.getId(), + member.getNickname(), + getProfileImageUrl(member, domain), + member.getIntroduction())) + .toList(); + } + + private static String getProfileImageUrl(Member member, String domain) { + if (member.getProfileImageUrl() == null) { + return null; + } + if (isDefaultImage(member)) { + return member.getProfileImageUrl(); + } + return domain + "/" + member.getProfileImageUrl(); + } + + private static boolean isDefaultImage(Member member) { + String url = member.getProfileImageUrl(); + return url.equals("1") || url.equals("2") || url.equals("3") || url.equals("4"); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberResponse.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberResponse.java new file mode 100644 index 00000000..cae6dc58 --- /dev/null +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberResponse.java @@ -0,0 +1,28 @@ +package com.depromeet.blacklist.dto.response; + +import com.depromeet.blacklist.domain.vo.BlacklistPage; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public record BlackMemberResponse( + @Schema(description = "차단한 유저 리스트", requiredMode = Schema.RequiredMode.REQUIRED) + List blackMembers, + @Schema( + description = "다음 페이지가 존재하는지 여부", + example = "true", + requiredMode = Schema.RequiredMode.REQUIRED) + boolean hasNext, + @Schema( + description = "다음 페이지 검색 커서 ID(hasNext가 false일 시 null)", + example = "11", + requiredMode = Schema.RequiredMode.NOT_REQUIRED) + Long cursorId) { + public static BlackMemberResponse of(BlacklistPage page, String domain) { + return new BlackMemberResponse( + BlackMemberDetailResponse.of(page.blackMembers(), domain), + page.hasNext(), + page.cursorId()); + } +} diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java index 711329df..e970e61a 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java @@ -1,11 +1,14 @@ package com.depromeet.blacklist.facade; +import com.depromeet.blacklist.domain.vo.BlacklistPage; import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.dto.response.BlackMemberResponse; import com.depromeet.blacklist.port.in.usecase.BlacklistCommandUseCase; import com.depromeet.blacklist.port.in.usecase.BlacklistQueryUseCase; import com.depromeet.exception.BadRequestException; import com.depromeet.type.blacklist.BlacklistErrorType; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,6 +19,9 @@ public class BlacklistFacade { private final BlacklistQueryUseCase blacklistQueryUseCase; private final BlacklistCommandUseCase blacklistCommandUseCase; + @Value("${cloud-front.domain}") + private String domain; + public void blackMember(Long memberId, BlackMemberRequest request) { Long blackMemberId = request.blackMemberId(); boolean isAlreadyBlacked = blacklistQueryUseCase.checkBlackMember(memberId, blackMemberId); @@ -29,4 +35,10 @@ public void blackMember(Long memberId, BlackMemberRequest request) { public void unblackMember(Long memberId, Long blackMemberId) { blacklistCommandUseCase.unblackMember(memberId, blackMemberId); } + + @Transactional(readOnly = true) + public BlackMemberResponse getBlackMembers(Long memberId, Long cursorId) { + BlacklistPage page = blacklistQueryUseCase.getBlackMembers(memberId, cursorId); + return BlackMemberResponse.of(page, domain); + } } From c547880b6977155bbb66221ea7284816210597cc Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 01:53:50 +0900 Subject: [PATCH 26/28] =?UTF-8?q?feat:=20=EC=B0=A8=EB=8B=A8=ED=95=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A1=B0=ED=9A=8C=20API=20Swagge?= =?UTF-8?q?r=20=EC=B6=94=EA=B0=80=20(#385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/blacklist/api/BlacklistApi.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java index 7c1c99f0..f22ed158 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/api/BlacklistApi.java @@ -1,6 +1,7 @@ package com.depromeet.blacklist.api; import com.depromeet.blacklist.dto.request.BlackMemberRequest; +import com.depromeet.blacklist.dto.response.BlackMemberResponse; import com.depromeet.dto.response.ApiResponse; import com.depromeet.member.annotation.LoginMember; import io.swagger.v3.oas.annotations.Operation; @@ -8,6 +9,7 @@ import jakarta.validation.Valid; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; @Tag(name = "차단(Blacklist)") public interface BlacklistApi { @@ -18,4 +20,9 @@ ApiResponse blackMember( @Operation(summary = "사용자 차단 해제") ApiResponse unblackMember( @LoginMember Long memberId, @PathVariable("blackMemberId") Long blackMemberId); + + @Operation(summary = "사용자 차단 목록 조회") + ApiResponse getBlackMembers( + @LoginMember Long memberId, + @RequestParam(value = "cursorId", required = false) Long cursorId); } From 2cf3012895efa8d688063ed1e51feac2f064a9d6 Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 02:01:01 +0900 Subject: [PATCH 27/28] =?UTF-8?q?refactor:=20=EC=B0=A8=EB=8B=A8=20API=20?= =?UTF-8?q?=EC=9E=90=EC=8B=A0=EC=9D=80=20=EC=B0=A8=EB=8B=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/depromeet/type/blacklist/BlacklistErrorType.java | 3 ++- .../java/com/depromeet/blacklist/facade/BlacklistFacade.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java index f659cea8..41ee3b99 100644 --- a/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java +++ b/module-independent/src/main/java/com/depromeet/type/blacklist/BlacklistErrorType.java @@ -3,7 +3,8 @@ import com.depromeet.type.ErrorType; public enum BlacklistErrorType implements ErrorType { - ALREADY_BLACKED("BLACK_1", "이미 차단한 사용자입니다"); + ALREADY_BLACKED("BLACK_1", "이미 차단한 사용자입니다"), + CANNOT_BLACK_MYSELF("BLACK_2", "자기 자신을 차단할 수 없습니다"); private final String code; private final String message; diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java index e970e61a..df74d671 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/facade/BlacklistFacade.java @@ -24,6 +24,10 @@ public class BlacklistFacade { public void blackMember(Long memberId, BlackMemberRequest request) { Long blackMemberId = request.blackMemberId(); + if (memberId.equals(blackMemberId)) { + throw new BadRequestException(BlacklistErrorType.CANNOT_BLACK_MYSELF); + } + boolean isAlreadyBlacked = blacklistQueryUseCase.checkBlackMember(memberId, blackMemberId); if (isAlreadyBlacked) { throw new BadRequestException(BlacklistErrorType.ALREADY_BLACKED); From 0677c3b05b03c0ca8b080ebe42868d605550dbe9 Mon Sep 17 00:00:00 2001 From: its-sky Date: Sat, 7 Sep 2024 02:04:50 +0900 Subject: [PATCH 28/28] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20URL?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=20(#385)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/BlackMemberDetailResponse.java | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java index e0b56db5..b0da3638 100644 --- a/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java +++ b/module-presentation/src/main/java/com/depromeet/blacklist/dto/response/BlackMemberDetailResponse.java @@ -34,23 +34,8 @@ public static List of(List blackMembers, Stri new BlackMemberDetailResponse( member.getId(), member.getNickname(), - getProfileImageUrl(member, domain), + member.getProfileImageUrl(domain), member.getIntroduction())) .toList(); } - - private static String getProfileImageUrl(Member member, String domain) { - if (member.getProfileImageUrl() == null) { - return null; - } - if (isDefaultImage(member)) { - return member.getProfileImageUrl(); - } - return domain + "/" + member.getProfileImageUrl(); - } - - private static boolean isDefaultImage(Member member) { - String url = member.getProfileImageUrl(); - return url.equals("1") || url.equals("2") || url.equals("3") || url.equals("4"); - } }