Conversation
Walkthrough동호회(Club) 도메인 추가 및 관련 엔티티/레포지토리/서비스/컨트롤러/DTO/예외 도입, ChatRoom 모델·레포지토리·서비스·응답 DTO 리팩토링, STOMP 테스트 클라이언트 엔드포인트·페이로드 업데이트(및 테스트 파일 삭제), 로그인 DTO에 Swagger 스키마 주석 추가. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ClubController as Controller
participant ClubService as Service
participant ClubRepository as Repository
participant ClubMemberRepository as MemberRepo
participant ChatRoomService as ChatRoomSvc
Client->>Controller: POST /api/clubs (ClubCreateRequest)
Controller->>Service: createClub(request, authUser)
Service->>Repository: existsByName(name)?
alt name exists
Repository-->>Service: true
Service-->>Controller: throw CLUB_NAME_DUPLICATED
else
Repository-->>Service: false
Service->>Repository: save(Club)
Repository-->>Service: saved Club
Service->>MemberRepo: save(ClubMember as LEADER)
MemberRepo-->>Service: saved ClubMember
Service->>ChatRoomSvc: createGroup(chat for club)
ChatRoomSvc-->>Service: created ChatRoom
Service-->>Controller: ClubResponse.from(saved Club)
Controller-->>Client: 201 Created (ClubResponse)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
assets/stomp-test.html (1)
444-466: roomId 공백일 때 구독/입장 요청 차단 필요
빈 값이면/sub/chat/rooms/로 구독하고 roomId가 0/NaN으로 전송될 수 있어 서버 오류나 잘못된 방 조인이 발생합니다. 최소한 값 존재 확인 후 진행하세요.✅ 간단한 가드 추가
- const rid = roomIdValue(); + const rid = roomIdValue(); + if (!rid) return debug("[WARN] roomId is required"); const dest = `/sub/chat/rooms/${rid}`; $("roomTitle").textContent = `room: ${rid}`; currentSub = stompClient.subscribe(dest, (frame) => { @@ - stompClient.send("/pub/chat.join", {}, JSON.stringify({ - roomId: Number(roomIdValue()), + stompClient.send("/pub/chat.join", {}, JSON.stringify({ + roomId: Number(rid), senderUserId: myUserId(), senderNickname: myNickname() }));src/main/java/com/be/sportizebe/domain/chat/service/ChatRoomService.java (1)
36-37: Long 타입 비교에==대신.equals()를 사용하세요.
hostUser.getId() == guestUser.getId()는 Long 객체의 참조 비교를 수행합니다. Java의 Long 캐시 범위(-128~127) 밖의 ID 값에서는 동일한 값이어도false를 반환할 수 있어 자기 자신에게 채팅을 보낼 수 있는 버그가 발생할 수 있습니다.🐛 제안된 수정
// 자기 자신에게 채팅 불가 - if (hostUser.getId() == guestUser.getId()) { + if (hostUser.getId().equals(guestUser.getId())) { throw new CustomException(ChatErrorCode.SELF_CHAT_NOT_ALLOWED); }
🤖 Fix all issues with AI agents
In `@src/main/java/com/be/sportizebe/domain/club/controller/ClubController.java`:
- Around line 30-36: The createClub method in ClubController currently injects a
User via `@AuthenticationPrincipal` User user but the principal is a
CustomUserDetails (which implements UserDetails and wraps the User entity);
change the parameter to either `@AuthenticationPrincipal`(expression =
"principal.user") User user OR to `@AuthenticationPrincipal` CustomUserDetails
customUserDetails and then call clubService.createClub(request,
customUserDetails.getUser()) so the actual User entity is passed to
ClubController.createClub.
In
`@src/main/java/com/be/sportizebe/domain/club/dto/request/ClubCreateRequest.java`:
- Around line 9-23: ClubCreateRequest currently allows maxMembers to be null or
non-positive which can cause DB/runtime errors; add validation annotations to
the record parameter by annotating maxMembers with `@NotNull` and `@Min`(1) (e.g.,
`@NotNull`(message="최대 정원은 필수 입니다.") `@Min`(value=1, message="최대 정원은 1 이상이어야 합니다.")
Integer maxMembers) and import javax.validation.constraints.NotNull and
javax.validation.constraints.Min; additionally, defensively check in toEntity
(method ClubCreateRequest.toEntity) and throw a clear IllegalArgumentException
or similar if maxMembers is null or <1 before calling Club.builder() to ensure
safe construction.
In `@src/main/java/com/be/sportizebe/domain/club/service/ClubServiceImpl.java`:
- Around line 58-60: The permission check currently compares Long IDs using '!='
which does reference comparison; replace it with a null-safe value comparison
using Objects.equals(club.getLeader().getId(), user.getId()) (negated) so the
condition becomes if (!Objects.equals(...)) throw new
CustomException(ClubErrorCode.CLUB_UPDATE_DENIED); and add the necessary import
for java.util.Objects to avoid NPEs and ensure correct equality semantics for
Long values.
- Line 70: The call in ClubServiceImpl that does club.update(request.name(),
request.introduce(), request.maxMembers()) will overwrite maxMembers with null
when request.maxMembers() is null; change the service to preserve the existing
value by either branching: if request.maxMembers() != null then call
club.update(request.name(), request.introduce(), request.maxMembers()) else call
a partial updater such as club.updatePartial(request.name(),
request.introduce()), or alter Club.update(...) itself to treat a null
maxMembers as “do not change” (add a null check inside Club.update and only set
maxMembers when the passed value is non-null); reference ClubServiceImpl,
Club.update, Club.updatePartial and ClubUpdateRequest.maxMembers to locate and
implement the fix.
🧹 Nitpick comments (15)
src/main/java/com/be/sportizebe/domain/post/dto/request/CreatePostRequest.java (1)
15-15: TODO 마무리 계획을 명시해 주세요.
S3 설정 이후imgUrl을multipart/form-data로 전환할 예정이라면, 처리 범위(컨트롤러/서비스/DTO 변경)와 이슈/티켓 링크를 남겨 두면 추적이 쉬워집니다.필요하시면 전환 작업의 변경 목록을 정리해 드리거나 이슈 템플릿을 만들어 드릴까요?
assets/stomp-test.html (1)
415-419: 환경 의존적인 WebSocket URL 하드코딩 제거
로컬 고정 URL은 배포 환경/프록시/HTTPS에서 연결 실패나 mixed-content 문제를 유발할 수 있습니다. 동일 오리진을 기준으로 구성하는 편이 안전합니다.♻️ 변경 제안
- const socket = new SockJS( - "http://localhost:8080/ws-stomp", - null, - { transports: ["xhr-streaming", "xhr-polling"] } // ✅ opCode=7 우회 - ); + const socket = new SockJS( + `${window.location.origin}/ws-stomp`, + null, + { transports: ["xhr-streaming", "xhr-polling"] } // ✅ opCode=7 우회 + );src/main/java/com/be/sportizebe/domain/club/dto/request/ClubCreateRequest.java (1)
14-16: TODO 항목은 이슈로 추적해 주세요.Line 15의 TODO는 누락되기 쉬우니 별도 이슈/태스크로 등록해 관리하는 것을 권장합니다.
원하시면 이 작업을 위한 이슈 템플릿/체크리스트를 만들어 드릴까요?
src/main/java/com/be/sportizebe/domain/club/service/ClubService.java (1)
6-6: 사용되지 않는 import입니다.
SportType이 이 인터페이스에서 사용되지 않습니다. 제거하세요.♻️ 제안된 수정
-import com.be.sportizebe.domain.user.entity.SportType;src/main/java/com/be/sportizebe/domain/club/entity/Club.java (2)
4-4: 사용되지 않는 import입니다.
SportType이 이 엔티티에서 사용되지 않습니다. 제거하세요.♻️ 제안된 수정
-import com.be.sportizebe.domain.user.entity.SportType;
47-51: 부분 업데이트 시 null 값 처리를 고려하세요.현재
update()메서드는 모든 필드를 무조건 덮어씁니다. 클라이언트가 특정 필드만 업데이트하고 싶을 때 null이 전달되면 기존 값이 null로 덮어씌워질 수 있습니다.현재 구현이 의도된 동작이라면 무시해도 됩니다. 부분 업데이트가 필요하다면 아래 패턴을 고려하세요.
♻️ 부분 업데이트 패턴 예시
public void update(String name, String introduce, Integer maxMembers) { - this.name = name; - this.introduce = introduce; - this.maxMembers = maxMembers; + if (name != null) { + this.name = name; + } + if (introduce != null) { + this.introduce = introduce; + } + if (maxMembers != null) { + this.maxMembers = maxMembers; + } }src/main/java/com/be/sportizebe/domain/chat/dto/response/ChatRoomResponse.java (1)
29-37: NOTE 타입에서 post.getUser()가 null일 경우 NPE 가능성이 있습니다.
r.getPost() != null체크는 있지만,r.getPost().getUser()가 null인 경우에 대한 방어 로직이 없습니다. Post 엔티티에서 user가 항상 존재함이 보장된다면 괜찮지만, 방어적 코딩을 위해 null 체크를 추가하는 것을 고려하세요.♻️ 방어적 null 체크 추가
if (r.getChatRoomType() == ChatRoom.ChatRoomType.NOTE && r.getPost() != null) { builder.name(r.getPost().getTitle()); builder.postId(r.getPost().getId()); // hostUser는 게시글 작성자로 파생 - builder.hostUserId(r.getPost().getUser().getId()) - .hostUsername(r.getPost().getUser().getUsername()); + if (r.getPost().getUser() != null) { + builder.hostUserId(r.getPost().getUser().getId()) + .hostUsername(r.getPost().getUser().getUsername()); + } } else if (r.getChatRoomType() == ChatRoom.ChatRoomType.GROUP && r.getClub() != null) { builder.name(r.getClub().getName()); }src/main/java/com/be/sportizebe/domain/club/dto/request/ClubUpdateRequest.java (1)
10-10: maxMembers에 대한 유효성 검증이 누락되었습니다.
maxMembers가 null이거나 0 이하의 값이 전달될 수 있습니다. 서비스 레이어에서 검증하더라도 DTO 레벨에서 기본 유효성 검증을 추가하는 것이 좋습니다.♻️ 유효성 검증 추가
package com.be.sportizebe.domain.club.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Min; public record ClubUpdateRequest( `@NotBlank`(message = "동호회 이름은 필수 입니다.") `@Schema`(description = "동호회 이름", example = "축구 동호회") String name, `@Schema`(description = "동호회 소개", example = "매주 토요일 축구합니다") String introduce, - `@Schema`(description = "최대 정원", example = "20") Integer maxMembers) { + `@NotNull`(message = "최대 정원은 필수입니다.") + `@Min`(value = 1, message = "최대 정원은 1명 이상이어야 합니다.") + `@Schema`(description = "최대 정원", example = "20") Integer maxMembers) { }src/main/java/com/be/sportizebe/domain/club/dto/response/ClubResponse.java (1)
4-4: 사용되지 않는 import입니다.
SportType이 이 DTO에서 사용되지 않습니다. 제거하세요.♻️ 제안된 수정
-import com.be.sportizebe.domain.user.entity.SportType;src/main/java/com/be/sportizebe/domain/club/controller/ClubController.java (1)
6-7: 구현체 대신 인터페이스에 의존하고, 사용하지 않는 import를 제거하세요.
ClubServiceImpl대신ClubService인터페이스에 의존하는 것이 좋습니다. 이렇게 하면 DIP(Dependency Inversion Principle)를 준수하고, 테스트 시 목(mock) 주입이 용이해집니다.SportTypeimport는 사용되지 않으므로 제거해야 합니다.♻️ 제안된 수정
-import com.be.sportizebe.domain.club.service.ClubServiceImpl; -import com.be.sportizebe.domain.user.entity.SportType; +import com.be.sportizebe.domain.club.service.ClubService;그리고 필드 선언도 수정:
- private final ClubServiceImpl clubService; + private final ClubService clubService;src/main/java/com/be/sportizebe/domain/chat/entity/ChatRoom.java (1)
39-51: ChatRoomType에 따른 필드 유효성 검사가 없습니다.현재 엔티티 구조에서
ChatRoomType에 따라 다른 필드들이 사용됩니다:
GROUP:club이 필수,post/guestUser는 nullNOTE:post/guestUser가 필수,club은 null하지만 엔티티 레벨에서 이러한 제약 조건을 강제하지 않아 잘못된 데이터가 저장될 수 있습니다. 서비스 계층에서만 검증하고 있다면, 데이터베이스 무결성 문제가 발생할 수 있습니다.
고려할 수 있는 방안:
@PrePersist또는@PreUpdate에서 타입별 필드 검증- 정적 팩토리 메서드로 생성 제한 (builder 대신)
♻️ `@PrePersist에` 검증 로직 추가 예시
`@PrePersist` void prePersist() { if (createdAt == null) createdAt = Instant.now(); // 기본 활성화 active = true; + + // 타입별 필드 검증 + if (chatRoomType == ChatRoomType.GROUP && club == null) { + throw new IllegalStateException("GROUP 채팅방은 club이 필수입니다."); + } + if (chatRoomType == ChatRoomType.NOTE && (post == null || guestUser == null)) { + throw new IllegalStateException("NOTE 채팅방은 post와 guestUser가 필수입니다."); + } }src/main/java/com/be/sportizebe/domain/club/service/ClubServiceImpl.java (2)
12-12: 사용하지 않는 import를 제거하세요.
SportType이 import 되었지만 사용되지 않습니다.♻️ 제안된 수정
-import com.be.sportizebe.domain.user.entity.SportType;
66-68:club.getMembers()호출 시 N+1 또는 LazyInitializationException 가능성을 확인하세요.
@OneToMany관계인members가 기본적으로LAZY로딩이므로, 트랜잭션 내에서 호출되더라도 N+1 쿼리 문제가 발생할 수 있습니다. 현재 멤버 수만 필요하다면ClubMemberRepository에 count 쿼리를 추가하는 것이 효율적입니다.♻️ Count 쿼리 사용 제안
ClubMemberRepository에 추가:long countByClub(Club club); // 또는 long countByClubId(Long clubId);서비스에서 사용:
- if (request.maxMembers() != null && request.maxMembers() < club.getMembers().size()) { + if (request.maxMembers() != null && request.maxMembers() < clubMemberRepository.countByClubId(clubId)) { throw new CustomException(ClubErrorCode.CLUB_MAX_MEMBERS_TOO_SMALL); }src/main/java/com/be/sportizebe/domain/club/entity/ClubMember.java (2)
14-16:@NoArgsConstructor에access = AccessLevel.PROTECTED를 추가하세요.JPA 엔티티는 기본 생성자가 필요하지만,
public으로 열어두면 의도치 않은 객체 생성이 가능합니다.protected로 제한하면 JPA 프록시 생성은 허용하면서 직접 인스턴스화는 방지할 수 있습니다.♻️ 제안된 수정
-@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED)
AccessLevelimport도 필요합니다:+import lombok.AccessLevel;
23-29: 동일 사용자의 중복 가입 방지를 위해 유니크 제약조건을 추가하세요.한 사용자가 동일한 동호회에 여러 번 가입하는 것을 방지하기 위해
(club_id, user_id)조합에 유니크 제약조건이 필요합니다.♻️ 제안된 수정
`@Entity` `@Getter` `@Builder` `@AllArgsConstructor` -@NoArgsConstructor -@Table(name = "club_members") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "club_members", uniqueConstraints = { + `@UniqueConstraint`(columnNames = {"club_id", "user_id"}) +}) public class ClubMember extends BaseTimeEntity {
| public ResponseEntity<BaseResponse<ClubResponse>> createClub( | ||
| @RequestBody @Valid ClubCreateRequest request, | ||
| @AuthenticationPrincipal User user) { | ||
| ClubResponse response = clubService.createClub(request, user); | ||
| return ResponseEntity.status(HttpStatus.CREATED) | ||
| .body(BaseResponse.success("동호회 생성 성공", response)); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# CustomUserDetails 클래스 위치 및 구현 확인
find . -type f -name "*.java" | xargs grep -l "class CustomUserDetails"Repository: Sportize/be
Length of output: 127
🏁 Script executed:
# CustomUserDetails 구현 세부사항 확인
rg -n "class CustomUserDetails" -A 30Repository: Sportize/be
Length of output: 2962
🏁 Script executed:
# User 엔티티 구조 확인
find . -type f -name "*.java" -path "*/domain/*" | xargs grep -l "class User"Repository: Sportize/be
Length of output: 265
🏁 Script executed:
cat -n src/main/java/com/be/sportizebe/global/security/CustomUserDetails.javaRepository: Sportize/be
Length of output: 1570
@AuthenticationPrincipal 주입 타입 변경 필요
CustomUserDetails는 UserDetails 인터페이스를 구현하며 User를 상속하지 않습니다. @AuthenticationPrincipal의 기본 동작은 Authentication.getPrincipal()에서 CustomUserDetails 인스턴스를 반환하므로, 현재 @AuthenticationPrincipal User user로 직접 User 엔티티를 주입받을 수 없습니다.
다음 중 하나로 변경하세요:
@AuthenticationPrincipal(expression = "principal.user") User user사용- 또는
@AuthenticationPrincipal CustomUserDetails customUserDetails로 변경하고customUserDetails.getUser()로 User 엔티티 접근
🤖 Prompt for AI Agents
In `@src/main/java/com/be/sportizebe/domain/club/controller/ClubController.java`
around lines 30 - 36, The createClub method in ClubController currently injects
a User via `@AuthenticationPrincipal` User user but the principal is a
CustomUserDetails (which implements UserDetails and wraps the User entity);
change the parameter to either `@AuthenticationPrincipal`(expression =
"principal.user") User user OR to `@AuthenticationPrincipal` CustomUserDetails
customUserDetails and then call clubService.createClub(request,
customUserDetails.getUser()) so the actual User entity is passed to
ClubController.createClub.
| public record ClubCreateRequest( | ||
| @NotBlank(message = "동호회 이름은 필수 입니다.") | ||
| @Schema(description = "동호회 이름", example = "축구 동호회") String name, | ||
| @Schema(description = "동호회 소개", example = "매주 토요일 축구합니다") String introduce, | ||
| @Schema(description = "최대 정원", example = "20") Integer maxMembers) { | ||
| // 관련 종목은 파라미터로 받음 | ||
| // TODO : S3 세팅 후 imgUrl은 multipartform으로 변경 | ||
|
|
||
| public Club toEntity(User user) { | ||
| return Club.builder() | ||
| .name(name) | ||
| .introduce(introduce) | ||
| .maxMembers(maxMembers) | ||
| .leader(user) | ||
| .build(); |
There was a problem hiding this comment.
maxMembers 검증이 누락되어 있습니다.
Line 13에서 maxMembers가 null/음수여도 통과할 수 있어 저장 시 제약 위반 또는 런타임 오류가 날 수 있습니다. 최소한 null/양수 검증을 추가해 주세요.
🔧 제안 수정
-import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
public record ClubCreateRequest(
`@NotBlank`(message = "동호회 이름은 필수 입니다.")
`@Schema`(description = "동호회 이름", example = "축구 동호회") String name,
`@Schema`(description = "동호회 소개", example = "매주 토요일 축구합니다") String introduce,
- `@Schema`(description = "최대 정원", example = "20") Integer maxMembers) {
+ `@NotNull`(message = "최대 정원은 필수 입니다.")
+ `@Positive`(message = "최대 정원은 양수여야 합니다.")
+ `@Schema`(description = "최대 정원", example = "20") Integer maxMembers) {🤖 Prompt for AI Agents
In
`@src/main/java/com/be/sportizebe/domain/club/dto/request/ClubCreateRequest.java`
around lines 9 - 23, ClubCreateRequest currently allows maxMembers to be null or
non-positive which can cause DB/runtime errors; add validation annotations to
the record parameter by annotating maxMembers with `@NotNull` and `@Min`(1) (e.g.,
`@NotNull`(message="최대 정원은 필수 입니다.") `@Min`(value=1, message="최대 정원은 1 이상이어야 합니다.")
Integer maxMembers) and import javax.validation.constraints.NotNull and
javax.validation.constraints.Min; additionally, defensively check in toEntity
(method ClubCreateRequest.toEntity) and throw a clear IllegalArgumentException
or similar if maxMembers is null or <1 before calling Club.builder() to ensure
safe construction.
| if (club.getLeader().getId() != user.getId()) { | ||
| throw new CustomException(ClubErrorCode.CLUB_UPDATE_DENIED); | ||
| } |
There was a problem hiding this comment.
Long 객체 비교 시 == 대신 equals()를 사용하세요.
Long 객체를 !=로 비교하면 참조 비교가 수행됩니다. -128에서 127 범위 외의 ID 값에서는 동일한 값이라도 false를 반환할 수 있어 권한 검증이 실패합니다.
🐛 수정 제안
- if (club.getLeader().getId() != user.getId()) {
+ if (!club.getLeader().getId().equals(user.getId())) {
throw new CustomException(ClubErrorCode.CLUB_UPDATE_DENIED);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (club.getLeader().getId() != user.getId()) { | |
| throw new CustomException(ClubErrorCode.CLUB_UPDATE_DENIED); | |
| } | |
| if (!club.getLeader().getId().equals(user.getId())) { | |
| throw new CustomException(ClubErrorCode.CLUB_UPDATE_DENIED); | |
| } |
🤖 Prompt for AI Agents
In `@src/main/java/com/be/sportizebe/domain/club/service/ClubServiceImpl.java`
around lines 58 - 60, The permission check currently compares Long IDs using
'!=' which does reference comparison; replace it with a null-safe value
comparison using Objects.equals(club.getLeader().getId(), user.getId())
(negated) so the condition becomes if (!Objects.equals(...)) throw new
CustomException(ClubErrorCode.CLUB_UPDATE_DENIED); and add the necessary import
for java.util.Objects to avoid NPEs and ensure correct equality semantics for
Long values.
| throw new CustomException(ClubErrorCode.CLUB_MAX_MEMBERS_TOO_SMALL); | ||
| } | ||
|
|
||
| club.update(request.name(), request.introduce(), request.maxMembers()); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find and examine the Club.update() method implementation
cd /root/repo 2>/dev/null || cd .
# First, find the Club class
find . -type f -name "Club.java" | head -5
# Search for the update method in Club class
rg -n "public void update" -A 15 --type java | grep -A 15 "update"
# Also check if there's null checking in the method
rg -n "maxMembers" -B 3 -A 3 --type java | head -50Repository: Sportize/be
Length of output: 6825
🏁 Script executed:
#!/bin/bash
# Get more context around the update method to understand the full picture
cd /root/repo 2>/dev/null || cd .
# Check the full Club.update() method
cat -n ./src/main/java/com/be/sportizebe/domain/club/entity/Club.java | sed -n '40,60p'
# Check if there are any other update calls or patterns
rg -n "\.update\(" --type java | grep -i clubRepository: Sportize/be
Length of output: 718
request.maxMembers()가 null일 때 null로 설정되는 문제를 수정하세요.
ClubUpdateRequest의 maxMembers는 @NotNull 검증이 없어 null이 될 수 있으며, Club.update() 메서드는 전달된 값을 그대로 저장합니다. PATCH 요청에서 null은 "이 필드를 업데이트하지 않음"을 의미하므로, 다음과 같이 기존 값을 유지하도록 수정이 필요합니다:
if (request.maxMembers() != null) {
club.update(request.name(), request.introduce(), request.maxMembers());
} else {
club.updatePartial(request.name(), request.introduce());
}또는 Club.update() 메서드 내에서 null 체크를 추가하여 기존 값을 보존하는 방식으로 구현하세요.
🤖 Prompt for AI Agents
In `@src/main/java/com/be/sportizebe/domain/club/service/ClubServiceImpl.java` at
line 70, The call in ClubServiceImpl that does club.update(request.name(),
request.introduce(), request.maxMembers()) will overwrite maxMembers with null
when request.maxMembers() is null; change the service to preserve the existing
value by either branching: if request.maxMembers() != null then call
club.update(request.name(), request.introduce(), request.maxMembers()) else call
a partial updater such as club.updatePartial(request.name(),
request.introduce()), or alter Club.update(...) itself to treat a null
maxMembers as “do not change” (add a null check inside Club.update and only set
maxMembers when the passed value is non-null); reference ClubServiceImpl,
Club.update, Club.updatePartial and ClubUpdateRequest.maxMembers to locate and
implement the fix.
#️⃣ Issue Number
📝 요약(Summary)
ChatRoom.java — 필드 3개 제거
ChatRoomRepository.java — 쿼리 메서드 변경
동호회 수정 기능 + 예외처리
- Club 조회 → 리더 권한 확인 → 이름 변경 시 중복 검사 → entity.update() → ClubResponse 반환
게시글 목록 조회 구현
사용 예시:
etc
stomp-test.html 중복 파일 제거 : /ws-stomp/* 엔드포인트 사용
🛠️ PR 유형
어떤 변경 사항이 있나요?
📸스크린샷 (선택)
💬 공유사항 to 리뷰어
✅ PR Checklist
PR이 다음 요구 사항을 충족하는지 확인하세요.
Summary by CodeRabbit
릴리스 노트
New Features
Documentation
Refactor
Chores
✏️ Tip: You can customize this high-level summary in your review settings.