From 4590e26e598e184bfad52fc69d0c5f49cfbaa67b Mon Sep 17 00:00:00 2001 From: heejjinkim Date: Fri, 8 Nov 2024 10:50:51 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=ED=95=A0=20=EB=95=8C=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=A4=EB=B2=84=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/ProjectMemberResponse.java | 40 +++++++++++++++++++ .../presentation/ProjectController.java | 9 +++++ .../wepro/project/service/ProjectService.java | 12 ++++++ .../review/dto/response/ReviewResponse.java | 34 ---------------- .../review/presentation/ReviewController.java | 12 ------ 5 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java diff --git a/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java b/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java new file mode 100644 index 0000000..56990f5 --- /dev/null +++ b/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java @@ -0,0 +1,40 @@ +package com._119.wepro.project.dto.response; + +import com._119.wepro.project.domain.ProjectMember; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ProjectMemberResponse { + private List memberList; + + public static ProjectMemberResponse of(List projectMembers) { + return ProjectMemberResponse.builder() + .memberList(projectMembers.stream() + .map(MemberDto::of) + .toList()) + .build(); + } + + @Getter + @Builder + public static class MemberDto { + + private Long id; + private String profileUrl; + private String name; + private String tag; + private boolean isAlreadyRequest; + + public static MemberDto of(ProjectMember projectMember) { + return MemberDto.builder() + .id(projectMember.getId()) + .profileUrl(projectMember.getMember().getProfile().getProfileImageUrl()) + .name(projectMember.getMember().getProfile().getName()) + .tag(projectMember.getMember().getTag()) + .build(); + } + } +} diff --git a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java index 592ad65..44be62b 100644 --- a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java +++ b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java @@ -7,6 +7,7 @@ import com._119.wepro.project.dto.response.MyProjectResponse; import com._119.wepro.project.dto.response.ProjectDetailResponse; import com._119.wepro.project.dto.response.ProjectListResponse; +import com._119.wepro.project.dto.response.ProjectMemberResponse; import com._119.wepro.project.service.ProjectService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -201,4 +202,12 @@ public ResponseEntity addMember( projectService.addProjectMember(projectMemberCreateRequest.getMemberId(), id); return ResponseEntity.ok(null); } + + @Operation(summary = "리뷰 요청할 때 프로젝트 멤버 조회 API") + @GetMapping("/members/request/review") + public ResponseEntity getProjectMembersWithReviewRequest( + @RequestParam Long reviewFormId) { + securityUtil.getCurrentMemberId(); + return ResponseEntity.ok(projectService.getProjectMembersWithReviewRequest(reviewFormId)); + } } \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/project/service/ProjectService.java b/src/main/java/com/_119/wepro/project/service/ProjectService.java index c406a5b..d269b56 100644 --- a/src/main/java/com/_119/wepro/project/service/ProjectService.java +++ b/src/main/java/com/_119/wepro/project/service/ProjectService.java @@ -20,6 +20,8 @@ import com._119.wepro.project.dto.response.MyProjectResponse; import com._119.wepro.project.dto.response.ProjectDetailResponse; import com._119.wepro.project.dto.response.ProjectListResponse; +import com._119.wepro.project.dto.response.ProjectMemberResponse; +import com._119.wepro.review.domain.repository.ReviewFormRepository; import jakarta.transaction.Transactional; import java.util.List; import java.util.stream.Collectors; @@ -35,6 +37,7 @@ public class ProjectService { private final ProjectMemberCustomRepository projectMemberCustomRepository; private final MemberRepository memberRepository; private final ProjectCustomRepository projectCustomRepository; + private final ReviewFormRepository reviewFormRepository; public List searchProjects(String keyword) { List result = projectCustomRepository.searchProjects(keyword); @@ -151,4 +154,13 @@ public void addProjectMember(Long projectId, Long userId) { project.setMemberNum(project.getMemberNum() + 1); projectRepository.save(project); } + + public ProjectMemberResponse getProjectMembersWithReviewRequest(Long reviewFormId) { + + reviewFormRepository.findByIdOrThrow(reviewFormId); + List filteredMembers = projectMemberCustomRepository.getProjectMembersWithoutReviewRequest( + reviewFormId); + + return ProjectMemberResponse.of(filteredMembers); + } } \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/review/dto/response/ReviewResponse.java b/src/main/java/com/_119/wepro/review/dto/response/ReviewResponse.java index d6c1e33..016d6d3 100644 --- a/src/main/java/com/_119/wepro/review/dto/response/ReviewResponse.java +++ b/src/main/java/com/_119/wepro/review/dto/response/ReviewResponse.java @@ -20,38 +20,4 @@ public static ReviewFormCreateResponse of(ReviewForm reviewForm) { .build(); } } - - @Getter - @Builder - public static class ProjectMemberGetResponse { - - private List memberList; - - public static ProjectMemberGetResponse of(List projectMembers) { - return ProjectMemberGetResponse.builder() - .memberList(projectMembers.stream() - .map(MemberDto::of) - .toList()) - .build(); - } - - @Getter - @Builder - public static class MemberDto { - - private Long id; - private String profileUrl; - private String name; - private String tag; - - public static MemberDto of(ProjectMember projectMember) { - return MemberDto.builder() - .id(projectMember.getId()) - .profileUrl(projectMember.getMember().getProfile().getProfileImageUrl()) - .name(projectMember.getMember().getProfile().getName()) - .tag(projectMember.getMember().getTag()) - .build(); - } - } - } } diff --git a/src/main/java/com/_119/wepro/review/presentation/ReviewController.java b/src/main/java/com/_119/wepro/review/presentation/ReviewController.java index b2f0e29..1100bcd 100644 --- a/src/main/java/com/_119/wepro/review/presentation/ReviewController.java +++ b/src/main/java/com/_119/wepro/review/presentation/ReviewController.java @@ -1,23 +1,19 @@ package com._119.wepro.review.presentation; import com._119.wepro.global.util.SecurityUtil; -import com._119.wepro.review.dto.request.ReviewRequest; import com._119.wepro.review.dto.request.ReviewRequest.ReviewAskRequest; import com._119.wepro.review.dto.request.ReviewRequest.ReviewFormCreateRequest; import com._119.wepro.review.dto.request.ReviewRequest.ReviewSaveRequest; -import com._119.wepro.review.dto.response.ReviewResponse.ProjectMemberGetResponse; import com._119.wepro.review.dto.response.ReviewResponse.ReviewFormCreateResponse; import com._119.wepro.review.service.ReviewService; import io.swagger.v3.oas.annotations.Operation; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -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 @@ -53,14 +49,6 @@ public ResponseEntity draftReview(@PathVariable(name = "reviewFormId") Lon return ResponseEntity.ok().build(); } - @Operation(summary = "프로젝트 멤버 조회(리뷰 요청 받은 멤버 제외) API") - @GetMapping("/project/members") - public ResponseEntity getProjectMembers( - @RequestParam Long reviewFormId) { - securityUtil.getCurrentMemberId(); - return ResponseEntity.ok(reviewService.getProjectMembers(reviewFormId)); - } - @Operation(summary = "리뷰 제출하기 API") @PostMapping("/{reviewFormId}") public ResponseEntity submitReview(@PathVariable(name = "reviewFormId") Long reviewFormId, From f001ee2ff549fc67a3d0f10721e40a509f23544e Mon Sep 17 00:00:00 2001 From: heejjinkim Date: Fri, 8 Nov 2024 10:51:40 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=ED=95=98=EA=B8=B0=20=EB=A6=AC=EB=B7=B0=EC=96=B4=20?= =?UTF-8?q?=ED=95=9C=20=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 여러 명에게 한 번에 리뷰 요청 -> 한 명에 대해서만 리뷰 요청 --- .../wepro/review/dto/request/ReviewRequest.java | 2 +- .../wepro/review/service/ReviewService.java | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/_119/wepro/review/dto/request/ReviewRequest.java b/src/main/java/com/_119/wepro/review/dto/request/ReviewRequest.java index 7924157..bd176c5 100644 --- a/src/main/java/com/_119/wepro/review/dto/request/ReviewRequest.java +++ b/src/main/java/com/_119/wepro/review/dto/request/ReviewRequest.java @@ -35,7 +35,7 @@ public static class ReviewAskRequest { private Long reviewFormId; @NotNull - private List memberIdList; + private Long reviewerId; } @Getter diff --git a/src/main/java/com/_119/wepro/review/service/ReviewService.java b/src/main/java/com/_119/wepro/review/service/ReviewService.java index 6cc414c..e9abfbe 100644 --- a/src/main/java/com/_119/wepro/review/service/ReviewService.java +++ b/src/main/java/com/_119/wepro/review/service/ReviewService.java @@ -7,7 +7,6 @@ import com._119.wepro.member.domain.Member; import com._119.wepro.member.domain.repository.MemberRepository; import com._119.wepro.project.domain.Project; -import com._119.wepro.project.domain.ProjectMember; import com._119.wepro.project.domain.repository.ProjectMemberCustomRepository; import com._119.wepro.project.domain.repository.ProjectRepository; import com._119.wepro.review.domain.ReviewForm; @@ -21,7 +20,6 @@ import com._119.wepro.review.dto.request.ReviewRequest.ReviewAskRequest; import com._119.wepro.review.dto.request.ReviewRequest.ReviewFormCreateRequest; import com._119.wepro.review.dto.request.ReviewRequest.ReviewSaveRequest; -import com._119.wepro.review.dto.response.ReviewResponse.ProjectMemberGetResponse; import com._119.wepro.review.dto.response.ReviewResponse.ReviewFormCreateResponse; import jakarta.transaction.Transactional; import java.util.List; @@ -59,18 +57,9 @@ public ReviewFormCreateResponse createReviewForm(ReviewFormCreateRequest request public void requestReview(ReviewAskRequest request, Long memberId) { Member member = memberRepository.findByIdOrThrow(memberId); - request.getMemberIdList().forEach(reviewerId -> { - alarmService.createAlarm(member, reviewerId, AlarmType.REVIEW_REQUEST, - request.getReviewFormId()); - }); - } - - public ProjectMemberGetResponse getProjectMembers(Long reviewFormId) { - reviewFormRepository.findByIdOrThrow(reviewFormId); - List filteredMembers = projectMemberCustomRepository.getProjectMembersWithoutReviewRequest( - reviewFormId); - - return ProjectMemberGetResponse.of(filteredMembers); + Long reviewerId = request.getReviewerId(); + Long reviewFormId = request.getReviewFormId(); + alarmService.createAlarm(member, reviewerId, AlarmType.REVIEW_REQUEST, reviewFormId); } @Transactional From 914a1b1acf7eec5d553dfc7e69fe287b0d74c34e Mon Sep 17 00:00:00 2001 From: heejjinkim <06.hjhj.12@gmail.com> Date: Fri, 8 Nov 2024 15:24:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EC=A0=95=EB=B3=B4=20=ED=8F=AC=ED=95=A8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../ProjectMemberCustomRepository.java | 31 +-- .../response/MemberRequestStatusResponse.java | 26 +++ .../dto/response/ProjectMemberResponse.java | 40 ---- .../presentation/ProjectController.java | 12 +- .../wepro/project/service/ProjectService.java | 197 +++++++++--------- 6 files changed, 150 insertions(+), 159 deletions(-) create mode 100644 src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java delete mode 100644 src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java diff --git a/.gitignore b/.gitignore index 2dbb335..525bd2f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ out/ ### VS Code ### .vscode/ -db/mysql/data/* \ No newline at end of file +db/mysql/data/* +/src/main/generated/ \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/project/domain/repository/ProjectMemberCustomRepository.java b/src/main/java/com/_119/wepro/project/domain/repository/ProjectMemberCustomRepository.java index 1dceb1a..c9db4a7 100644 --- a/src/main/java/com/_119/wepro/project/domain/repository/ProjectMemberCustomRepository.java +++ b/src/main/java/com/_119/wepro/project/domain/repository/ProjectMemberCustomRepository.java @@ -1,15 +1,12 @@ package com._119.wepro.project.domain.repository; -import static com._119.wepro.project.domain.QProjectMember.projectMember; - import com._119.wepro.member.domain.Member; import com._119.wepro.project.domain.Project; import com._119.wepro.alarm.domain.QAlarm; import com._119.wepro.global.enums.AlarmType; import com._119.wepro.member.domain.QMember; -import com._119.wepro.project.domain.ProjectMember; import com._119.wepro.project.domain.QProjectMember; -import com.querydsl.jpa.JPAExpressions; +import com._119.wepro.project.dto.response.MemberRequestStatusResponse; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import lombok.RequiredArgsConstructor; @@ -22,6 +19,8 @@ public class ProjectMemberCustomRepository { private final JPAQueryFactory queryFactory; public Boolean existsByProjectAndMember(Project project, Member member) { + QProjectMember projectMember = QProjectMember.projectMember; + Integer fetchOne = queryFactory .selectOne() .from(projectMember) @@ -30,22 +29,28 @@ public Boolean existsByProjectAndMember(Project project, Member member) { return fetchOne != null; } - public List getProjectMembersWithoutReviewRequest(Long reviewFormId) { + public List getProjectMembersWithReviewRequestStatus(Long reviewFormId) { QProjectMember projectMember = QProjectMember.projectMember; QAlarm alarm = QAlarm.alarm; - QMember member = QMember.member; // Member 엔티티를 가져오기 위해 추가 + QMember member = QMember.member; + + List requestedMemberIds = queryFactory + .select(alarm.receiver.id) + .from(alarm) + .where(alarm.targetId.eq(reviewFormId) + .and(alarm.alarmType.eq(AlarmType.REVIEW_REQUEST))) + .fetch(); return queryFactory .selectFrom(projectMember) .join(projectMember.member, member).fetchJoin() - .where(projectMember.id.notIn( - JPAExpressions - .select(alarm.receiver.id) - .from(alarm) - .where(alarm.targetId.eq(reviewFormId) - .and(alarm.alarmType.eq(AlarmType.REVIEW_REQUEST))) + .fetch() + .stream() + .map(pm -> MemberRequestStatusResponse.of( + pm.getMember(), + requestedMemberIds.contains(pm.getMember().getId()) )) - .fetch(); + .toList(); } } \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java b/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java new file mode 100644 index 0000000..2adc299 --- /dev/null +++ b/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java @@ -0,0 +1,26 @@ +package com._119.wepro.project.dto.response; + +import com._119.wepro.member.domain.Member; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class MemberRequestStatusResponse { + + private Long id; + private String profileUrl; + private String name; + private String tag; + private boolean isAlreadyRequest; + + public static MemberRequestStatusResponse of(Member member, boolean isAlreadyRequest) { + return MemberRequestStatusResponse.builder() + .id(member.getId()) + .profileUrl(member.getProfile().getProfileImageUrl()) + .name(member.getProfile().getName()) + .tag(member.getTag()) + .isAlreadyRequest(isAlreadyRequest) + .build(); + } +} diff --git a/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java b/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java deleted file mode 100644 index 56990f5..0000000 --- a/src/main/java/com/_119/wepro/project/dto/response/ProjectMemberResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package com._119.wepro.project.dto.response; - -import com._119.wepro.project.domain.ProjectMember; -import java.util.List; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class ProjectMemberResponse { - private List memberList; - - public static ProjectMemberResponse of(List projectMembers) { - return ProjectMemberResponse.builder() - .memberList(projectMembers.stream() - .map(MemberDto::of) - .toList()) - .build(); - } - - @Getter - @Builder - public static class MemberDto { - - private Long id; - private String profileUrl; - private String name; - private String tag; - private boolean isAlreadyRequest; - - public static MemberDto of(ProjectMember projectMember) { - return MemberDto.builder() - .id(projectMember.getId()) - .profileUrl(projectMember.getMember().getProfile().getProfileImageUrl()) - .name(projectMember.getMember().getProfile().getName()) - .tag(projectMember.getMember().getTag()) - .build(); - } - } -} diff --git a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java index 44be62b..4a6cb68 100644 --- a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java +++ b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java @@ -7,7 +7,7 @@ import com._119.wepro.project.dto.response.MyProjectResponse; import com._119.wepro.project.dto.response.ProjectDetailResponse; import com._119.wepro.project.dto.response.ProjectListResponse; -import com._119.wepro.project.dto.response.ProjectMemberResponse; +import com._119.wepro.project.dto.response.MemberRequestStatusResponse; import com._119.wepro.project.service.ProjectService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -203,11 +203,11 @@ public ResponseEntity addMember( return ResponseEntity.ok(null); } - @Operation(summary = "리뷰 요청할 때 프로젝트 멤버 조회 API") - @GetMapping("/members/request/review") - public ResponseEntity getProjectMembersWithReviewRequest( - @RequestParam Long reviewFormId) { + @Operation(summary = "리뷰 요청할 때 프로젝트 멤버 조회", description = "리뷰 요청 가능 여부를 포함하여 프로젝트 멤버 정보를 조회합니다.") + @GetMapping("/members/request/review/{reviewFormId}") + public ResponseEntity> getProjectMembersWithRequestStatus( + @PathVariable("reviewFormId") Long reviewFormId) { securityUtil.getCurrentMemberId(); - return ResponseEntity.ok(projectService.getProjectMembersWithReviewRequest(reviewFormId)); + return ResponseEntity.ok(projectService.getProjectMembersWithRequestStatus(reviewFormId)); } } \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/project/service/ProjectService.java b/src/main/java/com/_119/wepro/project/service/ProjectService.java index d269b56..54276b2 100644 --- a/src/main/java/com/_119/wepro/project/service/ProjectService.java +++ b/src/main/java/com/_119/wepro/project/service/ProjectService.java @@ -17,10 +17,10 @@ import com._119.wepro.project.domain.repository.ProjectRepository; import com._119.wepro.project.dto.request.ProjectRequest.ProjectCreateRequest; import com._119.wepro.project.dto.request.ProjectRequest.ProjectUpdateRequest; +import com._119.wepro.project.dto.response.MemberRequestStatusResponse; import com._119.wepro.project.dto.response.MyProjectResponse; import com._119.wepro.project.dto.response.ProjectDetailResponse; import com._119.wepro.project.dto.response.ProjectListResponse; -import com._119.wepro.project.dto.response.ProjectMemberResponse; import com._119.wepro.review.domain.repository.ReviewFormRepository; import jakarta.transaction.Transactional; import java.util.List; @@ -32,135 +32,134 @@ @RequiredArgsConstructor public class ProjectService { - private final ProjectRepository projectRepository; - private final ProjectMemberRepository projectMemberRepository; - private final ProjectMemberCustomRepository projectMemberCustomRepository; - private final MemberRepository memberRepository; - private final ProjectCustomRepository projectCustomRepository; - private final ReviewFormRepository reviewFormRepository; + private final ProjectRepository projectRepository; + private final ProjectMemberRepository projectMemberRepository; + private final ProjectMemberCustomRepository projectMemberCustomRepository; + private final MemberRepository memberRepository; + private final ProjectCustomRepository projectCustomRepository; + private final ReviewFormRepository reviewFormRepository; - public List searchProjects(String keyword) { - List result = projectCustomRepository.searchProjects(keyword); + public List searchProjects(String keyword) { + List result = projectCustomRepository.searchProjects(keyword); - return result.stream().map(ProjectListResponse::of).toList(); - } - - public List getMyProjects(Long id) { - - return projectCustomRepository.getMyProjects(id); - } + return result.stream().map(ProjectListResponse::of).toList(); + } - public ProjectDetailResponse getProjectDetail(Long projectId) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + public List getMyProjects(Long id) { - return ProjectDetailResponse.of(project); - } + return projectCustomRepository.getMyProjects(id); + } - @Transactional - public Long createProject(ProjectCreateRequest projectCreateRequest, Long projectCreatorId) { - Project newProject = Project.of(projectCreateRequest); + public ProjectDetailResponse getProjectDetail(Long projectId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - // 팀원 멤버 역할로 등록 - for (Long memberId : projectCreateRequest.getMemberList()) { - registerProjectMember(newProject, memberId, MEMBER.name()); + return ProjectDetailResponse.of(project); } - // 팀장 등록 - registerProjectMember(newProject, projectCreatorId, TEAM_LEADER.name()); + @Transactional + public Long createProject(ProjectCreateRequest projectCreateRequest, Long projectCreatorId) { + Project newProject = Project.of(projectCreateRequest); - newProject.setImageList( - projectCreateRequest.getImgUrls().stream() - .map(imgUrl -> Image.of(imgUrl, newProject)) - .collect(Collectors.toList()) - ); + // 팀원 멤버 역할로 등록 + for (Long memberId : projectCreateRequest.getMemberList()) { + registerProjectMember(newProject, memberId, MEMBER.name()); + } - return projectRepository.save(newProject).getId(); - } + // 팀장 등록 + registerProjectMember(newProject, projectCreatorId, TEAM_LEADER.name()); - @Transactional - public Long updateProject(Long projectId, ProjectUpdateRequest projectUpdateRequest) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new IllegalArgumentException("Project not found with id: " + projectId)); + newProject.setImageList( + projectCreateRequest.getImgUrls().stream() + .map(imgUrl -> Image.of(imgUrl, newProject)) + .collect(Collectors.toList()) + ); - Project updatedProject = Project.of(projectUpdateRequest); - - updatedProject.setImageList(projectUpdateRequest.getImgUrls().stream() - .map(imgUrl -> Image.of(imgUrl, project)) - .collect(Collectors.toList())); + return projectRepository.save(newProject).getId(); + } - // 기존 팀원 정보 삭제 후 새로 업데이트된 팀원 추가 - projectMemberRepository.deleteByProjectId(projectId); + @Transactional + public Long updateProject(Long projectId, ProjectUpdateRequest projectUpdateRequest) { + Project project = projectRepository.findById(projectId) + .orElseThrow( + () -> new IllegalArgumentException("Project not found with id: " + projectId)); - for (Long memberId : projectUpdateRequest.getMemberList()) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new IllegalArgumentException("Invalid member ID: " + memberId)); + Project updatedProject = Project.of(projectUpdateRequest); - ProjectMember projectMember = ProjectMember.builder() - .project(project) - .member(member) - .role(MEMBER) - .build(); + updatedProject.setImageList(projectUpdateRequest.getImgUrls().stream() + .map(imgUrl -> Image.of(imgUrl, project)) + .collect(Collectors.toList())); - projectMemberRepository.save(projectMember); - } + // 기존 팀원 정보 삭제 후 새로 업데이트된 팀원 추가 + projectMemberRepository.deleteByProjectId(projectId); - return projectRepository.save(project).getId(); - } + for (Long memberId : projectUpdateRequest.getMemberList()) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("Invalid member ID: " + memberId)); - private void registerProjectMember(Project project, Long memberId, String role) { - // findById를 사용하여 실제 member가 존재하는지 확인 - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new RestApiException(PROJECT_MEMBER_NOT_FOUND)); + ProjectMember projectMember = ProjectMember.builder() + .project(project) + .member(member) + .role(MEMBER) + .build(); - ProjectMember projectMember = ProjectMember.of(project, member, role); + projectMemberRepository.save(projectMember); + } - project.getProjectMembers().add(projectMember); - project.setMemberNum(project.getMemberNum() + 1); - } + return projectRepository.save(project).getId(); + } + private void registerProjectMember(Project project, Long memberId, String role) { + // findById를 사용하여 실제 member가 존재하는지 확인 + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new RestApiException(PROJECT_MEMBER_NOT_FOUND)); - public Long deleteProject(Long projectId) { - Project project = projectRepository.findById(projectId).orElseThrow(() -> new RestApiException( - RESOURCE_NOT_FOUND)); - projectRepository.delete(project); + ProjectMember projectMember = ProjectMember.of(project, member, role); - return project.getId(); - } + project.getProjectMembers().add(projectMember); + project.setMemberNum(project.getMemberNum() + 1); + } - @Transactional - public void addProjectMember(Long projectId, Long userId) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - //todo : 탈퇴한 멤버 제외 - Member member = memberRepository.findById(userId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + public Long deleteProject(Long projectId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException( + RESOURCE_NOT_FOUND)); + projectRepository.delete(project); - // 기존에 해당 프로젝트와 멤버 조합이 있는지 확인합니다. - boolean exists = projectMemberCustomRepository.existsByProjectAndMember(project, member); - if (exists) { - throw new IllegalArgumentException("This member is already part of the project."); + return project.getId(); } - ProjectMember projectMember = ProjectMember.builder() - .project(project) - .member(member) - .role(MEMBER) - .build(); + @Transactional + public void addProjectMember(Long projectId, Long userId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + + //todo : 탈퇴한 멤버 제외 + Member member = memberRepository.findById(userId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - projectMemberRepository.save(projectMember); + // 기존에 해당 프로젝트와 멤버 조합이 있는지 확인합니다. + boolean exists = projectMemberCustomRepository.existsByProjectAndMember(project, member); + if (exists) { + throw new IllegalArgumentException("This member is already part of the project."); + } - project.setMemberNum(project.getMemberNum() + 1); - projectRepository.save(project); - } + ProjectMember projectMember = ProjectMember.builder() + .project(project) + .member(member) + .role(MEMBER) + .build(); - public ProjectMemberResponse getProjectMembersWithReviewRequest(Long reviewFormId) { + projectMemberRepository.save(projectMember); - reviewFormRepository.findByIdOrThrow(reviewFormId); - List filteredMembers = projectMemberCustomRepository.getProjectMembersWithoutReviewRequest( - reviewFormId); + project.setMemberNum(project.getMemberNum() + 1); + projectRepository.save(project); + } + + public List getProjectMembersWithRequestStatus(Long reviewFormId) { - return ProjectMemberResponse.of(filteredMembers); - } + reviewFormRepository.findByIdOrThrow(reviewFormId); + return projectMemberCustomRepository.getProjectMembersWithReviewRequestStatus(reviewFormId); + } } \ No newline at end of file From c4f366253b1e973c11a6d14c660dd312475d6a0f Mon Sep 17 00:00:00 2001 From: heejjinkim <06.hjhj.12@gmail.com> Date: Fri, 8 Nov 2024 16:07:06 +0900 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=EC=8A=A4=EC=9B=A8=EA=B1=B0=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/MemberRequestStatusResponse.java | 28 +-- .../presentation/ProjectController.java | 28 ++- .../wepro/project/service/ProjectService.java | 194 +++++++++--------- .../presentation/QuestionController.java | 134 +++++++++++- .../review/presentation/ReviewController.java | 35 +++- 5 files changed, 301 insertions(+), 118 deletions(-) diff --git a/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java b/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java index 2adc299..f3e40fb 100644 --- a/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java +++ b/src/main/java/com/_119/wepro/project/dto/response/MemberRequestStatusResponse.java @@ -8,19 +8,19 @@ @Builder public class MemberRequestStatusResponse { - private Long id; - private String profileUrl; - private String name; - private String tag; - private boolean isAlreadyRequest; + private Long id; + private String profileUrl; + private String name; + private String tag; + private boolean isAlreadyRequest; - public static MemberRequestStatusResponse of(Member member, boolean isAlreadyRequest) { - return MemberRequestStatusResponse.builder() - .id(member.getId()) - .profileUrl(member.getProfile().getProfileImageUrl()) - .name(member.getProfile().getName()) - .tag(member.getTag()) - .isAlreadyRequest(isAlreadyRequest) - .build(); - } + public static MemberRequestStatusResponse of(Member member, boolean isAlreadyRequest) { + return MemberRequestStatusResponse.builder() + .id(member.getId()) + .profileUrl(member.getProfile().getProfileImageUrl()) + .name(member.getProfile().getName()) + .tag(member.getTag()) + .isAlreadyRequest(isAlreadyRequest) + .build(); + } } diff --git a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java index 4a6cb68..0d64ba3 100644 --- a/src/main/java/com/_119/wepro/project/presentation/ProjectController.java +++ b/src/main/java/com/_119/wepro/project/presentation/ProjectController.java @@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import java.util.List; import lombok.RequiredArgsConstructor; @@ -203,8 +204,33 @@ public ResponseEntity addMember( return ResponseEntity.ok(null); } - @Operation(summary = "리뷰 요청할 때 프로젝트 멤버 조회", description = "리뷰 요청 가능 여부를 포함하여 프로젝트 멤버 정보를 조회합니다.") @GetMapping("/members/request/review/{reviewFormId}") + @Operation(summary = "리뷰 요청할 때 프로젝트 멤버 조회", description = "리뷰 요청 가능 여부를 포함하여 프로젝트 멤버 정보를 조회합니다.") + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content( + mediaType = "application/json", + examples = @ExampleObject( + value = "[\n" + + " {\n" + + " \"id\": 1,\n" + + " \"profileUrl\": \"https://img1.kakaocdn.net/thumb/R110x110.q70/?fname=https://t1.kakaocdn.net/account_images/default_profile.jpeg\",\n" + + " \"name\": \"김희진\",\n" + + " \"tag\": \"1\",\n" + + " \"alreadyRequest\": true\n" + + " },\n" + + " {\n" + + " \"id\": 2,\n" + + " \"profileUrl\": null,\n" + + " \"name\": \"테스트1\",\n" + + " \"tag\": \"2\",\n" + + " \"alreadyRequest\": false\n" + + " }\n" + + "]" + ) + ) + ) public ResponseEntity> getProjectMembersWithRequestStatus( @PathVariable("reviewFormId") Long reviewFormId) { securityUtil.getCurrentMemberId(); diff --git a/src/main/java/com/_119/wepro/project/service/ProjectService.java b/src/main/java/com/_119/wepro/project/service/ProjectService.java index 54276b2..66308c6 100644 --- a/src/main/java/com/_119/wepro/project/service/ProjectService.java +++ b/src/main/java/com/_119/wepro/project/service/ProjectService.java @@ -32,134 +32,134 @@ @RequiredArgsConstructor public class ProjectService { - private final ProjectRepository projectRepository; - private final ProjectMemberRepository projectMemberRepository; - private final ProjectMemberCustomRepository projectMemberCustomRepository; - private final MemberRepository memberRepository; - private final ProjectCustomRepository projectCustomRepository; - private final ReviewFormRepository reviewFormRepository; + private final ProjectRepository projectRepository; + private final ProjectMemberRepository projectMemberRepository; + private final ProjectMemberCustomRepository projectMemberCustomRepository; + private final MemberRepository memberRepository; + private final ProjectCustomRepository projectCustomRepository; + private final ReviewFormRepository reviewFormRepository; - public List searchProjects(String keyword) { - List result = projectCustomRepository.searchProjects(keyword); + public List searchProjects(String keyword) { + List result = projectCustomRepository.searchProjects(keyword); - return result.stream().map(ProjectListResponse::of).toList(); - } - - public List getMyProjects(Long id) { + return result.stream().map(ProjectListResponse::of).toList(); + } - return projectCustomRepository.getMyProjects(id); - } + public List getMyProjects(Long id) { - public ProjectDetailResponse getProjectDetail(Long projectId) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + return projectCustomRepository.getMyProjects(id); + } - return ProjectDetailResponse.of(project); - } + public ProjectDetailResponse getProjectDetail(Long projectId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - @Transactional - public Long createProject(ProjectCreateRequest projectCreateRequest, Long projectCreatorId) { - Project newProject = Project.of(projectCreateRequest); + return ProjectDetailResponse.of(project); + } - // 팀원 멤버 역할로 등록 - for (Long memberId : projectCreateRequest.getMemberList()) { - registerProjectMember(newProject, memberId, MEMBER.name()); - } + @Transactional + public Long createProject(ProjectCreateRequest projectCreateRequest, Long projectCreatorId) { + Project newProject = Project.of(projectCreateRequest); - // 팀장 등록 - registerProjectMember(newProject, projectCreatorId, TEAM_LEADER.name()); + // 팀원 멤버 역할로 등록 + for (Long memberId : projectCreateRequest.getMemberList()) { + registerProjectMember(newProject, memberId, MEMBER.name()); + } - newProject.setImageList( - projectCreateRequest.getImgUrls().stream() - .map(imgUrl -> Image.of(imgUrl, newProject)) - .collect(Collectors.toList()) - ); + // 팀장 등록 + registerProjectMember(newProject, projectCreatorId, TEAM_LEADER.name()); - return projectRepository.save(newProject).getId(); - } + newProject.setImageList( + projectCreateRequest.getImgUrls().stream() + .map(imgUrl -> Image.of(imgUrl, newProject)) + .collect(Collectors.toList()) + ); - @Transactional - public Long updateProject(Long projectId, ProjectUpdateRequest projectUpdateRequest) { - Project project = projectRepository.findById(projectId) - .orElseThrow( - () -> new IllegalArgumentException("Project not found with id: " + projectId)); + return projectRepository.save(newProject).getId(); + } - Project updatedProject = Project.of(projectUpdateRequest); + @Transactional + public Long updateProject(Long projectId, ProjectUpdateRequest projectUpdateRequest) { + Project project = projectRepository.findById(projectId) + .orElseThrow( + () -> new IllegalArgumentException("Project not found with id: " + projectId)); - updatedProject.setImageList(projectUpdateRequest.getImgUrls().stream() - .map(imgUrl -> Image.of(imgUrl, project)) - .collect(Collectors.toList())); + Project updatedProject = Project.of(projectUpdateRequest); - // 기존 팀원 정보 삭제 후 새로 업데이트된 팀원 추가 - projectMemberRepository.deleteByProjectId(projectId); + updatedProject.setImageList(projectUpdateRequest.getImgUrls().stream() + .map(imgUrl -> Image.of(imgUrl, project)) + .collect(Collectors.toList())); - for (Long memberId : projectUpdateRequest.getMemberList()) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new IllegalArgumentException("Invalid member ID: " + memberId)); + // 기존 팀원 정보 삭제 후 새로 업데이트된 팀원 추가 + projectMemberRepository.deleteByProjectId(projectId); - ProjectMember projectMember = ProjectMember.builder() - .project(project) - .member(member) - .role(MEMBER) - .build(); + for (Long memberId : projectUpdateRequest.getMemberList()) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("Invalid member ID: " + memberId)); - projectMemberRepository.save(projectMember); - } + ProjectMember projectMember = ProjectMember.builder() + .project(project) + .member(member) + .role(MEMBER) + .build(); - return projectRepository.save(project).getId(); + projectMemberRepository.save(projectMember); } - private void registerProjectMember(Project project, Long memberId, String role) { - // findById를 사용하여 실제 member가 존재하는지 확인 - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new RestApiException(PROJECT_MEMBER_NOT_FOUND)); + return projectRepository.save(project).getId(); + } - ProjectMember projectMember = ProjectMember.of(project, member, role); + private void registerProjectMember(Project project, Long memberId, String role) { + // findById를 사용하여 실제 member가 존재하는지 확인 + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new RestApiException(PROJECT_MEMBER_NOT_FOUND)); - project.getProjectMembers().add(projectMember); - project.setMemberNum(project.getMemberNum() + 1); - } + ProjectMember projectMember = ProjectMember.of(project, member, role); + project.getProjectMembers().add(projectMember); + project.setMemberNum(project.getMemberNum() + 1); + } - public Long deleteProject(Long projectId) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new RestApiException( - RESOURCE_NOT_FOUND)); - projectRepository.delete(project); - return project.getId(); - } + public Long deleteProject(Long projectId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException( + RESOURCE_NOT_FOUND)); + projectRepository.delete(project); + + return project.getId(); + } - @Transactional - public void addProjectMember(Long projectId, Long userId) { - Project project = projectRepository.findById(projectId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + @Transactional + public void addProjectMember(Long projectId, Long userId) { + Project project = projectRepository.findById(projectId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - //todo : 탈퇴한 멤버 제외 - Member member = memberRepository.findById(userId) - .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); + //todo : 탈퇴한 멤버 제외 + Member member = memberRepository.findById(userId) + .orElseThrow(() -> new RestApiException(RESOURCE_NOT_FOUND)); - // 기존에 해당 프로젝트와 멤버 조합이 있는지 확인합니다. - boolean exists = projectMemberCustomRepository.existsByProjectAndMember(project, member); - if (exists) { - throw new IllegalArgumentException("This member is already part of the project."); - } + // 기존에 해당 프로젝트와 멤버 조합이 있는지 확인합니다. + boolean exists = projectMemberCustomRepository.existsByProjectAndMember(project, member); + if (exists) { + throw new IllegalArgumentException("This member is already part of the project."); + } - ProjectMember projectMember = ProjectMember.builder() - .project(project) - .member(member) - .role(MEMBER) - .build(); + ProjectMember projectMember = ProjectMember.builder() + .project(project) + .member(member) + .role(MEMBER) + .build(); - projectMemberRepository.save(projectMember); + projectMemberRepository.save(projectMember); - project.setMemberNum(project.getMemberNum() + 1); - projectRepository.save(project); - } + project.setMemberNum(project.getMemberNum() + 1); + projectRepository.save(project); + } - public List getProjectMembersWithRequestStatus(Long reviewFormId) { + public List getProjectMembersWithRequestStatus(Long reviewFormId) { - reviewFormRepository.findByIdOrThrow(reviewFormId); - return projectMemberCustomRepository.getProjectMembersWithReviewRequestStatus(reviewFormId); - } + reviewFormRepository.findByIdOrThrow(reviewFormId); + return projectMemberCustomRepository.getProjectMembersWithReviewRequestStatus(reviewFormId); + } } \ No newline at end of file diff --git a/src/main/java/com/_119/wepro/review/presentation/QuestionController.java b/src/main/java/com/_119/wepro/review/presentation/QuestionController.java index 99495ce..f29969c 100644 --- a/src/main/java/com/_119/wepro/review/presentation/QuestionController.java +++ b/src/main/java/com/_119/wepro/review/presentation/QuestionController.java @@ -5,6 +5,9 @@ import com._119.wepro.review.dto.response.QuestionResponse.QuestionInReviewFormGetResponse; import com._119.wepro.review.service.QuestionService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -21,15 +24,142 @@ public class QuestionController { private final QuestionService questionService; - @Operation(summary = "카테고리에 해당하는 질문들 반환 API") @GetMapping("/categories") + @Operation(summary = "카테고리에 해당하는 질문들 반환", description = "리뷰 폼을 생성할 때, 선택된 카테고리에 해당하는 질문들을 반환합니다") + @ApiResponse( + responseCode = "200", + description = "성공", + content = @Content( + mediaType = "application/json", + examples = @ExampleObject( + value = "{\n" + + " \"allQuestions\": [\n" + + " {\n" + + " \"categoryType\": \"COMMUNICATION\",\n" + + " \"questions\": [\n" + + " {\n" + + " \"questionId\": 1,\n" + + " \"question\": \"${username}님은 팀 회의에서 의견을 제시할 때, 어떻게 소통하셨나요?\",\n" + + + " \"options\": [\n" + + " {\n" + + " \"content\": \"자신의 의견을 명확히 표현하고 다른 팀원들의 반응을 잘 경청하였다.\"\n" + + + " },\n" + + " {\n" + + " \"content\": \"의견을 제시했으나, 다른 팀원들의 의견을 충분히 반영하지 못하였다.\"\n" + + + " }\n" + + " ]\n" + + " },\n" + + " {\n" + + " \"questionId\": 2,\n" + + " \"question\": \"${username}님이 팀 내 갈등 상황에서 대화를 중재할 때, 어떤 방식으로 접근하였나요?\",\n" + + + " \"options\": [\n" + + " {\n" + + " \"content\": \"양측의 의견을 경청하고 공정하게 갈등을 중재하였다.\"\n" + + " },\n" + + " {\n" + + " \"content\": \"중재를 시도했으나 대화가 제대로 이루어지지 않았다.\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " {\n" + + " \"categoryType\": \"FOLLOWERSHIP\",\n" + + " \"questions\": [\n" + + " {\n" + + " \"questionId\": 32,\n" + + " \"question\": \"${username}님은 업무를 맡았을 때 끝까지 책임감 있게 수행하셨나요?\",\n" + + + " \"options\": [\n" + + " {\n" + + " \"content\": \"항상 맡은 업무를 끝까지 책임감 있게 수행하며, 완성도를 높였다.\"\n" + + + " },\n" + + " {\n" + + " \"content\": \"대부분의 경우 책임감 있게 업무를 수행하며, 결과를 잘 마무리했다.\"\n" + + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}" + ) + ) + ) public ResponseEntity getQuestionsInCategories( @RequestParam List categoryTypes) { return ResponseEntity.ok(questionService.getQuestionsInCategories(categoryTypes)); } - @Operation(summary = "리뷰폼에 해당하는 질문들 반환 API") @GetMapping("/reviewform/{id}") + @Operation(summary = "리뷰폼에 해당하는 질문들 반환", description = "리뷰를 시작할 때, 리뷰 폼에 해당하는 질문들을 반환합니다") + @ApiResponse( + responseCode = "200", + description = "username: 리뷰를 받는 사람의 이름, 답변 데이터가 존재할 경우 answerOptionId(객관식)과 answer(주관식)을 함께 반환합니다.", + content = @Content( + mediaType = "application/json", + examples = @ExampleObject( + value = "{\n" + + " \"username\": \"김희진\",\n" + + " \"choiceQuestions\": [\n" + + " {\n" + + " \"categoryType\": \"COMMUNICATION\",\n" + + " \"questions\": [\n" + + " {\n" + + " \"questionId\": 1,\n" + + " \"question\": \"${username}님은 팀 회의에서 의견을 제시할 때, 어떻게 소통하셨나요?\",\n" + + + " \"options\": [\n" + + " {\n" + + " \"optionId\": 1,\n" + + " \"content\": \"자신의 의견을 명확히 표현하고 다른 팀원들의 반응을 잘 경청하였다.\"\n" + + + " },\n" + + " {\n" + + " \"optionId\": 2,\n" + + " \"content\": \"의견을 제시했으나, 다른 팀원들의 의견을 충분히 반영하지 못하였다.\"\n" + + + " }\n" + + " ],\n" + + " \"answerOptionId\": 2\n" + + " },\n" + + " {\n" + + " \"questionId\": 3,\n" + + " \"question\": \"${username}님이 팀 회의에서 다른 팀원의 의견을 어떻게 대하였나요?\",\n" + + + " \"options\": [\n" + + " {\n" + + " \"optionId\": 9,\n" + + " \"content\": \"다른 팀원의 의견을 경청하고 존중하며, 적극적으로 피드백을 제공하였다.\"\n" + + + " },\n" + + " {\n" + + " \"optionId\": 10,\n" + + " \"content\": \"다른 팀원의 의견을 경청하였으나, 소극적으로 피드백을 제공하였다.\"\n" + + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"subQuestions\": [\n" + + " {\n" + + " \"questionId\": 1,\n" + + " \"content\": \"그만(Stop)했으면 하는 점은 무엇인가요?\",\n" + + " \"answer\": \"없어요\"\n" + + " }\n" + + " ]\n" + + "}" + ) + ) + ) public ResponseEntity getQuestionsInReviewForm( @PathVariable("id") Long reviewFormId) { return ResponseEntity.ok(questionService.getQuestionsInReviewForm(reviewFormId)); diff --git a/src/main/java/com/_119/wepro/review/presentation/ReviewController.java b/src/main/java/com/_119/wepro/review/presentation/ReviewController.java index 1100bcd..e2ff19c 100644 --- a/src/main/java/com/_119/wepro/review/presentation/ReviewController.java +++ b/src/main/java/com/_119/wepro/review/presentation/ReviewController.java @@ -7,6 +7,9 @@ import com._119.wepro.review.dto.response.ReviewResponse.ReviewFormCreateResponse; import com._119.wepro.review.service.ReviewService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -24,24 +27,44 @@ public class ReviewController { private final ReviewService reviewService; private final SecurityUtil securityUtil; - @Operation(summary = "리뷰 폼 생성 API") @PostMapping("/form") + @Operation(summary = "리뷰 폼 생성하기", description = "해당 프로젝트에 대한 리뷰 폼을 생성합니다") + @ApiResponse( + responseCode = "200", + description = "생성된 리뷰 폼 아이디를 반환합니다", + content = @Content( + mediaType = "application/json", + examples = @ExampleObject( + value = "{\n" + + " \"reviewFormId\": 1\n" + + "}" + ) + ) + ) public ResponseEntity createReviewForm( @RequestBody @Valid ReviewFormCreateRequest request) { Long memberId = securityUtil.getCurrentMemberId(); return ResponseEntity.ok(reviewService.createReviewForm(request, memberId)); } - @Operation(summary = "리뷰 요청하기 API") @PostMapping("/request") + @Operation(summary = "리뷰 요청하기", description = "특정 멤버에게 리뷰 요청 알림을 전송합니다") + @ApiResponse( + responseCode = "200", + description = "성공" + ) public ResponseEntity requestReview(@RequestBody @Valid ReviewAskRequest request) { Long memberId = securityUtil.getCurrentMemberId(); reviewService.requestReview(request, memberId); return ResponseEntity.ok().build(); } - @Operation(summary = "리뷰 임시저장 API") @PostMapping("/draft/{reviewFormId}") + @Operation(summary = "리뷰 임시저장", description = "진행 중인 리뷰의 응답 데이터를 임시저장합니다") + @ApiResponse( + responseCode = "200", + description = "성공" + ) public ResponseEntity draftReview(@PathVariable(name = "reviewFormId") Long reviewFormId, @RequestBody @Valid ReviewSaveRequest request) { Long memberId = securityUtil.getCurrentMemberId(); @@ -49,8 +72,12 @@ public ResponseEntity draftReview(@PathVariable(name = "reviewFormId") Lon return ResponseEntity.ok().build(); } - @Operation(summary = "리뷰 제출하기 API") @PostMapping("/{reviewFormId}") + @Operation(summary = "리뷰 제출하기", description = "진행 중인 리뷰가 완료되어 최종 제출합니다.") + @ApiResponse( + responseCode = "200", + description = "성공" + ) public ResponseEntity submitReview(@PathVariable(name = "reviewFormId") Long reviewFormId, @RequestBody @Valid ReviewSaveRequest request) { Long memberId = securityUtil.getCurrentMemberId();