Skip to content

Commit

Permalink
[feat] 신고 기능 구현 #37
Browse files Browse the repository at this point in the history
  • Loading branch information
wjdtkdgns committed Jul 16, 2023
1 parent 8df2a7b commit ba9c33f
Show file tree
Hide file tree
Showing 27 changed files with 330 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public List<Archiving> queryArchivingByUserId(Long userId) {
}

public boolean queryArchivingExist(Long archivingId) {
return archivingRepository.queryArchivingExist(archivingId);
return archivingRepository.queryArchivingExistById(archivingId);
}

public List<Archiving> findAllByUserId(Long userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ Slice<Archiving> querySliceArchivingIn(

List<Archiving> queryArchivingByUserId(Long userId);

boolean queryArchivingExist(Long archivingId);
boolean queryArchivingExistById(Long archivingId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public List<Archiving> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ public void deleteAllById(List<Long> contentIds) {
public List<Content> findAllByArchivingIds(List<Long> archivingIds) {
return contentRepository.queryContentInArchivingIds(archivingIds);
}

public boolean queryContentExistById(Long contentId) {
return contentRepository.queryContentExistById(contentId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public interface ContentCustomRepository {
Slice<Content> querySliceContentByArchivingId(Long archivingId, Pageable pageable);

List<Content> queryContentInArchivingIds(List<Long> archivingIds);

boolean queryContentExistById(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ public List<Content> queryContentInArchivingIds(List<Long> 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);
}
Expand All @@ -47,6 +54,10 @@ private BooleanExpression archivingIdIn(List<Long> archivingIds) {
return content.archivingId.in(archivingIds);
}

private BooleanExpression idEq(Long id) {
return content.id.eq(id);
}

private OrderSpecifier<LocalDateTime> createdAtDesc() {
return content.createdAt.desc();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ public void verifyUserInIdList(Long userId, List<Long> contentIds) {
.toList();
archivingValidator.verifyUserInIdList(userId, archivingIds);
}

public void validateExistById(Long contentId) {
if (!contentAdaptor.queryContentExistById(contentId)) {
throw ContentNotFoundException.EXCEPTION;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -19,7 +20,7 @@ public class Report extends BaseTimeEntity {
private Long id;

@Enumerated(EnumType.STRING)
private ReportType reportType;
private ReportObjectType reportObjectTypeType;

private String reason;

Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Getter
@AllArgsConstructor
public enum ReportType {
public enum ReportObjectType {
CONTENT("content"),
ARCHIVING("archiving");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading

0 comments on commit ba9c33f

Please sign in to comment.