From d9b7b8fc0ca30313f9de04326fef3055dd87c2e8 Mon Sep 17 00:00:00 2001 From: Jin Hyuk Date: Fri, 22 Nov 2024 00:22:08 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=9E=90=20?= =?UTF-8?q?=EB=A7=A4=EC=B9=AD=20=EC=B7=A8=EC=86=8C=20-=20=EB=A7=A4?= =?UTF-8?q?=EC=B9=AD=EC=9D=B4=20=ED=99=95=EC=A0=95=EB=90=98=EB=A9=B4=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=EC=9E=90=20=EB=A7=A4=EC=B9=AD=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=EA=B0=80=20=EB=B6=88=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ParticipantController.java | 15 ++++--- .../dangu/participant/domain/Participant.java | 4 +- .../domain/ParticipantRepository.java | 6 ++- .../UpdateParticipantMatchRequest.java | 3 ++ .../exception/AlreadyMatchedException.java | 11 +++++ .../exception/ParticipantError.java | 4 +- .../service/ParticipantService.java | 44 ++++++++++++------- 7 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/hyunsolution/dangu/participant/dto/request/UpdateParticipantMatchRequest.java create mode 100644 src/main/java/com/hyunsolution/dangu/participant/exception/AlreadyMatchedException.java diff --git a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java index c0020b0..55a14b1 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java +++ b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java @@ -2,16 +2,15 @@ import com.hyunsolution.dangu.common.apiResponse.ApiResponse; import com.hyunsolution.dangu.participant.domain.ParticipantRepository; +import com.hyunsolution.dangu.participant.dto.request.UpdateParticipantMatchRequest; import com.hyunsolution.dangu.participant.dto.response.EnterChatRoomResponse; import com.hyunsolution.dangu.participant.service.ParticipantService; import com.hyunsolution.dangu.user.domain.UserRepository; import com.hyunsolution.dangu.workspace.domain.WorkspaceRepository; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RestController @@ -23,13 +22,15 @@ public class ParticipantController { private final ParticipantService participantService; // 사용자 매칭 버튼 클릭 - @PostMapping("/participant/matching/{roomNumber}") + @PostMapping("/participant/matching/{chatRoomId}") + @Operation(summary = "참가자 매칭 수락/거절", description = "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)") public ApiResponse matching( @Parameter(hidden = true) @RequestHeader("Authorization") Long id, - @PathVariable("roomNumber") Long workspaceId) { + @PathVariable("chatRoomId") Long chatRoomId, + @RequestBody UpdateParticipantMatchRequest request) { // 매칭확인버튼 누른 사용자 매칭칼럼 상태 변경 - participantService.changeMatching(id, workspaceId); + participantService.updateMatching(id, chatRoomId, request); return ApiResponse.success(null); } diff --git a/src/main/java/com/hyunsolution/dangu/participant/domain/Participant.java b/src/main/java/com/hyunsolution/dangu/participant/domain/Participant.java index b21e3b5..0db5b58 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/domain/Participant.java +++ b/src/main/java/com/hyunsolution/dangu/participant/domain/Participant.java @@ -42,7 +42,7 @@ private Participant(User user, Workspace workspace, boolean participantMatch) { this.participantMatch = participantMatch; } - public void accept() { - this.participantMatch = true; + public void updateParticipantMatch(boolean isMatch) { + this.participantMatch = isMatch; } } diff --git a/src/main/java/com/hyunsolution/dangu/participant/domain/ParticipantRepository.java b/src/main/java/com/hyunsolution/dangu/participant/domain/ParticipantRepository.java index 3f8256c..24eb28c 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/domain/ParticipantRepository.java +++ b/src/main/java/com/hyunsolution/dangu/participant/domain/ParticipantRepository.java @@ -13,12 +13,14 @@ public interface ParticipantRepository extends JpaRepository List findParticipantIdByWorkspaceId(Long workspaceId); // ID별 매칭버튼 클릭 여부 - Boolean existsByIdAndParticipantMatchTrue(long id); + @Query( + "select count(p) > 0 from Participant p where p.id in :ids and p.participantMatch = true") + Boolean existsByIdAndParticipantMatchTrue(List ids); // 개인 ID 찾기 @Query( value = - "SELECT p from Participant p join p.workspace w where p.user.id =:id and p.workspace.id=:workspaceId") + "SELECT p from Participant p join fetch p.workspace w where p.user.id =:id and p.workspace.id=:workspaceId") Optional findByUserIdAndWorkspaceId( @Param("id") Long id, @Param("workspaceId") Long workspaceId); diff --git a/src/main/java/com/hyunsolution/dangu/participant/dto/request/UpdateParticipantMatchRequest.java b/src/main/java/com/hyunsolution/dangu/participant/dto/request/UpdateParticipantMatchRequest.java new file mode 100644 index 0000000..0617891 --- /dev/null +++ b/src/main/java/com/hyunsolution/dangu/participant/dto/request/UpdateParticipantMatchRequest.java @@ -0,0 +1,3 @@ +package com.hyunsolution.dangu.participant.dto.request; + +public record UpdateParticipantMatchRequest(boolean isMatch) {} diff --git a/src/main/java/com/hyunsolution/dangu/participant/exception/AlreadyMatchedException.java b/src/main/java/com/hyunsolution/dangu/participant/exception/AlreadyMatchedException.java new file mode 100644 index 0000000..ffb344c --- /dev/null +++ b/src/main/java/com/hyunsolution/dangu/participant/exception/AlreadyMatchedException.java @@ -0,0 +1,11 @@ +package com.hyunsolution.dangu.participant.exception; + +import com.hyunsolution.dangu.common.exception.CustomException; + +public class AlreadyMatchedException extends CustomException { + public static final AlreadyMatchedException EXCEPTION = new AlreadyMatchedException(); + + private AlreadyMatchedException() { + super(ParticipantError.ALREADY_MATCHED); + } +} diff --git a/src/main/java/com/hyunsolution/dangu/participant/exception/ParticipantError.java b/src/main/java/com/hyunsolution/dangu/participant/exception/ParticipantError.java index 58605a2..6509480 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/exception/ParticipantError.java +++ b/src/main/java/com/hyunsolution/dangu/participant/exception/ParticipantError.java @@ -9,7 +9,9 @@ @Getter @AllArgsConstructor public enum ParticipantError implements BaseErrorCode { - PARTICIPANT_NOT_FOUND("PARTICIPANT_400_1", HttpStatus.BAD_REQUEST, "해당 채팅방 참여자를 찾을 수 없습니다."); + PARTICIPANT_NOT_FOUND("PARTICIPANT_400_1", HttpStatus.BAD_REQUEST, "해당 채팅방 참여자를 찾을 수 없습니다."), + ALREADY_MATCHED("PARTICIPANT_400_2", HttpStatus.BAD_REQUEST, "이미 매칭된 경우 수락/거절이 불가능합니다."), + ; private final String code; private final HttpStatus httpStatus; diff --git a/src/main/java/com/hyunsolution/dangu/participant/service/ParticipantService.java b/src/main/java/com/hyunsolution/dangu/participant/service/ParticipantService.java index f538d30..0227b2d 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/service/ParticipantService.java +++ b/src/main/java/com/hyunsolution/dangu/participant/service/ParticipantService.java @@ -2,7 +2,9 @@ import com.hyunsolution.dangu.participant.domain.Participant; import com.hyunsolution.dangu.participant.domain.ParticipantRepository; +import com.hyunsolution.dangu.participant.dto.request.UpdateParticipantMatchRequest; import com.hyunsolution.dangu.participant.dto.response.EnterChatRoomResponse; +import com.hyunsolution.dangu.participant.exception.AlreadyMatchedException; import com.hyunsolution.dangu.participant.exception.ParticipantNotFoundException; import com.hyunsolution.dangu.user.domain.User; import com.hyunsolution.dangu.user.domain.UserRepository; @@ -22,33 +24,41 @@ public class ParticipantService { private final WorkspaceRepository workspaceRepository; @Transactional - public void changeMatching(Long id, Long workspaceId) { - // 상태 변경 - Participant participantOptional = + public void updateMatching(Long id, Long chatRoomId, UpdateParticipantMatchRequest request) { + // 1. 참가자 조회 + Participant participant = participantRepository - .findByUserIdAndWorkspaceId(id, workspaceId) + .findByUserIdAndWorkspaceId(id, chatRoomId) .orElseThrow(() -> ParticipantNotFoundException.EXCEPTION); - participantOptional.accept(); + // 2. 이미 매칭된 상태인지 확인 + if (participant.getWorkspace().isMatched()) { + throw AlreadyMatchedException.EXCEPTION; + } + + // 3. 참가자의 매칭 상태 업데이트 + participant.updateParticipantMatch(request.isMatch()); - // participant테이블에서 roomNumber로 들어온 숫자를 통해 누가 있는지 파악 + // 4. 매칭 요청 처리 + if (request.isMatch() && allParticipantsMatched(chatRoomId)) { + finalizeWorkspaceMatching(chatRoomId); + } + } + + // 모든 참가자가 매칭되었는지 확인 + private boolean allParticipantsMatched(Long workspaceId) { List participantIds = participantRepository.findParticipantIdByWorkspaceId(workspaceId); + return participantRepository.existsByIdAndParticipantMatchTrue(participantIds); + } - // 방안에 모든 참가자가 "확정"버튼을 눌렀는지 확인 - for (Long participant : participantIds) { - boolean mathingCheck = - participantRepository.existsByIdAndParticipantMatchTrue(participant); - if (!mathingCheck) { - return; - } - } - // 게임방 테이블 속 매칭 결과를 true로 바꿈 - Workspace workspace1 = + // 워크스페이스의 매칭을 최종 확정 + private void finalizeWorkspaceMatching(Long workspaceId) { + Workspace workspace = workspaceRepository .findById(workspaceId) .orElseThrow(() -> WorkspaceNotFoundException.EXCEPTION); - workspace1.acceptFinal(); + workspace.acceptFinal(); } // 채팅방 입장 메시지 전송 From 3cce5a89589963c192a32addf86fa304993bd95d Mon Sep 17 00:00:00 2001 From: Jin Hyuk Date: Fri, 22 Nov 2024 00:23:03 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=EC=B1=84=ED=8C=85=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=BF=BC=EB=A6=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dangu/workspace/domain/WorkspaceRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hyunsolution/dangu/workspace/domain/WorkspaceRepository.java b/src/main/java/com/hyunsolution/dangu/workspace/domain/WorkspaceRepository.java index bbc1533..0b00786 100644 --- a/src/main/java/com/hyunsolution/dangu/workspace/domain/WorkspaceRepository.java +++ b/src/main/java/com/hyunsolution/dangu/workspace/domain/WorkspaceRepository.java @@ -8,6 +8,6 @@ public interface WorkspaceRepository extends JpaRepository { @EntityGraph(attributePaths = {"participants"}) @Query( - "select w from Workspace w where exists (select 1 from Participant p where p.workspace = w and p.user.id = :userId) and w.chatUpdateAt is not null") + "select w from Workspace w where exists (select 1 from Participant p where p.workspace = w and p.user.id = :userId)") List findByParticipantUserId(Long userId); } From 7c436ba5996840c55d638e47dc9c12864fbc9a56 Mon Sep 17 00:00:00 2001 From: Jin Hyuk Date: Fri, 22 Nov 2024 00:26:21 +0900 Subject: [PATCH 3/5] =?UTF-8?q?docs:=20Swagger=20Operation=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dangu/participant/controller/ParticipantController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java index 55a14b1..516f2b9 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java +++ b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java @@ -23,7 +23,8 @@ public class ParticipantController { // 사용자 매칭 버튼 클릭 @PostMapping("/participant/matching/{chatRoomId}") - @Operation(summary = "참가자 매칭 수락/거절", description = "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)") + @Operation(summary = "참가자 매칭 수락/거절", description = "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)" + + "workspace의 매칭이 확정된 경우 참여자는 매칭 거절을 할 수 없다.") public ApiResponse matching( @Parameter(hidden = true) @RequestHeader("Authorization") Long id, @PathVariable("chatRoomId") Long chatRoomId, From 9ad617b979e4fb312cd72f88310eb2369205cb1d Mon Sep 17 00:00:00 2001 From: Jin Hyuk Date: Fri, 22 Nov 2024 00:26:48 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20ApiResponse=20=EC=99=80=EC=9D=BC?= =?UTF-8?q?=EB=93=9C=EC=B9=B4=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dangu/participant/controller/ParticipantController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java index 516f2b9..7ab749d 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java +++ b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java @@ -25,7 +25,7 @@ public class ParticipantController { @PostMapping("/participant/matching/{chatRoomId}") @Operation(summary = "참가자 매칭 수락/거절", description = "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)" + "workspace의 매칭이 확정된 경우 참여자는 매칭 거절을 할 수 없다.") - public ApiResponse matching( + public ApiResponse matching( @Parameter(hidden = true) @RequestHeader("Authorization") Long id, @PathVariable("chatRoomId") Long chatRoomId, @RequestBody UpdateParticipantMatchRequest request) { From 4713811050c2deb48c2d54b6ef952d2cede303eb Mon Sep 17 00:00:00 2001 From: Jin Hyuk Date: Fri, 22 Nov 2024 00:27:05 +0900 Subject: [PATCH 5/5] style: spotless --- .../participant/controller/ParticipantController.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java index 7ab749d..fb3c15f 100644 --- a/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java +++ b/src/main/java/com/hyunsolution/dangu/participant/controller/ParticipantController.java @@ -23,8 +23,11 @@ public class ParticipantController { // 사용자 매칭 버튼 클릭 @PostMapping("/participant/matching/{chatRoomId}") - @Operation(summary = "참가자 매칭 수락/거절", description = "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)" + - "workspace의 매칭이 확정된 경우 참여자는 매칭 거절을 할 수 없다.") + @Operation( + summary = "참가자 매칭 수락/거절", + description = + "참가자 매칭 수락/거절 한다. (isMatch가 true이면 매칭 수락)" + + "workspace의 매칭이 확정된 경우 참여자는 매칭 거절을 할 수 없다.") public ApiResponse matching( @Parameter(hidden = true) @RequestHeader("Authorization") Long id, @PathVariable("chatRoomId") Long chatRoomId,