Skip to content

Commit 29657f3

Browse files
authored
fix : 파티 인증 정보 확인 변경 및 리팩토링 진행 (#56)
* fix : 파티 기능 인증 정보 확인하도록 변경 * refactor : 파티 도메인 리팩토링 진행
1 parent 3083664 commit 29657f3

File tree

9 files changed

+155
-104
lines changed

9 files changed

+155
-104
lines changed

backend/src/main/java/com/back/domain/party/party/controller/ApiV1PartyController.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
import com.back.domain.party.party.entity.PartyMember;
66
import com.back.domain.party.party.service.PartyService;
77
import com.back.global.common.ApiResponse;
8+
import com.back.global.exception.CustomException;
9+
import com.back.global.exception.ErrorCode;
810
import io.swagger.v3.oas.annotations.Operation;
911
import io.swagger.v3.oas.annotations.tags.Tag;
1012
import jakarta.validation.Valid;
1113
import lombok.RequiredArgsConstructor;
1214
import org.springframework.http.HttpStatus;
1315
import org.springframework.http.ResponseEntity;
16+
import org.springframework.security.core.Authentication;
1417
import org.springframework.web.bind.annotation.*;
1518

1619
import java.util.List;
@@ -24,12 +27,25 @@ public class ApiV1PartyController {
2427

2528
private final PartyService partyService;
2629

30+
// Authentication 객체로부터 사용자 ID를 안전하게 가져오는 헬퍼 메서드
31+
private Integer getMemberIdFromAuthentication(Authentication authentication) {
32+
if (authentication == null || authentication.getName() == null) {
33+
throw new IllegalArgumentException("인증 정보가 없습니다.");
34+
}
35+
try {
36+
return Integer.parseInt(authentication.getName());
37+
} catch (NumberFormatException e) {
38+
throw new CustomException(ErrorCode.UNAUTHORIZED, "유효하지 않은 인증 정보입니다.");
39+
}
40+
}
41+
2742
@PostMapping
2843
@Operation(summary = "파티 생성", description = "파티를 생성하는 API")
2944
public ResponseEntity<ApiResponse<PartyDto>> createParty(
3045
@Valid @RequestBody PartyRequestDto requestDto,
31-
@RequestParam("memberId") Integer memberId
46+
Authentication authentication
3247
) {
48+
Integer memberId = getMemberIdFromAuthentication(authentication);
3349
Party createdParty = partyService.createParty(requestDto, memberId);
3450
PartyDto partyDto = new PartyDto(createdParty);
3551

@@ -42,8 +58,9 @@ public ResponseEntity<ApiResponse<PartyDto>> createParty(
4258
@Operation(summary = "공개 파티 가입 신청", description = "공개 파티에 가입을 신청하는 API. 파티장이 수락해야 가입 완료됩니다.")
4359
public ResponseEntity<ApiResponse<Void>> joinParty(
4460
@PathVariable Integer partyId,
45-
@RequestParam("memberId") Integer memberId
61+
Authentication authentication
4662
) {
63+
Integer memberId = getMemberIdFromAuthentication(authentication);
4764
partyService.joinParty(partyId, memberId);
4865

4966
return ResponseEntity
@@ -55,8 +72,9 @@ public ResponseEntity<ApiResponse<Void>> joinParty(
5572
@Operation(summary = "파티 탈퇴", description = "가입된 파티를 탈퇴하는 API")
5673
public ResponseEntity<ApiResponse<Void>> leaveParty(
5774
@PathVariable Integer partyId,
58-
@RequestParam("memberId") Integer memberId
75+
Authentication authentication
5976
) {
77+
Integer memberId = getMemberIdFromAuthentication(authentication);
6078
partyService.leaveParty(partyId, memberId);
6179

6280
return ResponseEntity
@@ -69,8 +87,9 @@ public ResponseEntity<ApiResponse<Void>> leaveParty(
6987
public ResponseEntity<ApiResponse<Void>> updateParty(
7088
@PathVariable Integer partyId,
7189
@Valid @RequestBody PartyUpdateRequestDto requestDto,
72-
@RequestParam("memberId") Integer memberId
90+
Authentication authentication
7391
) {
92+
Integer memberId = getMemberIdFromAuthentication(authentication);
7493
partyService.updateParty(partyId, requestDto, memberId);
7594

7695
return ResponseEntity
@@ -82,8 +101,9 @@ public ResponseEntity<ApiResponse<Void>> updateParty(
82101
@Operation(summary = "파티 삭제", description = "파티를 삭제하는 API")
83102
public ResponseEntity<ApiResponse<Void>> deleteParty(
84103
@PathVariable Integer partyId,
85-
@RequestParam("memberId") Integer memberId
104+
Authentication authentication
86105
) {
106+
Integer memberId = getMemberIdFromAuthentication(authentication);
87107
partyService.deleteParty(partyId, memberId);
88108

89109
return ResponseEntity
@@ -119,9 +139,10 @@ public ResponseEntity<ApiResponse<PartyDto>> getPartyDetails(@PathVariable Integ
119139
@Operation(summary = "파티 초대 (코드)", description = "파티장이 다른 멤버를 코드를 사용하여 파티에 초대하는 API")
120140
public ResponseEntity<ApiResponse<Void>> inviteMember(
121141
@PathVariable Integer partyId,
122-
@RequestParam("leaderId") Integer leaderId,
123-
@RequestBody @Valid InvitationDto invitationDto
142+
@RequestBody @Valid InvitationDto invitationDto,
143+
Authentication authentication
124144
) {
145+
Integer leaderId = getMemberIdFromAuthentication(authentication);
125146
partyService.inviteMember(partyId, leaderId, invitationDto.getInvitedMemberCode());
126147

127148
return ResponseEntity
@@ -133,8 +154,9 @@ public ResponseEntity<ApiResponse<Void>> inviteMember(
133154
@Operation(summary = "초대/신청 수락", description = "초대/신청 대기 중인 멤버를 파티원이 되도록 수락하는 API")
134155
public ResponseEntity<ApiResponse<Void>> acceptInvitation(
135156
@PathVariable Integer partyId,
136-
@RequestParam("memberId") Integer memberId
157+
Authentication authentication
137158
) {
159+
Integer memberId = getMemberIdFromAuthentication(authentication);
138160
partyService.acceptInvitation(partyId, memberId);
139161
return ResponseEntity
140162
.status(HttpStatus.OK)
@@ -145,8 +167,9 @@ public ResponseEntity<ApiResponse<Void>> acceptInvitation(
145167
@Operation(summary = "초대/신청 거절", description = "초대/신청 대기 중인 멤버를 거절하는 API")
146168
public ResponseEntity<ApiResponse<Void>> rejectInvitation(
147169
@PathVariable Integer partyId,
148-
@RequestParam("memberId") Integer memberId
170+
Authentication authentication
149171
) {
172+
Integer memberId = getMemberIdFromAuthentication(authentication);
150173
partyService.rejectInvitation(partyId, memberId);
151174
return ResponseEntity
152175
.status(HttpStatus.OK)
@@ -157,9 +180,10 @@ public ResponseEntity<ApiResponse<Void>> rejectInvitation(
157180
@Operation(summary = "파티원 추방", description = "파티장이 특정 파티원을 추방하는 API")
158181
public ResponseEntity<ApiResponse<Void>> kickMember(
159182
@PathVariable Integer partyId,
160-
@RequestParam("leaderId") Integer leaderId,
183+
Authentication authentication,
161184
@PathVariable Integer kickedMemberId
162185
) {
186+
Integer leaderId = getMemberIdFromAuthentication(authentication);
163187
partyService.kickMember(partyId, leaderId, kickedMemberId);
164188

165189
return ResponseEntity
@@ -171,8 +195,9 @@ public ResponseEntity<ApiResponse<Void>> kickMember(
171195
@Operation(summary = "파티 가입 신청/초대 목록 조회", description = "파티장이 가입 신청 또는 초대 대기 중인 멤버 목록을 조회하는 API")
172196
public ResponseEntity<ApiResponse<List<PartyMemberDto>>> getPendingJoinRequests(
173197
@PathVariable Integer partyId,
174-
@RequestParam("leaderId") Integer leaderId
198+
Authentication authentication
175199
) {
200+
Integer leaderId = getMemberIdFromAuthentication(authentication);
176201
List<PartyMember> pendingRequests = partyService.getPendingJoinRequests(partyId, leaderId);
177202
List<PartyMemberDto> requestDtos = pendingRequests.stream()
178203
.map(pm -> new PartyMemberDto(pm.getMember()))

backend/src/main/java/com/back/domain/party/party/entity/PartyMemberId.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
@NoArgsConstructor
99
@AllArgsConstructor
10-
@EqualsAndHashCode
10+
@EqualsAndHashCode(callSuper = false)
1111
public class PartyMemberId implements Serializable {
1212
private int party;
1313
private int member;

backend/src/main/java/com/back/domain/party/party/entity/PartyMemberStatus.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@
33
public enum PartyMemberStatus {
44
PENDING, // 초대 대기
55
ACCEPTED, // 파티원
6-
REJECTED // 초대 거절
76
}

backend/src/main/java/com/back/domain/party/party/service/PartyService.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ public class PartyService {
3131
private final MemberRepository memberRepository;
3232
private final PartyMemberRepository partyMemberRepository;
3333

34+
// 파티 정원 확인 메서드
35+
private void checkPartyCapacity(Party party) {
36+
long acceptedMembers = partyMemberRepository.countByParty_IdAndStatus(party.getId(), PartyMemberStatus.ACCEPTED);
37+
if (acceptedMembers >= party.getMaxMembers()) {
38+
throw new CustomException(ErrorCode.CONFLICT, "파티의 정원이 가득 찼습니다.");
39+
}
40+
}
41+
3442
@Transactional
3543
@CacheEvict(value = {"partyList", "partyDetails"}, allEntries = true)
3644
public Party createParty(PartyRequestDto requestDto, Integer memberId) {
@@ -73,10 +81,7 @@ public void joinParty(Integer partyId, Integer memberId) {
7381
}
7482

7583
// 3. 파티의 정원이 가득 찼는지 확인
76-
long acceptedMembers = partyMemberRepository.countByParty_IdAndStatus(partyId, PartyMemberStatus.ACCEPTED);
77-
if (acceptedMembers >= party.getMaxMembers()) {
78-
throw new CustomException(ErrorCode.CONFLICT, "파티의 정원이 가득 찼습니다.");
79-
}
84+
checkPartyCapacity(party);
8085

8186
// 4. PartyMember 객체 생성 및 상태를 PENDING으로 설정
8287
PartyMember partyMember = new PartyMember();
@@ -106,14 +111,16 @@ public void leaveParty(Integer partyId, Integer memberId) {
106111
if (!otherMembers.isEmpty()) {
107112
PartyMember newLeaderMember = otherMembers.getFirst();
108113
party.setLeader(newLeaderMember.getMember());
114+
// 파티원 목록에서 탈퇴 멤버 삭제
115+
partyMemberRepository.delete(leavingMember);
109116
} else {
110117
// 남은 멤버가 없다면 파티 삭제
111-
partyRepository.delete(party);
118+
deleteParty(partyId, memberId);
112119
}
120+
} else {
121+
// 파티 멤버 목록에서 탈퇴 멤버 삭제
122+
partyMemberRepository.delete(leavingMember);
113123
}
114-
115-
// 파티 멤버 목록에서 탈퇴 멤버 삭제
116-
partyMemberRepository.delete(leavingMember);
117124
}
118125

119126
@Transactional
@@ -154,12 +161,7 @@ public void deleteParty(Integer partyId, Integer memberId) {
154161
throw new CustomException(ErrorCode.UNAUTHORIZED, "파티 삭제 권한이 없습니다.");
155162
}
156163

157-
// 파티에 속한 모든 멤버 관계를 먼저 삭제
158-
List<PartyMember> partyMembers = partyMemberRepository.findByParty_Id(partyId);
159-
partyMemberRepository.deleteAll(partyMembers);
160-
161-
// 파티 삭제
162-
partyRepository.deleteById(partyId);
164+
partyRepository.delete(party);
163165
}
164166

165167
@Cacheable(value = "partyList", key = "'all'")
@@ -185,11 +187,8 @@ public void inviteMember(Integer partyId, Integer leaderId, String invitedMember
185187
throw new CustomException(ErrorCode.UNAUTHORIZED, "파티 초대 권한이 없습니다.");
186188
}
187189

188-
// 정원 확인 로직을 개선된 쿼리로 변경
189-
long acceptedMembers = partyMemberRepository.countByParty_IdAndStatus(partyId, PartyMemberStatus.ACCEPTED);
190-
if (acceptedMembers >= party.getMaxMembers()) {
191-
throw new CustomException(ErrorCode.CONFLICT, "파티의 정원이 가득 찼습니다.");
192-
}
190+
// 정원 확인
191+
checkPartyCapacity(party);
193192

194193
// 코드로 멤버를 조회합니다.
195194
Member invitedMember = memberRepository.findByCode(invitedMemberCode)

backend/src/main/java/com/back/domain/party/paryChat/controller/WebSocketController.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.springframework.messaging.handler.annotation.MessageMapping;
1313
import org.springframework.messaging.handler.annotation.Payload;
1414
import org.springframework.messaging.simp.SimpMessageSendingOperations;
15+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
16+
import org.springframework.security.core.userdetails.User;
1517
import org.springframework.web.bind.annotation.*;
1618

1719
@RestController
@@ -23,27 +25,41 @@ public class WebSocketController {
2325
private final ChatMessageService chatMessageService;
2426

2527
@MessageMapping("/chat.sendMessage") // 클라이언트가 메시지를 보내는 경로 (예: /app/chat.sendMessage)
26-
public void sendMessage(@Payload ChatMessageDto chatMessageDto) {
28+
public void sendMessage(@Payload ChatMessageDto chatMessageDto, @AuthenticationPrincipal User user) {
2729
// 1. 메시지를 데이터베이스에 저장
30+
chatMessageDto.setSenderEmail(user.getUsername()); // 인증된 사용자 이메일로 설정
2831
chatMessageService.saveMessage(chatMessageDto);
2932

3033
// 2. 메시지를 해당 파티의 채팅방으로 전송
3134
messagingTemplate.convertAndSend("/topic/party/" + chatMessageDto.getPartyId(), chatMessageDto);
3235
}
3336

3437
@MessageMapping("/chat.updateMessage")
35-
public void updateMessage(@Payload ChatMessageDto chatMessageDto) {
38+
public void updateMessage(@Payload ChatMessageDto chatMessageDto, @AuthenticationPrincipal User user) {
39+
// 인증된 사용자의 이메일을 DTO에 설정
40+
chatMessageDto.setSenderEmail(user.getUsername());
41+
3642
// 메시지를 업데이트하고 반환된 최신 정보를 브로드캐스트합니다.
37-
ChatMessage updatedMessage = chatMessageService.updateMessage(chatMessageDto.getId(), chatMessageDto.getContent(), chatMessageDto.getSenderEmail());
43+
ChatMessage updatedMessage = chatMessageService.updateMessage(chatMessageDto); // DTO를 직접 넘기도록 수정
3844
ChatMessageDto updatedDto = new ChatMessageDto(updatedMessage);
3945
messagingTemplate.convertAndSend("/topic/party/" + updatedDto.getPartyId(), updatedDto);
4046
}
4147

4248
@MessageMapping("/chat.deleteMessage")
43-
public void deleteMessage(@Payload ChatMessageDto chatMessageDto) {
44-
// 메시지를 삭제하고 변경 내용을 브로드캐스트합니다.
45-
ChatMessage deletedMessage = chatMessageService.deleteMessage(chatMessageDto.getId(), chatMessageDto.getSenderEmail());
46-
ChatMessageDto deletedDto = new ChatMessageDto(deletedMessage);
49+
public void deleteMessage(@Payload ChatMessageDto chatMessageDto, @AuthenticationPrincipal User user) {
50+
// 인증된 사용자의 이메일을 가져옵니다.
51+
String senderEmail = user.getUsername();
52+
53+
// 1. 서비스 메서드를 호출하여 메시지를 삭제합니다. 이 메서드는 이제 반환값이 없습니다.
54+
chatMessageService.deleteMessage(chatMessageDto.getId(), senderEmail);
55+
56+
// 2. 클라이언트에 삭제 사실을 알리기 위한 DTO를 생성합니다.
57+
ChatMessageDto deletedDto = new ChatMessageDto();
58+
deletedDto.setId(chatMessageDto.getId());
59+
deletedDto.setPartyId(chatMessageDto.getPartyId());
60+
deletedDto.setContent(null); // 삭제되었음을 명확히 하기 위해 content를 null로 설정
61+
62+
// 3. 삭제된 메시지 정보를 브로드캐스트합니다.
4763
messagingTemplate.convertAndSend("/topic/party/" + deletedDto.getPartyId(), deletedDto);
4864
}
4965

backend/src/main/java/com/back/domain/party/paryChat/entity/ChatMessage.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import jakarta.persistence.*;
77
import lombok.*;
88
import org.hibernate.annotations.SoftDelete;
9+
import org.hibernate.annotations.Where;
910

1011
@Entity
1112
@Getter
@@ -17,6 +18,7 @@
1718
@Table(name = "chat_message", indexes = {
1819
@Index(name = "idx_partyId_createDate", columnList = "party_id, create_date DESC")
1920
})
21+
@Where(clause = "deleted_at IS NULL")
2022
public class ChatMessage extends BaseEntity {
2123

2224
@ManyToOne(fetch = FetchType.LAZY)

0 commit comments

Comments
 (0)