-
Notifications
You must be signed in to change notification settings - Fork 2
feat : 가입 요청 생성 및 조회 승인 및 거절 #399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
5138ed2
4fda339
746e13c
cc53a7a
f5f6081
bd57fc2
751ccf9
98cff16
92e0db0
1d80555
4534414
30f42e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,9 @@ | |
| import com.gamzabat.algohub.feature.group.studygroup.dto.GroupRoleResponse; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.UpdateBookmarkResponse; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.UpdateGroupMemberRoleRequest; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.UpdateJoinRequestStatusRequest; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.JoinRequestException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.service.JoinRequestService; | ||
| import com.gamzabat.algohub.feature.group.studygroup.service.StudyGroupService; | ||
| import com.gamzabat.algohub.feature.user.domain.User; | ||
|
|
||
|
|
@@ -51,6 +54,7 @@ | |
| @Tag(name = "그룹 API", description = "스터디 그룹 관련 API") | ||
| public class StudyGroupController { | ||
| private final StudyGroupService studyGroupService; | ||
| private final JoinRequestService joinRequestService; | ||
|
|
||
| @PostMapping(value = "/groups", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) | ||
| @Operation(summary = "그룹 생성 API") | ||
|
|
@@ -208,34 +212,31 @@ public ResponseEntity<Page<GetGroupResponse>> getSearchedGroupList(@RequestParam | |
| return ResponseEntity.ok().body(responses); | ||
| } | ||
|
|
||
| @PostMapping(value = "/{groupId}/join-request") | ||
| @PostMapping(value = "/groups/{groupId}/join-request") | ||
| @Operation(summary = "그룹 가입 요청 API", description = "스터디 그룹에 가입 요청을 보내는 API") | ||
| public ResponseEntity<Void> joinRequest(@AuthedUser User user, @PathVariable Long groupId) { | ||
| studyGroupService.joinRequest(user, groupId); | ||
| joinRequestService.joinRequest(user, groupId); | ||
| return ResponseEntity.ok().build(); | ||
| } | ||
|
|
||
| @GetMapping(value = "/{groupId}/join-request") | ||
| @GetMapping(value = "/groups/{groupId}/join-request") | ||
| @Operation(summary = "그룹 가입 요청 목록 조회 API", description = "스터디 그룹 가입 요청 목록을 조회하는 API") | ||
| public ResponseEntity<List<JoinRequest>> getAllJoinRequests(@AuthedUser User user, @PathVariable Long groupId) { | ||
| List<JoinRequest> response = studyGroupService.getAllJoinRequests(user, groupId); | ||
| List<JoinRequest> response = joinRequestService.getAllJoinRequests(user, groupId); | ||
|
|
||
| return ResponseEntity.ok().body(response); | ||
| } | ||
|
|
||
| @PostMapping(value = "/{groupId}/{requestId}/approve") | ||
| @Operation(summary = "그룹 가입 요청 승인 API", description = "스터디 그룹 가입 요청을 승인하는 API") | ||
| public ResponseEntity<Void> approveRequest(@AuthedUser User user, @PathVariable Long requestId, | ||
| @PathVariable Long groupId) { | ||
| studyGroupService.approveJoinRequest(user, requestId, groupId); | ||
| return ResponseEntity.ok().build(); | ||
| } | ||
|
|
||
| @PostMapping(value = "/{groupId}/{requestId}/reject") | ||
| @Operation(summary = "그룹 가입 요청 거절 API", description = "스터디 그룹 가입 요청을 거절하는 API") | ||
| public ResponseEntity<Void> rejectRequest(@AuthedUser User user, @PathVariable Long requestId, | ||
| @PathVariable Long groupId) { | ||
| studyGroupService.rejectJoinRequest(user, requestId, groupId); | ||
| @PostMapping(value = "/groups/{groupId}/join-request/{requestId}") | ||
|
||
| @Operation(summary = "그룹 가입 요청 승인 / 거절", description = "스터디 그룹 가입 요청을 승인 / 거절하는 API") | ||
| public ResponseEntity<Void> updateRequest( | ||
| @AuthedUser User user, | ||
| @PathVariable Long requestId, | ||
| @PathVariable Long groupId, | ||
| @RequestBody @Valid UpdateJoinRequestStatusRequest request, Errors errors) { | ||
| if (errors.hasErrors()) | ||
| throw new JoinRequestException("가입 요청이 올바르지 않습니다."); | ||
| joinRequestService.updateJoinRequest(user, requestId, groupId, request); | ||
| return ResponseEntity.ok().build(); | ||
| } | ||
|
|
||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.gamzabat.algohub.feature.group.studygroup.dto; | ||
|
|
||
| import com.gamzabat.algohub.enums.JoinRequestStatus; | ||
|
|
||
| import jakarta.validation.constraints.NotNull; | ||
|
|
||
| public record UpdateJoinRequestStatusRequest(@NotNull(message = "status 는 필수입니다.") JoinRequestStatus status) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| package com.gamzabat.algohub.feature.group.studygroup.service; | ||
|
|
||
| import java.time.LocalDate; | ||
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import com.gamzabat.algohub.enums.JoinRequestStatus; | ||
| import com.gamzabat.algohub.exception.StudyGroupValidationException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.GroupMember; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.JoinRequest; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.StudyGroup; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.UpdateJoinRequestStatusRequest; | ||
| import com.gamzabat.algohub.feature.group.studygroup.etc.RoleOfGroupMember; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.GroupMemberValidationException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.JoinRequestException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.GroupMemberRepository; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.JoinRequestRepository; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.StudyGroupRepository; | ||
| import com.gamzabat.algohub.feature.user.domain.User; | ||
| import com.gamzabat.algohub.feature.user.repository.UserRepository; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| @Slf4j | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class JoinRequestService { | ||
| private final StudyGroupRepository studyGroupRepository; | ||
| private final GroupMemberRepository groupMemberRepository; | ||
| private final UserRepository userRepository; | ||
| private final JoinRequestRepository joinRequestRepository; | ||
|
|
||
| @Transactional | ||
| public void joinRequest(User user, Long groupId) { | ||
| StudyGroup studyGroup = studyGroupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹 입니다.")); | ||
| if (groupMemberRepository.existsByUserAndStudyGroup(user, studyGroup)) { | ||
| throw new GroupMemberValidationException(HttpStatus.BAD_REQUEST.value(), "이미 가입한 그룹입니다"); | ||
| } | ||
| if (joinRequestRepository.existsByGroup_IdAndRequester_Id(groupId, user.getId())) { | ||
| throw new JoinRequestException("이미 요청한 그룹입니다."); | ||
| } | ||
|
|
||
| JoinRequest request = new JoinRequest(studyGroup, user); | ||
| joinRequestRepository.save(request); | ||
| log.info("success to join request group = {}", groupId); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public List<JoinRequest> getAllJoinRequests(User user, Long groupId) { | ||
| StudyGroup studyGroup = studyGroupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹 입니다.")); | ||
| Optional<GroupMember> groupMember = groupMemberRepository.findByUserAndStudyGroup(user, studyGroup); | ||
| if (groupMember.isPresent() && RoleOfGroupMember.isParticipant(groupMember.get()) || groupMember.isEmpty()) { | ||
| throw new JoinRequestException("요청 목록을 조회할 권한이 없습니다."); | ||
| } | ||
| return joinRequestRepository.findAllByGroup_Id(groupId); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void updateJoinRequest(User user, Long requestId, Long groupId, UpdateJoinRequestStatusRequest request) { | ||
| JoinRequest joinRequest = joinRequestRepository.findById(requestId) | ||
| .orElseThrow(() -> new JoinRequestException("해당 요청이 존재하지 않습니다")); | ||
| StudyGroup studyGroup = studyGroupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹입니다.")); | ||
| GroupMember groupMember = groupMemberRepository.findByUserAndStudyGroup(user, studyGroup) | ||
| .orElseThrow(() -> new GroupMemberValidationException(HttpStatus.NOT_FOUND.value(), "해당 그룹의 멤버가 아닙니다.")); | ||
| if (RoleOfGroupMember.isParticipant(groupMember)) { | ||
| throw new JoinRequestException("승인 권한이 없습니다."); | ||
| } | ||
| if (request.status() == JoinRequestStatus.APPROVE) { | ||
| joinRequest.updateStatus(request.status()); | ||
| GroupMember newGroupMember = GroupMember.builder() | ||
| .user(joinRequest.getRequester()) | ||
| .studyGroup(studyGroup) | ||
| .joinDate(LocalDate.now()) | ||
| .role(RoleOfGroupMember.PARTICIPANT) | ||
| .build(); | ||
| groupMemberRepository.save(newGroupMember); | ||
| joinRequestRepository.delete(joinRequest); | ||
|
Comment on lines
+82
to
+104
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 가입 후 처리에 누락된 부분이 있습니다! 가입 처리 되면 |
||
| } else if (request.status() == JoinRequestStatus.REJECT) { | ||
| joinRequestRepository.delete(joinRequest); | ||
| } | ||
| log.info("success to approve/reject for join request group = {}", groupId); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,6 @@ | |
| import com.gamzabat.algohub.feature.group.ranking.repository.RankingRepository; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.BookmarkedStudyGroup; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.GroupMember; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.JoinRequest; | ||
| import com.gamzabat.algohub.feature.group.studygroup.domain.StudyGroup; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.BookmarkStatus; | ||
| import com.gamzabat.algohub.feature.group.studygroup.dto.CheckSolvedProblemResponse; | ||
|
|
@@ -51,7 +50,6 @@ | |
| import com.gamzabat.algohub.feature.group.studygroup.exception.CannotFoundProblemException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.CannotFoundUserException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.GroupMemberValidationException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.exception.JoinRequestException; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.BookmarkedStudyGroupRepository; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.GroupMemberRepository; | ||
| import com.gamzabat.algohub.feature.group.studygroup.repository.JoinRequestRepository; | ||
|
|
@@ -659,71 +657,4 @@ public Page<GetGroupResponse> getSearchedStudyGroupList(String searchPattern, Pa | |
| )); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void joinRequest(User user, Long groupId) { | ||
| StudyGroup studyGroup = groupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹 입니다.")); | ||
| if (groupMemberRepository.existsByUserAndStudyGroup(user, studyGroup)) { | ||
| throw new GroupMemberValidationException(HttpStatus.BAD_REQUEST.value(), "이미 가입한 그룹입니다"); | ||
| } | ||
| if (joinRequestRepository.existsByGroup_IdAndRequester_Id(groupId, user.getId())) { | ||
| throw new JoinRequestException("이미 요청한 그룹입니다."); | ||
| } | ||
|
|
||
| JoinRequest request = new JoinRequest(); | ||
| request.setRequester(user); | ||
| request.setGroup(studyGroup); | ||
| joinRequestRepository.save(request); | ||
| log.info("success to join request group = {}", groupId); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public List<JoinRequest> getAllJoinRequests(User user, Long groupId) { | ||
| StudyGroup studyGroup = groupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹 입니다.")); | ||
| Optional<GroupMember> groupMember = groupMemberRepository.findByUserAndStudyGroup(user, studyGroup); | ||
| if (groupMember.isPresent() && RoleOfGroupMember.isParticipant(groupMember.get()) || groupMember.isEmpty()) { | ||
| throw new JoinRequestException("요청 목록을 조회할 권한이 없습니다."); | ||
| } | ||
| return joinRequestRepository.findAllByGroup_Id(groupId); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void approveJoinRequest(User user, Long requestId, Long groupId) { | ||
| JoinRequest joinRequest = joinRequestRepository.findById(requestId) | ||
| .orElseThrow(() -> new JoinRequestException("해당 요청이 존재하지 않습니다")); | ||
| StudyGroup studyGroup = studyGroupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹입니다.")); | ||
| GroupMember groupMember = groupMemberRepository.findByUserAndStudyGroup(user, studyGroup) | ||
| .orElseThrow(() -> new GroupMemberValidationException(HttpStatus.NOT_FOUND.value(), "해당 그룹의 멤버가 아닙니다.")); | ||
| if (RoleOfGroupMember.isParticipant(groupMember)) { | ||
| throw new JoinRequestException("승인 권한이 없습니다."); | ||
| } | ||
| joinRequest.approve(); | ||
| GroupMember newGroupMember = GroupMember.builder() | ||
| .user(joinRequest.getRequester()) | ||
| .studyGroup(studyGroup) | ||
| .joinDate(LocalDate.now()) | ||
| .role(RoleOfGroupMember.PARTICIPANT) | ||
| .build(); | ||
| groupMemberRepository.save(newGroupMember); | ||
| joinRequestRepository.delete(joinRequest); | ||
| log.info("success to approve join request group = {}", groupId); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void rejectJoinRequest(User user, Long requestId, Long groupId) { | ||
| JoinRequest joinRequest = joinRequestRepository.findById(requestId) | ||
| .orElseThrow(() -> new JoinRequestException("해당 요청이 존재하지 않습니다")); | ||
| StudyGroup studyGroup = studyGroupRepository.findById(groupId) | ||
| .orElseThrow(() -> new StudyGroupValidationException(HttpStatus.NOT_FOUND.value(), "존재하지 않는 그룹입니다.")); | ||
| GroupMember groupMember = groupMemberRepository.findByUserAndStudyGroup(user, studyGroup) | ||
| .orElseThrow(() -> new GroupMemberValidationException(HttpStatus.NOT_FOUND.value(), "해당 그룹의 멤버가 아닙니다.")); | ||
| if (RoleOfGroupMember.isParticipant(groupMember)) { | ||
| throw new JoinRequestException("승인 권한이 없습니다."); | ||
| } | ||
| joinRequestRepository.delete(joinRequest); | ||
| log.info("success to reject join request group = {} and delete request = {} ", groupId, requestId); | ||
|
|
||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Approve와 reject를 하나로 묶으려면 isApproved 필드를 하나 더 받아서 처리하면 되지 않을까 싶네요! reject를 만들지 말지 프론트랑 결정해서 하면 될거같아요 |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로
JoinRequestController가 따로 쪼개져도 괜찮을 것 같다고 생각합니다!사유는.. service 분리 요청 이유와 같습니다.. 너무 커지는 이유..