diff --git a/src/main/java/zipdabang/server/base/Code.java b/src/main/java/zipdabang/server/base/Code.java index aeed725..7d0e84f 100644 --- a/src/main/java/zipdabang/server/base/Code.java +++ b/src/main/java/zipdabang/server/base/Code.java @@ -59,6 +59,7 @@ public enum Code { PHONE_AUTH_ERROR(HttpStatus.BAD_REQUEST, 4057, "잘못된 인증 번호 입니다."), PHONE_AUTH_TIMEOUT(HttpStatus.BAD_REQUEST, 4058, "인증 시간이 초과되었습니다."), TEMP_MEMBER_FORBIDDEN(HttpStatus.FORBIDDEN, 4059, "해당 기능은 로그인을 해야 합니다."), + NO_REPORT_EXIST(HttpStatus.BAD_REQUEST, 4060, "해당 id를 가진 신고 목록이 없습니다. 잘못 보내줬어요"), // market error @@ -72,6 +73,8 @@ public enum Code { NOT_RECIPE_OWNER(HttpStatus.BAD_REQUEST, 4106, "본인이 작성한 레시피가 아닙니다. 변경할 수 없습니다"), NO_COMMENT_EXIST(HttpStatus.BAD_REQUEST, 4107, "해당 댓글이 존재하지 않습니다."), NOT_COMMENT_OWNER(HttpStatus.BAD_REQUEST, 4108, "본인이 작성한 댓글이 아닙니다. 변경할 수 없습니다"), + RECIPE_OWNER(HttpStatus.BAD_REQUEST, 4109, "본인의 레시피입니다. 신고/차단할 수 없습니다"), + COMMENT_OWNER(HttpStatus.BAD_REQUEST, 4110, "본인의 댓글입니다. 신고/차단할 수 없습니다"), INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 5000, "Internal server Error"), FEIGN_CLIENT_ERROR_500(HttpStatus.INTERNAL_SERVER_ERROR, 5001, "Inter server Error in feign client"); diff --git a/src/main/java/zipdabang/server/converter/RecipeConverter.java b/src/main/java/zipdabang/server/converter/RecipeConverter.java index ad01d8b..fe84d2a 100644 --- a/src/main/java/zipdabang/server/converter/RecipeConverter.java +++ b/src/main/java/zipdabang/server/converter/RecipeConverter.java @@ -7,6 +7,7 @@ import org.springframework.web.multipart.MultipartFile; //import zipdabang.server.aws.s3.AmazonS3Manager; import zipdabang.server.aws.s3.AmazonS3Manager; +import zipdabang.server.domain.Report; import zipdabang.server.domain.etc.Uuid; import zipdabang.server.domain.member.Member; import zipdabang.server.domain.recipe.*; @@ -18,7 +19,6 @@ import javax.annotation.PostConstruct; import java.io.IOException; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -386,4 +386,19 @@ public static RecipeResponseDto.CommentPageListDto toPagingCommentDtoList(Page allReports) { + return RootResponseDto.ReportListDto.builder() + .reportList(allReports.stream() + .map(report -> toReportDto(report)) + .collect(Collectors.toList())) + .size(allReports.size()) + .build(); + } + + private static RootResponseDto.ReportDto toReportDto(Report report) { + return RootResponseDto.ReportDto.builder() + .id(report.getId()) + .reportName(report.getName()) + .build(); + } } diff --git a/src/main/java/zipdabang/server/domain/Report.java b/src/main/java/zipdabang/server/domain/Report.java new file mode 100644 index 0000000..33aa644 --- /dev/null +++ b/src/main/java/zipdabang/server/domain/Report.java @@ -0,0 +1,26 @@ +package zipdabang.server.domain; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class Report { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; +} diff --git a/src/main/java/zipdabang/server/domain/recipe/ReportedComment.java b/src/main/java/zipdabang/server/domain/recipe/ReportedComment.java new file mode 100644 index 0000000..7a23519 --- /dev/null +++ b/src/main/java/zipdabang/server/domain/recipe/ReportedComment.java @@ -0,0 +1,35 @@ +package zipdabang.server.domain.recipe; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.Report; +import zipdabang.server.domain.member.Member; + +import javax.persistence.*; + +@Entity +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class ReportedComment { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "report_id", nullable = false) + private Report reportId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "comment_id", nullable = false) + private Comment reported; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "owner_id", nullable = false) + private Member owner; +} diff --git a/src/main/java/zipdabang/server/domain/recipe/ReportedRecipe.java b/src/main/java/zipdabang/server/domain/recipe/ReportedRecipe.java new file mode 100644 index 0000000..8fcae8e --- /dev/null +++ b/src/main/java/zipdabang/server/domain/recipe/ReportedRecipe.java @@ -0,0 +1,35 @@ +package zipdabang.server.domain.recipe; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.Report; +import zipdabang.server.domain.member.Member; + +import javax.persistence.*; + +@Entity +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class ReportedRecipe { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "report_id", nullable = false) + private Report reportId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "recipe_id", nullable = false) + private Recipe reported; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "owner_id", nullable = false) + private Member owner; +} diff --git a/src/main/java/zipdabang/server/repository/ReportRepository.java b/src/main/java/zipdabang/server/repository/ReportRepository.java new file mode 100644 index 0000000..9601d8b --- /dev/null +++ b/src/main/java/zipdabang/server/repository/ReportRepository.java @@ -0,0 +1,7 @@ +package zipdabang.server.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.Report; + +public interface ReportRepository extends JpaRepository { +} diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/BlockedCommentRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/BlockedCommentRepository.java index 3dadfd7..b733e9e 100644 --- a/src/main/java/zipdabang/server/repository/recipeRepositories/BlockedCommentRepository.java +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/BlockedCommentRepository.java @@ -3,9 +3,13 @@ import org.springframework.data.jpa.repository.JpaRepository; import zipdabang.server.domain.member.Member; import zipdabang.server.domain.recipe.BlockedComment; +import zipdabang.server.domain.recipe.Comment; import java.util.List; +import java.util.Optional; public interface BlockedCommentRepository extends JpaRepository { List findByOwner(Member member); + + Boolean existsByOwnerAndBlocked(Member member, Comment findComment); } diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/ReportedCommentRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/ReportedCommentRepository.java new file mode 100644 index 0000000..8431dbc --- /dev/null +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/ReportedCommentRepository.java @@ -0,0 +1,11 @@ +package zipdabang.server.repository.recipeRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.Report; +import zipdabang.server.domain.member.Member; +import zipdabang.server.domain.recipe.Comment; +import zipdabang.server.domain.recipe.ReportedComment; + +public interface ReportedCommentRepository extends JpaRepository { + Boolean existsByReportIdAndReportedAndOwner(Report findReport, Comment findComment, Member member); +} diff --git a/src/main/java/zipdabang/server/service/RecipeService.java b/src/main/java/zipdabang/server/service/RecipeService.java index 637b5ac..8436cb3 100644 --- a/src/main/java/zipdabang/server/service/RecipeService.java +++ b/src/main/java/zipdabang/server/service/RecipeService.java @@ -53,4 +53,7 @@ public interface RecipeService { Comment updateComment(RecipeRequestDto.updateCommentDto request, Long recipeId, Long commentId, Member member); + Long reportComment(RecipeRequestDto.reportCommentDto request, Long recipeId, Long commentId, Member member); + + Long blockComment(Long recipeId, Long commentId, Member member); } diff --git a/src/main/java/zipdabang/server/service/RootService.java b/src/main/java/zipdabang/server/service/RootService.java index 976543b..dc27f64 100644 --- a/src/main/java/zipdabang/server/service/RootService.java +++ b/src/main/java/zipdabang/server/service/RootService.java @@ -1,6 +1,7 @@ package zipdabang.server.service; import zipdabang.server.domain.Category; +import zipdabang.server.domain.Report; import zipdabang.server.domain.inform.Notification; import java.util.List; @@ -14,4 +15,6 @@ public interface RootService { List notificationList(); Notification findNotification(Long notificationId); + + List getAllReports(); } diff --git a/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java b/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java index 573a8cc..f78bc0b 100644 --- a/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java +++ b/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java @@ -12,17 +12,17 @@ import zipdabang.server.aws.s3.AmazonS3Manager; import zipdabang.server.base.Code; import zipdabang.server.base.exception.handler.RecipeException; -import zipdabang.server.config.AmazonConfig; import zipdabang.server.converter.RecipeConverter; +import zipdabang.server.domain.Report; import zipdabang.server.domain.member.BlockedMember; import zipdabang.server.domain.member.Member; import zipdabang.server.domain.recipe.*; +import zipdabang.server.repository.ReportRepository; import zipdabang.server.repository.memberRepositories.BlockedMemberRepository; import zipdabang.server.repository.recipeRepositories.*; import zipdabang.server.service.RecipeService; import zipdabang.server.web.dto.requestDto.RecipeRequestDto; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -48,6 +48,8 @@ public class RecipeServiceImpl implements RecipeService { private final BlockedMemberRepository blockedMemberRepository; private final CommentRepository commentRepository; private final BlockedCommentRepository blockedCommentRepository; + private final ReportRepository reportRepository; + private final ReportedCommentRepository reportedCommentRepository; @Value("${paging.size}") Integer pageSize; @@ -386,4 +388,37 @@ public Comment updateComment(RecipeRequestDto.updateCommentDto request, Long rec else throw new RecipeException(Code.NOT_COMMENT_OWNER); } + + @Transactional(readOnly = false) + @Override + public Long reportComment(RecipeRequestDto.reportCommentDto request, Long recipeId, Long commentId, Member member) { + Recipe findRecipe = recipeRepository.findById(recipeId).orElseThrow(() -> new RecipeException(Code.NO_RECIPE_EXIST)); + Comment findComment = commentRepository.findById(commentId).orElseThrow(() -> new RecipeException(Code.NO_COMMENT_EXIST)); + Report findReport = reportRepository.findById(request.getReportId()).orElseThrow(() -> new RecipeException(Code.NO_REPORT_EXIST)); + + if (!findComment.getMember().equals(member) && findComment.getRecipe().equals(findRecipe)) { + ReportedComment mapping = RecipeConverter.toCommentReport(findReport, findComment, member); + reportedCommentRepository.save(mapping); + + return findComment.getId(); + } + else + throw new RecipeException(Code.COMMENT_OWNER); + } + + @Transactional(readOnly = false) + @Override + public Long blockComment(Long recipeId, Long commentId, Member member) { + Recipe findRecipe = recipeRepository.findById(recipeId).orElseThrow(() -> new RecipeException(Code.NO_RECIPE_EXIST)); + Comment findComment = commentRepository.findById(commentId).orElseThrow(() -> new RecipeException(Code.NO_COMMENT_EXIST)); + + if (!findComment.getMember().equals(member) && findComment.getRecipe().equals(findRecipe)) { + BlockedComment mapping = RecipeConverter.toCommentBlock(findComment, member); + blockedCommentRepository.save(mapping); + + return findComment.getId(); + } + else + throw new RecipeException(Code.COMMENT_OWNER); + } } diff --git a/src/main/java/zipdabang/server/service/serviceImpl/RootServiceImpl.java b/src/main/java/zipdabang/server/service/serviceImpl/RootServiceImpl.java index 00e089a..1990534 100644 --- a/src/main/java/zipdabang/server/service/serviceImpl/RootServiceImpl.java +++ b/src/main/java/zipdabang/server/service/serviceImpl/RootServiceImpl.java @@ -8,10 +8,12 @@ import zipdabang.server.base.Code; import zipdabang.server.base.exception.handler.RootException; import zipdabang.server.domain.Category; +import zipdabang.server.domain.Report; import zipdabang.server.domain.inform.Notification; import zipdabang.server.domain.member.Member; import zipdabang.server.repository.CategoryRepository; import zipdabang.server.repository.NotificationRepository; +import zipdabang.server.repository.ReportRepository; import zipdabang.server.repository.memberRepositories.MemberRepository; import zipdabang.server.service.RootService; @@ -29,6 +31,8 @@ public class RootServiceImpl implements RootService { private final NotificationRepository notificationRepository; + private final ReportRepository reportRepository; + private final TokenProvider tokenProvider; @Override @@ -68,4 +72,9 @@ public List notificationList() { public Notification findNotification(Long notificationId) { return notificationRepository.findById(notificationId).get(); } + + @Override + public List getAllReports() { + return reportRepository.findAll(); + } } diff --git a/src/main/java/zipdabang/server/web/controller/RecipeRestController.java b/src/main/java/zipdabang/server/web/controller/RecipeRestController.java index ccc800e..d5adaab 100644 --- a/src/main/java/zipdabang/server/web/controller/RecipeRestController.java +++ b/src/main/java/zipdabang/server/web/controller/RecipeRestController.java @@ -14,6 +14,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.view.RedirectView; import zipdabang.server.auth.handler.annotation.AuthMember; import zipdabang.server.base.Code; import zipdabang.server.base.ResponseDto; @@ -475,4 +476,49 @@ public ResponseDto updateComment(@RequestBody Reci return ResponseDto.of(RecipeConverter.toCommentDto(updateComment, member)); } + + @Operation(summary = "댓글 신고 API 🔑 ✔", description = "댓글 신고 API입니다.") + @ApiResponses({ + @ApiResponse(responseCode = "2000", description = "OK, 댓글이 신고 되었습니다."), + @ApiResponse(responseCode = "4003", description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4005", description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4008", description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4052", description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4060", description = "BAD_REQUEST, 해당 id를 가진 신고 목록이 없습니다. 잘못 보내줬어요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4101", description = "BAD_REQUEST, 해당 recipeId를 가진 recipe가 없어요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4107", description = "BAD_REQUEST, 해당 commentId를 가진 댓글이 없어요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4110", description = "BAD_REQUEST, 본인의 댓글입니다. 신고/차단할 수 없습니다", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "5000", description = "SERVER ERROR, 백앤드 개발자에게 알려주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + }) + @Parameters({ + @Parameter(name = "member", hidden = true), + }) + @PostMapping("/members/recipes/{recipeId}/{commentId}/report") + public ResponseDto reportComment(@RequestBody RecipeRequestDto.reportCommentDto request, @PathVariable(name = "recipeId") Long recipeId, @PathVariable(name = "commentId") Long commentId, @CheckTempMember @AuthMember Member member) { + Long reportedCommentId = recipeService.reportComment(request, recipeId,commentId, member); + + return ResponseDto.of(reportedCommentId+"번 댓글이 신고되었습니다."); + } + + @Operation(summary = "댓글 차단 API 🔑 ✔", description = "댓글 차단 API입니다.") + @ApiResponses({ + @ApiResponse(responseCode = "2000", description = "OK, 댓글이 차단 되었습니다."), + @ApiResponse(responseCode = "4003", description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4005", description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4008", description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4052", description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4101", description = "BAD_REQUEST, 해당 recipeId를 가진 recipe가 없어요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4107", description = "BAD_REQUEST, 해당 commentId를 가진 댓글이 없어요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4110", description = "BAD_REQUEST, 본인의 댓글입니다. 신고/차단할 수 없습니다", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "5000", description = "SERVER ERROR, 백앤드 개발자에게 알려주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + }) + @Parameters({ + @Parameter(name = "member", hidden = true), + }) + @GetMapping("/members/recipes/{recipeId}/{commentId}/block") + public ResponseDto blockComment(@PathVariable(name = "recipeId") Long recipeId, @PathVariable(name = "commentId") Long commentId, @CheckTempMember @AuthMember Member member) { + Long blockCommentId = recipeService.blockComment(recipeId, commentId, member); + + return ResponseDto.of(blockCommentId+"번 댓글이 차단되었습니다."); + } } diff --git a/src/main/java/zipdabang/server/web/controller/RootController.java b/src/main/java/zipdabang/server/web/controller/RootController.java index 009e331..a06e8d5 100644 --- a/src/main/java/zipdabang/server/web/controller/RootController.java +++ b/src/main/java/zipdabang/server/web/controller/RootController.java @@ -18,6 +18,7 @@ import zipdabang.server.base.ResponseDto; import zipdabang.server.converter.RootConverter; import zipdabang.server.domain.Category; +import zipdabang.server.domain.Report; import zipdabang.server.domain.inform.Notification; import zipdabang.server.service.RootService; import zipdabang.server.validation.annotation.ExistNotification; @@ -94,4 +95,18 @@ public ResponseDto getNoticeList(){ List notificationList = rootService.notificationList(); return ResponseDto.of(RootConverter.toNoticeListDto(notificationList)); } + + @Operation(summary = "신고 목록 조회 API 🔑 ✔", description = "신고 목록 조회 API입니다.") + @ApiResponses({ + @ApiResponse(responseCode = "2000", description = "OK 성공"), + @ApiResponse(responseCode = "4003", description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4005", description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4008", description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4052", description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + }) + @GetMapping("/reports") + public ResponseDto showReportList(){ + List allReports = rootService.getAllReports(); + return ResponseDto.of(RootConverter.toReportListDto(allReports)); + } } diff --git a/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java b/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java index e814c78..62773dc 100644 --- a/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java +++ b/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java @@ -45,4 +45,9 @@ public static class createCommentDto { public static class updateCommentDto { private String comment; } + + @Getter + public static class reportCommentDto { + private Long reportId; + } } diff --git a/src/main/java/zipdabang/server/web/dto/responseDto/RootResponseDto.java b/src/main/java/zipdabang/server/web/dto/responseDto/RootResponseDto.java index 84faa11..5fe7adb 100644 --- a/src/main/java/zipdabang/server/web/dto/responseDto/RootResponseDto.java +++ b/src/main/java/zipdabang/server/web/dto/responseDto/RootResponseDto.java @@ -70,4 +70,22 @@ public static class NoticeListDto{ List noticeList; Integer size; } + + @Builder + @Getter + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class ReportDto{ + private Long id; + private String reportName; + } + + @Builder + @Getter + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class ReportListDto{ + List reportList; + Integer size; + } }