From ba9c33fd3cd2bc4172044fd8f757f3c5b1f479c4 Mon Sep 17 00:00:00 2001 From: wjdtkdgns Date: Sun, 16 Jul 2023 19:55:30 +0900 Subject: [PATCH] =?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#37?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/UpdateArchivingPinUseCase.java | 2 +- .../service/UpdateArchivingScrapUseCase.java | 2 +- .../content/service/CreateContentUseCase.java | 2 +- .../report/controller/ReportController.java | 28 +++++++++++ .../dto/request/CreateReportRequest.java | 20 ++++++++ .../api/report/model/mapper/ReportMapper.java | 31 +++++++++++++ .../report/service/CreateReportUseCase.java | 37 +++++++++++++++ .../archiving/adaptor/ArchivingAdaptor.java | 2 +- .../repository/ArchivingCustomRepository.java | 2 +- .../ArchivingCustomRepositoryImpl.java | 2 +- .../validator/ArchivingValidator.java | 2 +- .../content/adaptor/ContentAdaptor.java | 4 ++ .../repository/ContentCustomRepository.java | 2 + .../ContentCustomRepositoryImpl.java | 11 +++++ .../content/validator/ContentValidator.java | 6 +++ .../domains/report/adaptor/ReportAdaptor.java | 18 +++++++- .../domain/domains/report/domain/Report.java | 40 ++++++++++++++-- ...{ReportType.java => ReportObjectType.java} | 2 +- .../report/domain/enums/ReportedType.java | 10 +++- .../report/exception/ReportErrorCode.java | 8 ++-- .../exceptions/DuplicatedReportArchiving.java | 14 ++++++ .../exceptions/DuplicatedReportContent.java | 14 ++++++ .../repository/ReportCustomRepository.java | 7 +++ .../ReportCustomRepositoryImpl.java | 46 +++++++++++++++++++ .../report/repository/ReportRepository.java | 2 +- .../report/service/ReportDomainService.java | 10 +++- .../report/validator/ReportValidator.java | 26 ++++++++++- 27 files changed, 330 insertions(+), 20 deletions(-) create mode 100644 Api/src/main/java/allchive/server/api/report/controller/ReportController.java create mode 100644 Api/src/main/java/allchive/server/api/report/model/dto/request/CreateReportRequest.java create mode 100644 Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java create mode 100644 Api/src/main/java/allchive/server/api/report/service/CreateReportUseCase.java rename Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/{ReportType.java => ReportObjectType.java} (95%) create mode 100644 Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportArchiving.java create mode 100644 Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportContent.java create mode 100644 Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepository.java create mode 100644 Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepositoryImpl.java diff --git a/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingPinUseCase.java b/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingPinUseCase.java index 0ae77af9..a85f5d9e 100644 --- a/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingPinUseCase.java +++ b/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingPinUseCase.java @@ -17,7 +17,7 @@ public class UpdateArchivingPinUseCase { @Transactional public void execute(Long archivingId, Boolean cancel) { Long userId = SecurityUtil.getCurrentUserId(); - archivingValidator.validateExistArchiving(archivingId); + archivingValidator.validateExistById(archivingId); archivingValidator.validateDeleteStatus(archivingId, userId); if (cancel) { archivingValidator.validateNotPinStatus(archivingId, userId); diff --git a/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingScrapUseCase.java b/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingScrapUseCase.java index 4ac4c2ef..5e8bcd0d 100644 --- a/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingScrapUseCase.java +++ b/Api/src/main/java/allchive/server/api/archiving/service/UpdateArchivingScrapUseCase.java @@ -24,7 +24,7 @@ public class UpdateArchivingScrapUseCase { @Transactional public void execute(Long archivingId, Boolean cancel) { - archivingValidator.validateExistArchiving(archivingId); + archivingValidator.validateExistById(archivingId); Long userId = SecurityUtil.getCurrentUserId(); archivingValidator.validateDeleteStatus(archivingId, userId); User user = userAdaptor.queryUserById(userId); diff --git a/Api/src/main/java/allchive/server/api/content/service/CreateContentUseCase.java b/Api/src/main/java/allchive/server/api/content/service/CreateContentUseCase.java index 1b758454..975c66ff 100644 --- a/Api/src/main/java/allchive/server/api/content/service/CreateContentUseCase.java +++ b/Api/src/main/java/allchive/server/api/content/service/CreateContentUseCase.java @@ -29,7 +29,7 @@ public class CreateContentUseCase { @Transactional public void execute(CreateContentRequest request) { - archivingValidator.validateExistArchiving(request.getArchivingId()); + archivingValidator.validateExistById(request.getArchivingId()); Long userId = SecurityUtil.getCurrentUserId(); archivingValidator.validateArchivingUser(request.getArchivingId(), userId); tagValidator.validateExistTagsAndUser(request.getTagIds(), userId); diff --git a/Api/src/main/java/allchive/server/api/report/controller/ReportController.java b/Api/src/main/java/allchive/server/api/report/controller/ReportController.java new file mode 100644 index 00000000..ac3c0266 --- /dev/null +++ b/Api/src/main/java/allchive/server/api/report/controller/ReportController.java @@ -0,0 +1,28 @@ +package allchive.server.api.report.controller; + + +import allchive.server.api.report.model.dto.request.CreateReportRequest; +import allchive.server.api.report.service.CreateReportUseCase; +import allchive.server.domain.domains.report.domain.enums.ReportObjectType; +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("/reports") +@RequiredArgsConstructor +@Slf4j +@Tag(name = "7. [report]") +public class ReportController { + private final CreateReportUseCase createReportUseCase; + + @Operation(summary = "아카이빙, 컨텐츠를 신고합니다.") + @PostMapping() + public void createReport( + @RequestParam("type") ReportObjectType type, + @RequestBody CreateReportRequest createReportRequest) { + createReportUseCase.execute(createReportRequest, type); + } +} diff --git a/Api/src/main/java/allchive/server/api/report/model/dto/request/CreateReportRequest.java b/Api/src/main/java/allchive/server/api/report/model/dto/request/CreateReportRequest.java new file mode 100644 index 00000000..de3d048f --- /dev/null +++ b/Api/src/main/java/allchive/server/api/report/model/dto/request/CreateReportRequest.java @@ -0,0 +1,20 @@ +package allchive.server.api.report.model.dto.request; + + +import allchive.server.core.annotation.ValidEnum; +import allchive.server.domain.domains.report.domain.enums.ReportedType; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +@Getter +public class CreateReportRequest { + @Schema(defaultValue = "기타기타기타기타기타", description = "사유 ('기타'에만 해당)") + private String reason; + + @Schema(defaultValue = "spam", description = "신고 종류") + @ValidEnum(target = ReportedType.class) + private ReportedType reportedType; + + @Schema(defaultValue = "1", description = "아카이빙, 컨텐츠 고유번호") + private Long id; +} 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 new file mode 100644 index 00000000..12a83292 --- /dev/null +++ b/Api/src/main/java/allchive/server/api/report/model/mapper/ReportMapper.java @@ -0,0 +1,31 @@ +package allchive.server.api.report.model.mapper; + + +import allchive.server.api.report.model.dto.request.CreateReportRequest; +import allchive.server.core.annotation.Mapper; +import allchive.server.domain.domains.report.domain.Report; +import allchive.server.domain.domains.report.domain.enums.ReportObjectType; + +@Mapper +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); + } + return report; + } +} diff --git a/Api/src/main/java/allchive/server/api/report/service/CreateReportUseCase.java b/Api/src/main/java/allchive/server/api/report/service/CreateReportUseCase.java new file mode 100644 index 00000000..1f58aa1a --- /dev/null +++ b/Api/src/main/java/allchive/server/api/report/service/CreateReportUseCase.java @@ -0,0 +1,37 @@ +package allchive.server.api.report.service; + + +import allchive.server.api.config.security.SecurityUtil; +import allchive.server.api.report.model.dto.request.CreateReportRequest; +import allchive.server.api.report.model.mapper.ReportMapper; +import allchive.server.core.annotation.UseCase; +import allchive.server.domain.domains.archiving.validator.ArchivingValidator; +import allchive.server.domain.domains.content.validator.ContentValidator; +import allchive.server.domain.domains.report.domain.Report; +import allchive.server.domain.domains.report.domain.enums.ReportObjectType; +import allchive.server.domain.domains.report.service.ReportDomainService; +import allchive.server.domain.domains.report.validator.ReportValidator; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@UseCase +@RequiredArgsConstructor +public class CreateReportUseCase { + private final ReportValidator reportValidator; + private final ContentValidator contentValidator; + private final ArchivingValidator archivingValidator; + private final ReportMapper reportMapper; + private final ReportDomainService reportDomainService; + + @Transactional + public void execute(CreateReportRequest request, ReportObjectType type) { + Long userId = SecurityUtil.getCurrentUserId(); + reportValidator.validateNotDuplicateReport(userId, request.getId(), type); + switch (type) { + case CONTENT -> contentValidator.validateExistById(request.getId()); + case ARCHIVING -> archivingValidator.validateExistById(request.getId()); + } + Report report = reportMapper.toEntity(request, type, userId); + reportDomainService.save(report); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/archiving/adaptor/ArchivingAdaptor.java b/Domain/src/main/java/allchive/server/domain/domains/archiving/adaptor/ArchivingAdaptor.java index c89f22f3..c892093d 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/archiving/adaptor/ArchivingAdaptor.java +++ b/Domain/src/main/java/allchive/server/domain/domains/archiving/adaptor/ArchivingAdaptor.java @@ -58,7 +58,7 @@ public List queryArchivingByUserId(Long userId) { } public boolean queryArchivingExist(Long archivingId) { - return archivingRepository.queryArchivingExist(archivingId); + return archivingRepository.queryArchivingExistById(archivingId); } public List findAllByUserId(Long userId) { diff --git a/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepository.java b/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepository.java index c0f61b24..0385366e 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepository.java +++ b/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepository.java @@ -18,5 +18,5 @@ Slice querySliceArchivingIn( List queryArchivingByUserId(Long userId); - boolean queryArchivingExist(Long archivingId); + boolean queryArchivingExistById(Long archivingId); } diff --git a/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepositoryImpl.java b/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepositoryImpl.java index 6c346be7..b7d8ed8f 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepositoryImpl.java +++ b/Domain/src/main/java/allchive/server/domain/domains/archiving/repository/ArchivingCustomRepositoryImpl.java @@ -86,7 +86,7 @@ public List queryArchivingByUserId(Long userId) { } @Override - public boolean queryArchivingExist(Long archivingId) { + public boolean queryArchivingExistById(Long archivingId) { Archiving fetchOne = queryFactory.selectFrom(archiving).where(archivingIdEq(archivingId)).fetchFirst(); return fetchOne != null; diff --git a/Domain/src/main/java/allchive/server/domain/domains/archiving/validator/ArchivingValidator.java b/Domain/src/main/java/allchive/server/domain/domains/archiving/validator/ArchivingValidator.java index cc89741d..0dd6ec08 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/archiving/validator/ArchivingValidator.java +++ b/Domain/src/main/java/allchive/server/domain/domains/archiving/validator/ArchivingValidator.java @@ -28,7 +28,7 @@ public void validateDeleteStatus(Long archivingId, Long userId) { archivingAdaptor.findById(archivingId).validateDeleteStatus(userId); } - public void validateExistArchiving(Long archivingId) { + public void validateExistById(Long archivingId) { if (!archivingAdaptor.queryArchivingExist(archivingId)) { throw ArchivingNotFoundException.EXCEPTION; } diff --git a/Domain/src/main/java/allchive/server/domain/domains/content/adaptor/ContentAdaptor.java b/Domain/src/main/java/allchive/server/domain/domains/content/adaptor/ContentAdaptor.java index 0972bd8f..7d789bed 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/content/adaptor/ContentAdaptor.java +++ b/Domain/src/main/java/allchive/server/domain/domains/content/adaptor/ContentAdaptor.java @@ -48,4 +48,8 @@ public void deleteAllById(List contentIds) { public List findAllByArchivingIds(List archivingIds) { return contentRepository.queryContentInArchivingIds(archivingIds); } + + public boolean queryContentExistById(Long contentId) { + return contentRepository.queryContentExistById(contentId); + } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepository.java b/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepository.java index 1f822736..34e2fc7a 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepository.java +++ b/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepository.java @@ -10,4 +10,6 @@ public interface ContentCustomRepository { Slice querySliceContentByArchivingId(Long archivingId, Pageable pageable); List queryContentInArchivingIds(List archivingIds); + + boolean queryContentExistById(Long id); } diff --git a/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepositoryImpl.java b/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepositoryImpl.java index 0c3838f3..91ffbc07 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepositoryImpl.java +++ b/Domain/src/main/java/allchive/server/domain/domains/content/repository/ContentCustomRepositoryImpl.java @@ -39,6 +39,13 @@ public List queryContentInArchivingIds(List archivingIds) { .fetch(); } + @Override + public boolean queryContentExistById(Long id) { + Integer fetchOne = + queryFactory.selectOne().from(content).where(idEq(id)).fetchFirst(); // limit 1 + return fetchOne != null; + } + private BooleanExpression archivingIdEq(Long archivingId) { return content.archivingId.eq(archivingId); } @@ -47,6 +54,10 @@ private BooleanExpression archivingIdIn(List archivingIds) { return content.archivingId.in(archivingIds); } + private BooleanExpression idEq(Long id) { + return content.id.eq(id); + } + private OrderSpecifier createdAtDesc() { return content.createdAt.desc(); } diff --git a/Domain/src/main/java/allchive/server/domain/domains/content/validator/ContentValidator.java b/Domain/src/main/java/allchive/server/domain/domains/content/validator/ContentValidator.java index bfe16ad3..f14abc84 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/content/validator/ContentValidator.java +++ b/Domain/src/main/java/allchive/server/domain/domains/content/validator/ContentValidator.java @@ -30,4 +30,10 @@ public void verifyUserInIdList(Long userId, List contentIds) { .toList(); archivingValidator.verifyUserInIdList(userId, archivingIds); } + + public void validateExistById(Long contentId) { + if (!contentAdaptor.queryContentExistById(contentId)) { + throw ContentNotFoundException.EXCEPTION; + } + } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/adaptor/ReportAdaptor.java b/Domain/src/main/java/allchive/server/domain/domains/report/adaptor/ReportAdaptor.java index 14ad8dca..95c1d405 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/adaptor/ReportAdaptor.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/adaptor/ReportAdaptor.java @@ -2,8 +2,24 @@ import allchive.server.core.annotation.Adaptor; +import allchive.server.domain.domains.report.domain.Report; +import allchive.server.domain.domains.report.repository.ReportRepository; import lombok.RequiredArgsConstructor; @Adaptor @RequiredArgsConstructor -public class ReportAdaptor {} +public class ReportAdaptor { + private final ReportRepository reportRepository; + + public void save(Report report) { + reportRepository.save(report); + } + + public Boolean queryReportExistByUserIdAndContentId(Long userId, Long contentId) { + return reportRepository.queryReportExistByUserIdAndContentId(userId, contentId); + } + + public Boolean queryReportExistByUserIdAndArchivingId(Long userId, Long archivingId) { + return reportRepository.queryReportExistByUserIdAndArchivingId(userId, archivingId); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/domain/Report.java b/Domain/src/main/java/allchive/server/domain/domains/report/domain/Report.java index 97dc956d..693b4dc7 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/domain/Report.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/domain/Report.java @@ -2,10 +2,11 @@ import allchive.server.domain.common.model.BaseTimeEntity; -import allchive.server.domain.domains.report.domain.enums.ReportType; +import allchive.server.domain.domains.report.domain.enums.ReportObjectType; import allchive.server.domain.domains.report.domain.enums.ReportedType; import javax.persistence.*; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,7 +20,7 @@ public class Report extends BaseTimeEntity { private Long id; @Enumerated(EnumType.STRING) - private ReportType reportType; + private ReportObjectType reportObjectTypeType; private String reason; @@ -28,5 +29,38 @@ public class Report extends BaseTimeEntity { private Long contentId; private Long archivingId; - private Long userId; + private Long userId; // 신고한 유저 + + @Builder + private Report( + ReportObjectType reportObjectTypeType, + String reason, + ReportedType reportedType, + Long contentId, + Long archivingId, + Long userId) { + this.reportObjectTypeType = reportObjectTypeType; + this.reason = reason; + this.reportedType = reportedType; + this.contentId = contentId; + this.archivingId = archivingId; + this.userId = userId; + } + + public static Report of( + ReportObjectType reportObjectTypeType, + String reason, + ReportedType reportedType, + Long contentId, + Long archivingId, + Long userId) { + return Report.builder() + .reportObjectTypeType(reportObjectTypeType) + .reason(reason) + .reportedType(reportedType) + .contentId(contentId) + .archivingId(archivingId) + .userId(userId) + .build(); + } } diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportType.java b/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportObjectType.java similarity index 95% rename from Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportType.java rename to Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportObjectType.java index d57c5d1f..5c90c3c7 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportType.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportObjectType.java @@ -10,7 +10,7 @@ @Getter @AllArgsConstructor -public enum ReportType { +public enum ReportObjectType { CONTENT("content"), ARCHIVING("archiving"); diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportedType.java b/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportedType.java index bdc610d5..ad0f8cc4 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportedType.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/domain/enums/ReportedType.java @@ -11,8 +11,14 @@ @Getter @AllArgsConstructor public enum ReportedType { - CONTENT("content"), - ARCHIVING("archiving"); + SPAM("spam"), // 스팸이에요 + OBSCENE("obscene"), // 음란성 컨텐츠를 담고있어요 + PERSONAL_INFO("personalInfo"), // 개인정보를 노출하고 있어요 + INTELLECTUAL_PROPERTY("intellectualProperty"), // 지식재산권을 침해해요 + VIOLENCE("violence"), // 혐오/폭력 컨텐츠를 담고 있어요 + ILLEGAL_INFO("illegalInformation"), // 불법 정보를 포함하고 있어요 + FRAUD("fraud"), // 사기 또는 피싱성 링크를 포함하고 있어요 + ETC("etc"); // 기타 @JsonValue private String value; diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/exception/ReportErrorCode.java b/Domain/src/main/java/allchive/server/domain/domains/report/exception/ReportErrorCode.java index 711696c3..d3d14c9b 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/exception/ReportErrorCode.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/exception/ReportErrorCode.java @@ -1,22 +1,24 @@ package allchive.server.domain.domains.report.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 ReportErrorCode implements BaseErrorCode { + DUPLICATED_REPORT_CONTENT(BAD_REQUEST, "REPORT_400_1", "이미 신고한 컨텐츠입니다."), + DUPLICATED_REPORT_ARCHIVING(BAD_REQUEST, "REPORT_400_1", "이미 신고한 아카이빙입니다."), ; - 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/report/exception/exceptions/DuplicatedReportArchiving.java b/Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportArchiving.java new file mode 100644 index 00000000..e66332e9 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportArchiving.java @@ -0,0 +1,14 @@ +package allchive.server.domain.domains.report.exception.exceptions; + + +import allchive.server.core.error.BaseErrorException; +import allchive.server.domain.domains.report.exception.ReportErrorCode; + +public class DuplicatedReportArchiving extends BaseErrorException { + + public static final BaseErrorException EXCEPTION = new DuplicatedReportArchiving(); + + private DuplicatedReportArchiving() { + super(ReportErrorCode.DUPLICATED_REPORT_ARCHIVING); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportContent.java b/Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportContent.java new file mode 100644 index 00000000..df245952 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/report/exception/exceptions/DuplicatedReportContent.java @@ -0,0 +1,14 @@ +package allchive.server.domain.domains.report.exception.exceptions; + + +import allchive.server.core.error.BaseErrorException; +import allchive.server.domain.domains.report.exception.ReportErrorCode; + +public class DuplicatedReportContent extends BaseErrorException { + + public static final BaseErrorException EXCEPTION = new DuplicatedReportContent(); + + private DuplicatedReportContent() { + super(ReportErrorCode.DUPLICATED_REPORT_CONTENT); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepository.java b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepository.java new file mode 100644 index 00000000..8c7a1f08 --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepository.java @@ -0,0 +1,7 @@ +package allchive.server.domain.domains.report.repository; + +public interface ReportCustomRepository { + Boolean queryReportExistByUserIdAndContentId(Long userId, Long contentId); + + Boolean queryReportExistByUserIdAndArchivingId(Long userId, Long archivingId); +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepositoryImpl.java b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepositoryImpl.java new file mode 100644 index 00000000..d1ea0a1c --- /dev/null +++ b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportCustomRepositoryImpl.java @@ -0,0 +1,46 @@ +package allchive.server.domain.domains.report.repository; + +import static allchive.server.domain.domains.report.domain.QReport.report; + +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ReportCustomRepositoryImpl implements ReportCustomRepository { + private final JPAQueryFactory queryFactory; + + @Override + public Boolean queryReportExistByUserIdAndContentId(Long userId, Long contentId) { + Integer fetchOne = + queryFactory + .selectOne() + .from(report) + .where(userIdEq(userId), contentIdEq(contentId)) + .fetchFirst(); // limit 1 + return fetchOne != null; + } + + @Override + public Boolean queryReportExistByUserIdAndArchivingId(Long userId, Long archivingId) { + Integer fetchOne = + queryFactory + .selectOne() + .from(report) + .where(userIdEq(userId), archivingIdEq(archivingId)) + .fetchFirst(); // limit 1 + return fetchOne != null; + } + + private BooleanExpression userIdEq(Long userId) { + return report.userId.eq(userId); + } + + private BooleanExpression contentIdEq(Long contentId) { + return report.contentId.eq(contentId); + } + + private BooleanExpression archivingIdEq(Long archivingId) { + return report.archivingId.eq(archivingId); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportRepository.java b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportRepository.java index 7b6f4638..c1bf33b6 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportRepository.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/repository/ReportRepository.java @@ -4,4 +4,4 @@ import allchive.server.domain.domains.report.domain.Report; import org.springframework.data.jpa.repository.JpaRepository; -public interface ReportRepository extends JpaRepository {} +public interface ReportRepository extends JpaRepository, ReportCustomRepository {} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/service/ReportDomainService.java b/Domain/src/main/java/allchive/server/domain/domains/report/service/ReportDomainService.java index 710f96e7..6e24e2d6 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/service/ReportDomainService.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/service/ReportDomainService.java @@ -2,8 +2,16 @@ import allchive.server.core.annotation.DomainService; +import allchive.server.domain.domains.report.adaptor.ReportAdaptor; +import allchive.server.domain.domains.report.domain.Report; import lombok.RequiredArgsConstructor; @DomainService @RequiredArgsConstructor -public class ReportDomainService {} +public class ReportDomainService { + private final ReportAdaptor reportAdaptor; + + public void save(Report report) { + reportAdaptor.save(report); + } +} diff --git a/Domain/src/main/java/allchive/server/domain/domains/report/validator/ReportValidator.java b/Domain/src/main/java/allchive/server/domain/domains/report/validator/ReportValidator.java index 1f82f50b..676eae89 100644 --- a/Domain/src/main/java/allchive/server/domain/domains/report/validator/ReportValidator.java +++ b/Domain/src/main/java/allchive/server/domain/domains/report/validator/ReportValidator.java @@ -2,6 +2,30 @@ import allchive.server.core.annotation.Validator; +import allchive.server.domain.domains.report.adaptor.ReportAdaptor; +import allchive.server.domain.domains.report.domain.enums.ReportObjectType; +import allchive.server.domain.domains.report.exception.exceptions.DuplicatedReportArchiving; +import allchive.server.domain.domains.report.exception.exceptions.DuplicatedReportContent; +import lombok.RequiredArgsConstructor; @Validator -public class ReportValidator {} +@RequiredArgsConstructor +public class ReportValidator { + private final ReportAdaptor reportAdaptor; + + public void validateNotDuplicateReport(Long userId, Long objectId, ReportObjectType type) { + Boolean duplicateStatus = Boolean.FALSE; + switch (type) { + case CONTENT -> duplicateStatus = + reportAdaptor.queryReportExistByUserIdAndContentId(userId, objectId); + case ARCHIVING -> duplicateStatus = + reportAdaptor.queryReportExistByUserIdAndArchivingId(userId, objectId); + } + if (duplicateStatus) { + switch (type) { + case CONTENT -> throw DuplicatedReportContent.EXCEPTION; + case ARCHIVING -> throw DuplicatedReportArchiving.EXCEPTION; + } + } + } +}