diff --git a/Api/src/main/java/allchive/server/api/block/controller/BlockController.java b/Api/src/main/java/allchive/server/api/block/controller/BlockController.java new file mode 100644 index 00000000..c444d3d6 --- /dev/null +++ b/Api/src/main/java/allchive/server/api/block/controller/BlockController.java @@ -0,0 +1,26 @@ +package allchive.server.api.block.controller; + + +import allchive.server.api.block.model.dto.request.BlockRequest; +import allchive.server.api.block.model.dto.response.BlockResponse; +import allchive.server.api.block.service.CreateBlockUseCase; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/blocks") +@RequiredArgsConstructor +@Slf4j +@Tag(name = "8. [block]") +public class BlockController { + private final CreateBlockUseCase createBlockUseCase; + + @Operation(summary = "유저를 차단합니다") + @PostMapping() + public BlockResponse createBlock(@RequestBody BlockRequest blockRequest) { + return createBlockUseCase.execute(blockRequest); + } +} diff --git a/Api/src/main/java/allchive/server/api/block/model/dto/request/BlockRequest.java b/Api/src/main/java/allchive/server/api/block/model/dto/request/BlockRequest.java new file mode 100644 index 00000000..f555cf73 --- /dev/null +++ b/Api/src/main/java/allchive/server/api/block/model/dto/request/BlockRequest.java @@ -0,0 +1,11 @@ +package allchive.server.api.block.model.dto.request; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +@Getter +public class BlockRequest { + @Schema(defaultValue = "1", description = "차단할 유저의 id") + private Long userId; +} diff --git a/Api/src/main/java/allchive/server/api/block/model/dto/response/BlockResponse.java b/Api/src/main/java/allchive/server/api/block/model/dto/response/BlockResponse.java new file mode 100644 index 00000000..00ccbacf --- /dev/null +++ b/Api/src/main/java/allchive/server/api/block/model/dto/response/BlockResponse.java @@ -0,0 +1,21 @@ +package allchive.server.api.block.model.dto.response; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class BlockResponse { + @Schema(defaultValue = "이름", description = "차단한 유저의 닉네임") + private String nickname; + + @Builder + private BlockResponse(String nickname) { + this.nickname = nickname; + } + + public static BlockResponse from(String nickname) { + return BlockResponse.builder().nickname(nickname).build(); + } +} diff --git a/Api/src/main/java/allchive/server/api/block/model/mapper/BlockMapper.java b/Api/src/main/java/allchive/server/api/block/model/mapper/BlockMapper.java new file mode 100644 index 00000000..fc070b91 --- /dev/null +++ b/Api/src/main/java/allchive/server/api/block/model/mapper/BlockMapper.java @@ -0,0 +1,12 @@ +package allchive.server.api.block.model.mapper; + + +import allchive.server.core.annotation.Mapper; +import allchive.server.domain.domains.block.domain.Block; + +@Mapper +public class BlockMapper { + public Block toEntity(Long blockFrom, Long blockUser) { + return Block.of(blockFrom, blockUser); + } +} diff --git a/Api/src/main/java/allchive/server/api/block/service/CreateBlockUseCase.java b/Api/src/main/java/allchive/server/api/block/service/CreateBlockUseCase.java new file mode 100644 index 00000000..f66bdbaa --- /dev/null +++ b/Api/src/main/java/allchive/server/api/block/service/CreateBlockUseCase.java @@ -0,0 +1,33 @@ +package allchive.server.api.block.service; + + +import allchive.server.api.block.model.dto.request.BlockRequest; +import allchive.server.api.block.model.dto.response.BlockResponse; +import allchive.server.api.block.model.mapper.BlockMapper; +import allchive.server.api.config.security.SecurityUtil; +import allchive.server.core.annotation.UseCase; +import allchive.server.domain.domains.block.domain.Block; +import allchive.server.domain.domains.block.service.BlockDomainService; +import allchive.server.domain.domains.block.validator.BlockValidator; +import allchive.server.domain.domains.user.adaptor.UserAdaptor; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@UseCase +@RequiredArgsConstructor +public class CreateBlockUseCase { + private final BlockValidator blockValidator; + private final BlockMapper blockMapper; + private final BlockDomainService blockDomainService; + private final UserAdaptor userAdaptor; + + @Transactional + public BlockResponse execute(BlockRequest request) { + Long userId = SecurityUtil.getCurrentUserId(); + blockValidator.validateNotDuplicate(userId, request.getUserId()); + blockValidator.validateNotMyself(userId, request.getUserId()); + Block block = blockMapper.toEntity(userId, request.getUserId()); + blockDomainService.save(block); + return BlockResponse.from(userAdaptor.queryUserById(request.getUserId()).getNickname()); + } +} diff --git a/Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java b/Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java index 12a83292..3cc73d79 100644 --- a/Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java +++ b/Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java @@ -11,20 +11,22 @@ public class ReportMapper { public Report toEntity(CreateReportRequest request, ReportObjectType type, Long userId) { Report report = null; switch (type) { - case CONTENT -> report = Report.of( - type, - request.getReason(), - request.getReportedType(), - request.getId(), - null, - userId); - case ARCHIVING -> report = Report.of( - type, - request.getReason(), - request.getReportedType(), - null, - request.getId(), - userId); + case CONTENT -> report = + Report.of( + type, + request.getReason(), + request.getReportedType(), + request.getId(), + null, + userId); + case ARCHIVING -> report = + Report.of( + type, + request.getReason(), + request.getReportedType(), + null, + request.getId(), + userId); } return report; } diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/adaptor/BlockAdaptor.java b/Domain/src/main/java/allchive/server/domain/domains/block/adaptor/BlockAdaptor.java index 5a9dd6f4..b6268370 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/block/adaptor/BlockAdaptor.java +++ b/Domain/src/main/java/allchive/server/domain/domains/block/adaptor/BlockAdaptor.java @@ -15,4 +15,12 @@ public class BlockAdaptor { public List findByBlockFrom(Long userId) { return blockRepository.findAllByBlockFrom(userId); } + + public boolean queryBlockExistByBlockFromAndBlockUser(Long blockFrom, Long blockUser) { + return blockRepository.queryBlockExistByBlockFromAndBlockUser(blockFrom, blockUser); + } + + public void save(Block block) { + blockRepository.save(block); + } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/domain/Block.java b/Domain/src/main/java/allchive/server/domain/domains/block/domain/Block.java index 6eef9cad..dcc4e2bf 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/block/domain/Block.java +++ b/Domain/src/main/java/allchive/server/domain/domains/block/domain/Block.java @@ -5,6 +5,7 @@ import javax.persistence.*; import javax.validation.constraints.NotNull; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -22,4 +23,14 @@ public class Block extends BaseTimeEntity { // Block 당한 유저 private Long blockUser; + + @Builder + private Block(Long blockFrom, Long blockUser) { + this.blockFrom = blockFrom; + this.blockUser = blockUser; + } + + public static Block of(Long blockFrom, Long blockUser) { + return Block.builder().blockFrom(blockFrom).blockUser(blockUser).build(); + } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/exception/BlockErrorCode.java b/Domain/src/main/java/allchive/server/domain/domains/block/exception/BlockErrorCode.java index 248eb69e..dfb4bccd 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/block/exception/BlockErrorCode.java +++ b/Domain/src/main/java/allchive/server/domain/domains/block/exception/BlockErrorCode.java @@ -1,22 +1,24 @@ package allchive.server.domain.domains.block.exception; +import static allchive.server.core.consts.AllchiveConst.BAD_REQUEST; import allchive.server.core.dto.ErrorReason; import allchive.server.core.error.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import org.springframework.http.HttpStatus; @Getter @AllArgsConstructor public enum BlockErrorCode implements BaseErrorCode { + DUPLICATED_BLOCK(BAD_REQUEST, "BLOCK_400_1", "이미 차단한 유저입니다."), + CANNOT_BLOCK_MYSELF(BAD_REQUEST, "BLOCK_400_2", "본인을 차단할 수 없습니다."), ; - private HttpStatus status; + private int status; private String code; private String reason; @Override public ErrorReason getErrorReason() { - return ErrorReason.of(status.value(), code, reason); + return ErrorReason.of(status, code, reason); } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/CannotBlockMyselfException.java b/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/CannotBlockMyselfException.java new file mode 100644 index 00000000..aa3c8fec --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/CannotBlockMyselfException.java @@ -0,0 +1,14 @@ +package allchive.server.domain.domains.block.exception.exceptions; + + +import allchive.server.core.error.BaseErrorException; +import allchive.server.domain.domains.block.exception.BlockErrorCode; + +public class CannotBlockMyselfException extends BaseErrorException { + + public static final BaseErrorException EXCEPTION = new CannotBlockMyselfException(); + + private CannotBlockMyselfException() { + super(BlockErrorCode.CANNOT_BLOCK_MYSELF); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/DuplicatedBlockException.java b/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/DuplicatedBlockException.java new file mode 100644 index 00000000..b1772083 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/block/exception/exceptions/DuplicatedBlockException.java @@ -0,0 +1,14 @@ +package allchive.server.domain.domains.block.exception.exceptions; + + +import allchive.server.core.error.BaseErrorException; +import allchive.server.domain.domains.block.exception.BlockErrorCode; + +public class DuplicatedBlockException extends BaseErrorException { + + public static final BaseErrorException EXCEPTION = new DuplicatedBlockException(); + + private DuplicatedBlockException() { + super(BlockErrorCode.DUPLICATED_BLOCK); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepository.java b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepository.java new file mode 100644 index 00000000..ae169ca0 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepository.java @@ -0,0 +1,5 @@ +package allchive.server.domain.domains.block.repository; + +public interface BlockCustomRepository { + boolean queryBlockExistByBlockFromAndBlockUser(Long blockFrom, Long blockUser); +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepositoryImpl.java b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepositoryImpl.java new file mode 100644 index 00000000..f172ef31 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockCustomRepositoryImpl.java @@ -0,0 +1,31 @@ +package allchive.server.domain.domains.block.repository; + +import static allchive.server.domain.domains.block.domain.QBlock.block; + +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class BlockCustomRepositoryImpl implements BlockCustomRepository { + private final JPAQueryFactory queryFactory; + + @Override + public boolean queryBlockExistByBlockFromAndBlockUser(Long blockFrom, Long blockUser) { + Integer fetchOne = + queryFactory + .selectOne() + .from(block) + .where(blockFromEq(blockFrom), blockUserEq(blockUser)) + .fetchFirst(); // limit 1 + return fetchOne != null; + } + + private BooleanExpression blockFromEq(Long blockFrom) { + return block.blockFrom.eq(blockFrom); + } + + private BooleanExpression blockUserEq(Long blockUser) { + return block.blockUser.eq(blockUser); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockRepository.java b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockRepository.java index f3107795..43a855f7 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockRepository.java +++ b/Domain/src/main/java/allchive/server/domain/domains/block/repository/BlockRepository.java @@ -5,6 +5,6 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -public interface BlockRepository extends JpaRepository { +public interface BlockRepository extends JpaRepository, BlockCustomRepository { List findAllByBlockFrom(Long userId); } diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockDomainService.java b/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockDomainService.java new file mode 100644 index 00000000..e9938577 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockDomainService.java @@ -0,0 +1,17 @@ +package allchive.server.domain.domains.block.service; + + +import allchive.server.core.annotation.DomainService; +import allchive.server.domain.domains.block.adaptor.BlockAdaptor; +import allchive.server.domain.domains.block.domain.Block; +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class BlockDomainService { + private final BlockAdaptor blockAdaptor; + + public void save(Block block) { + blockAdaptor.save(block); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockService.java b/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockService.java deleted file mode 100644 index c2072c33..00000000 --- a/Domain/src/main/java/allchive/server/domain/domains/block/service/BlockService.java +++ /dev/null @@ -1,7 +0,0 @@ -package allchive.server.domain.domains.block.service; - - -import allchive.server.core.annotation.DomainService; - -@DomainService -public class BlockService {} diff --git a/Domain/src/main/java/allchive/server/domain/domains/block/validator/BlockValidator.java b/Domain/src/main/java/allchive/server/domain/domains/block/validator/BlockValidator.java index 31763f39..e9d78138 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/block/validator/BlockValidator.java +++ b/Domain/src/main/java/allchive/server/domain/domains/block/validator/BlockValidator.java @@ -2,6 +2,25 @@ import allchive.server.core.annotation.Validator; +import allchive.server.domain.domains.block.adaptor.BlockAdaptor; +import allchive.server.domain.domains.block.exception.exceptions.CannotBlockMyselfException; +import allchive.server.domain.domains.block.exception.exceptions.DuplicatedBlockException; +import lombok.RequiredArgsConstructor; @Validator -public class BlockValidator {} +@RequiredArgsConstructor +public class BlockValidator { + private final BlockAdaptor blockAdaptor; + + public void validateNotDuplicate(Long blockFrom, Long blockUser) { + if (blockAdaptor.queryBlockExistByBlockFromAndBlockUser(blockFrom, blockUser)) { + throw DuplicatedBlockException.EXCEPTION; + } + } + + public void validateNotMyself(Long blockFrom, Long blockUser) { + if (blockFrom.equals(blockUser)) { + throw CannotBlockMyselfException.EXCEPTION; + } + } +}