[feat] 유저 닉네임 중복 확인 API 구현 #98
Conversation
Walkthrough이번 변경에서는 사용자 정보를 조회하는 GET Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserController
participant SecurityContext
participant UserInfoService
participant UserRepository
Client->>UserController: GET /info
UserController->>SecurityContext: 사용자 ID 추출
UserController->>UserInfoService: getUserInfo(userId)
UserInfoService->>UserRepository: findById(userId)
UserRepository-->>UserInfoService: User 반환
UserInfoService-->>UserController: UserInfoResponseDto
UserController-->>Client: CommonResponse<UserInfoResponseDto>
Client->>UserController: GET /check-nickname?nickname=xxx
UserController->>UserInfoService: isNicknameAvailable(nickname)
UserInfoService->>UserRepository: existsByNickname(nickname)
UserRepository-->>UserInfoService: boolean
UserInfoService-->>UserController: boolean
UserController-->>Client: CommonResponse<NicknameCheckResponse>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15–20 minutes Possibly related PRs
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Walkthrough이번 변경에서는 사용자 정보 관리 기능이 확장되었습니다. UserController에 사용자 정보 조회(GET /info)와 닉네임 중복 확인(GET /check-nickname) 엔드포인트가 추가되었고, 관련 DTO, 응답 객체, 서비스, 리포지토리, 예외 케이스, 그리고 User 엔티티 및 관련 enum이 신설 또는 수정되었습니다. 장애유형과 이동보조기구는 String 리스트에서 Enum 리스트로 전환되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserController
participant SecurityContext
participant UserInfoService
participant UserRepository
Client->>UserController: GET /info (인증 필요)
UserController->>SecurityContext: 사용자 ID 추출
UserController->>UserInfoService: getUserInfo(userId)
UserInfoService->>UserRepository: findById(userId)
UserRepository-->>UserInfoService: User 엔티티 반환
UserInfoService-->>UserController: UserInfoResponseDto 반환
UserController-->>Client: CommonResponse<UserInfoResponseDto>
Client->>UserController: GET /check-nickname?nickname=xxx
UserController->>UserInfoService: isNicknameAvailable(nickname)
UserInfoService->>UserRepository: existsByNickname(nickname)
UserRepository-->>UserInfoService: boolean 반환
UserInfoService-->>UserController: boolean 반환
UserController-->>Client: CommonResponse<NicknameCheckResponse>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Walkthrough사용자 정보 조회와 닉네임 중복 확인을 위한 GET API가 UserController에 추가되었습니다. 장애 유형과 이동 보조기구 관련 필드가 String 리스트에서 Enum 리스트로 변경되었으며, 이에 맞는 Enum 타입과 DTO, 응답 클래스가 새로 도입되었습니다. 닉네임 중복 확인 및 사용자 정보 미존재 등 새로운 에러 케이스가 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserController
participant UserInfoService
participant UserRepository
participant DB
Client->>UserController: GET /api/v1/user/info (인증 포함)
UserController->>UserInfoService: getUserInfo(userId)
UserInfoService->>UserRepository: findById(userId)
UserRepository->>DB: 사용자 정보 조회
DB-->>UserRepository: User 엔티티 반환
UserRepository-->>UserInfoService: User 엔티티
UserInfoService-->>UserController: UserInfoResponseDto
UserController-->>Client: CommonResponse<UserInfoResponseDto>
Client->>UserController: GET /api/v1/user/check-nickname?nickname=xxx
UserController->>UserInfoService: isNicknameAvailable(nickname)
UserInfoService->>UserRepository: existsByNickname(nickname)
UserRepository-->>UserInfoService: true/false
UserInfoService-->>UserController: boolean
UserController-->>Client: CommonResponse<NicknameCheckResponse>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20분 Possibly related PRs
Suggested reviewers
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
6-6: 사용되지 않는 import문을 제거하세요.
HttpStatusimport가 추가되었지만 실제 코드에서 사용되지 않습니다. 사용되지 않는 import문은 제거하는 것이 좋습니다.-import org.springframework.http.HttpStatus;src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java (1)
19-20: 필드명 일관성 개선을 고려해보세요.
disabilityType과mobilityAid필드가 복수 값을 담는 List임에도 단수형 이름을 사용하고 있습니다. 가독성을 위해disabilityTypes,mobilityAids로 변경하는 것을 고려해보세요.- private List<DisabilityType> disabilityType; // 복수 선택 가능 - private List<MobilityAid> mobilityAid; // 복수 선택 가능 + private List<DisabilityType> disabilityTypes; // 복수 선택 가능 + private List<MobilityAid> mobilityAids; // 복수 선택 가능src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java (1)
32-34: enum 리스트 필드에 대한 유효성 검증을 고려해보세요.현재
disabilityType과mobilityAid필드에는 유효성 검증 어노테이션이 없습니다.userType이DISABLED일 때만 값이 존재해야 한다는 비즈니스 로직이 있다면, 커스텀 유효성 검증을 추가하는 것을 고려해보세요.@AssertTrue(message = "장애인 유형일 때는 장애 유형이 필수입니다.") private boolean isDisabilityTypeValid() { return userType != UserType.DISABLED || (disabilityType != null && !disabilityType.isEmpty()); }src/main/java/com/wayble/server/user/controller/UserController.java (1)
111-119: 닉네임 검증 로직을 개선할 수 있습니다.수동 파라미터 검증보다는 Bean Validation을 활용하는 것이 더 좋은 접근법입니다.
- public CommonResponse<NicknameCheckResponse> checkNickname(@RequestParam(value = "nickname", required = false) String nickname) { - if (nickname == null || nickname.trim().isEmpty()) { - throw new ApplicationException(UserErrorCase.NICKNAME_REQUIRED); - } + public CommonResponse<NicknameCheckResponse> checkNickname( + @RequestParam("nickname") @NotBlank(message = "닉네임은 필수입니다.") String nickname) { if (!userInfoService.isNicknameAvailable(nickname.trim())) { throw new ApplicationException(UserErrorCase.NICKNAME_DUPLICATED); } return CommonResponse.success(new NicknameCheckResponse(true, "사용 가능한 닉네임입니다.")); }src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (1)
18-19: 필드명 일관성 개선을 고려해보세요.복수 값을 담는 List 필드임에도 단수형 이름을 사용하고 있습니다. 다른 DTO들과 함께
disabilityTypes,mobilityAids로 변경하는 것을 고려해보세요.src/main/java/com/wayble/server/user/service/UserInfoService.java (2)
107-123: 사용자 정보 조회 메서드 구현 승인사용자 정보 조회 로직이 적절히 구현되었습니다. 필수 필드 존재 여부 확인과 DTO 매핑이 올바르게 수행됩니다.
Line 116에서
user.getBirthDate() != null체크는 불필요합니다. Line 111에서 이미 null 체크를 수행했으므로 다음과 같이 단순화할 수 있습니다:- .birthDate(user.getBirthDate() != null ? user.getBirthDate().toString() : null) + .birthDate(user.getBirthDate().toString())
125-129: 닉네임 중복 확인 메서드 구현 승인닉네임 사용 가능 여부를 확인하는 로직이 명확하게 구현되었습니다.
읽기 전용 작업이므로 성능 최적화를 위해
readOnly = true옵션을 고려해보세요:- @Transactional + @Transactional(readOnly = true) public boolean isNicknameAvailable(String nickname) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/main/java/com/wayble/server/user/controller/UserController.java(3 hunks)src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/entity/DisabilityType.java(1 hunks)src/main/java/com/wayble/server/user/entity/MobilityAid.java(1 hunks)src/main/java/com/wayble/server/user/entity/User.java(2 hunks)src/main/java/com/wayble/server/user/exception/UserErrorCase.java(2 hunks)src/main/java/com/wayble/server/user/repository/UserRepository.java(1 hunks)src/main/java/com/wayble/server/user/service/UserInfoService.java(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 im...
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.318Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
Applied to files:
src/main/java/com/wayble/server/user/entity/DisabilityType.javasrc/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.javasrc/main/java/com/wayble/server/user/entity/User.javasrc/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.javasrc/main/java/com/wayble/server/user/controller/UserController.javasrc/main/java/com/wayble/server/user/service/UserInfoService.java
🔇 Additional comments (15)
src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
21-24: 새로운 에러 케이스 정의가 적절합니다.닉네임 중복 확인 기능을 위한 3개의 새로운 에러 케이스가 잘 정의되었습니다:
USER_INFO_NOT_EXISTS: 404 상태 코드와 적절한 메시지NICKNAME_REQUIRED: 400 상태 코드로 필수 파라미터 누락 표현NICKNAME_DUPLICATED: 409 상태 코드로 중복 상황을 명확히 표현에러 코드 번호도 순차적으로 잘 할당되었습니다.
src/main/java/com/wayble/server/user/repository/UserRepository.java (1)
15-15: 닉네임 중복 확인을 위한 메서드가 잘 구현되었습니다.
existsByNickname메서드는 Spring Data JPA의 naming convention을 따르며, 닉네임 중복 확인 기능에 필요한 효율적인 구현입니다. boolean 반환 타입으로 존재 여부를 명확히 표현합니다.src/main/java/com/wayble/server/user/entity/MobilityAid.java (1)
3-8: 이동 보조기구 enum이 잘 정의되었습니다.이동 보조기구 타입을 enum으로 강타입화한 것은 좋은 리팩토링입니다. 각 상수명이 명확하고 한국어 주석도 적절합니다.
NONE값을 통해 "보조기구 없음"을 명시적으로 표현한 점도 좋습니다.src/main/java/com/wayble/server/user/entity/DisabilityType.java (1)
3-8: 장애 유형 enum이 잘 정의되었습니다.장애 유형을 enum으로 강타입화한 것은 좋은 리팩토링입니다. 4가지 주요 장애 유형(발달장애, 시각장애, 지체장애, 청각장애)을 명확히 분류하고 있으며, 각 상수명과 한국어 주석이 적절합니다.
MobilityAidenum과 일관성 있는 스타일을 유지하고 있습니다.src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java (1)
5-12: 닉네임 중복 확인 응답 DTO가 잘 설계되었습니다.Java record를 사용하여 간결하고 불변성을 보장하는 응답 DTO가 잘 구현되었습니다.
available과message필드는 닉네임 사용 가능 여부와 상세 정보를 명확히 전달합니다. Swagger 어노테이션도 API 문서화를 위해 적절히 적용되었습니다.src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java (1)
1-22: 잘 구현된 응답 DTO입니다.타입 안전성을 위해 enum을 사용한 것이 좋은 선택입니다. 구조도 엔티티와 일관성 있게 구성되어 있습니다.
src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java (1)
4-6: enum 타입 전환이 잘 구현되었습니다.String 리스트에서 enum 리스트로의 전환으로 타입 안전성이 크게 향상되었습니다.
src/main/java/com/wayble/server/user/controller/UserController.java (1)
88-102: 사용자 정보 조회 엔드포인트가 잘 구현되었습니다.인증 확인과 서비스 호출 로직이 적절합니다. API 문서화도 충실히 되어 있습니다.
src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (1)
3-6: enum 타입 전환이 일관성 있게 적용되었습니다.다른 DTO들과 동일하게 타입 안전성을 위한 enum 사용이 잘 구현되었습니다.
src/main/java/com/wayble/server/user/entity/User.java (3)
61-71: enum 타입을 위한 데이터베이스 매핑이 잘 구현되었습니다.
@ElementCollection과 별도 테이블을 사용한 것이 적절하며,FetchType.LAZY로 성능도 고려되었습니다.EnumType.STRING사용으로 가독성도 좋습니다.
126-128: setter 메서드가 적절히 업데이트되었습니다.enum 리스트 타입에 맞게 setter 메서드들이 올바르게 수정되었습니다.
61-71: SQL 마이그레이션 스크립트가 리포지토리에서 발견되지 않아 자동 검증이 불가합니다.
다음 사항을 직접 확인해주세요:
- DB 마이그레이션 도구(Flyway, Liquibase 등)와 스크립트 경로 확인
- 기존 String 컬럼에서 Enum 타입으로 변경 시 데이터 변환 로직 검토
- 어플리케이션 설정(application.properties 또는 application.yml)의 마이그레이션 설정(spring.flyway.locations 등) 점검
src/main/java/com/wayble/server/user/service/UserInfoService.java (3)
6-6: 새로운 DTO import 추가 승인getUserInfo 메서드에서 사용할 UserInfoResponseDto의 import가 적절히 추가되었습니다.
30-30: 사용자 정보 중복 검사 로직 개선기존에 nickname만 확인하던 것을 nickname, birthDate, gender 모두를 확인하도록 확장하여 더 정확한 중복 등록 방지가 가능해졌습니다.
42-42: 프로필 이미지 기능 준비 코드 승인향후 프로필 이미지 기능 구현을 위한 준비 코드가 일관성 있게 주석 처리되어 있습니다. 현재 구현에 영향을 주지 않으면서 향후 확장성을 고려한 좋은 접근입니다.
Also applies to: 84-88, 121-121
| Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
| if (!(authentication.getPrincipal() instanceof Long userId)) { | ||
| throw new ApplicationException(UserErrorCase.FORBIDDEN); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
인증 로직 중복을 해결해보세요.
여러 메서드에서 동일한 인증 확인 패턴이 반복되고 있습니다. 공통 로직을 추출하여 코드 중복을 줄이는 것을 고려해보세요.
private Long getCurrentUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication.getPrincipal() instanceof Long userId)) {
throw new ApplicationException(UserErrorCase.FORBIDDEN);
}
return userId;
}
// 사용 예시
public CommonResponse<UserInfoResponseDto> getUserInfo() {
Long userId = getCurrentUserId();
UserInfoResponseDto info = userInfoService.getUserInfo(userId);
return CommonResponse.success(info);
}🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/user/controller/UserController.java around
lines 96 to 98, there is repeated authentication logic checking the current
user's ID. To fix this, extract this repeated code into a private method named
getCurrentUserId() that retrieves and validates the user ID from the
SecurityContextHolder. Replace all occurrences of the authentication check with
calls to this new method to reduce code duplication and improve maintainability.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
src/main/java/com/wayble/server/user/entity/DisabilityType.java (1)
3-8: 타입 안전성을 위한 좋은 enum 설계입니다.String 기반 접근법에서 enum으로 변경하여 타입 안전성이 향상되었습니다. 한국어 주석도 이해에 도움이 됩니다.
주석 스타일의 일관성을 위해 다음과 같이 개선할 수 있습니다:
public enum DisabilityType { - DEVELOPMENTAL, // 발달장애 - VISUAL, // 시각장애 - PHYSICAL, // 지체장애 - AUDITORY // 청각장애 + DEVELOPMENTAL, // 발달장애 + VISUAL, // 시각장애 + PHYSICAL, // 지체장애 + AUDITORY // 청각장애 }src/main/java/com/wayble/server/user/entity/MobilityAid.java (1)
3-8: 이동보조기구를 위한 적절한 enum 설계입니다.NONE 옵션을 포함하여 다양한 이동보조기구 유형을 잘 표현했습니다. 타입 안전성 향상이 좋습니다.
DisabilityType과 동일하게 주석 정렬을 일관되게 맞출 수 있습니다:
public enum MobilityAid { - GUIDE_DOG, // 안내견 - CANE, // 지팡이 - WHEELCHAIR, // 휠체어 - NONE // 없음 + GUIDE_DOG, // 안내견 + CANE, // 지팡이 + WHEELCHAIR, // 휠체어 + NONE // 없음 }src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
6-6: HttpStatus import가 추가되었지만 사용되지 않고 있습니다.현재 코드에서는 HttpStatus를 직접 사용하지 않고 있습니다. 향후 사용 계획이 있다면 유지하고, 그렇지 않다면 제거를 고려해보세요.
src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java (1)
10-10: 사용되지 않는 import가 있습니다.
Patternimport가 추가되었지만 현재 주석 처리된 코드에서만 사용되고 있습니다. 향후 사용 예정이라면 문제없지만, 당장 사용하지 않는다면 제거를 고려해보세요.src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (1)
7-7: 사용되지 않는 import입니다.
Patternimport가 주석 처리된 코드에서만 사용되고 있습니다. 필요시에만 import하는 것을 권장합니다.src/main/java/com/wayble/server/user/entity/User.java (2)
126-126: Null 안전성 고려해보세요현재 setter는 null 값을 그대로 할당할 수 있습니다. 방어적 프로그래밍을 위해 null 체크를 추가하는 것을 고려해보세요.
-public void setDisabilityType(List<DisabilityType> disabilityType) { this.disabilityType = disabilityType; } +public void setDisabilityType(List<DisabilityType> disabilityType) { + this.disabilityType = disabilityType != null ? disabilityType : new ArrayList<>(); +}
128-128: 일관성을 위해 동일한 null 처리 추가 권장
setDisabilityType과 마찬가지로 null 안전성을 추가하면 좋겠습니다.-public void setMobilityAid(List<MobilityAid> mobilityAid) { this.mobilityAid = mobilityAid; } +public void setMobilityAid(List<MobilityAid> mobilityAid) { + this.mobilityAid = mobilityAid != null ? mobilityAid : new ArrayList<>(); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/main/java/com/wayble/server/user/controller/UserController.java(3 hunks)src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/entity/DisabilityType.java(1 hunks)src/main/java/com/wayble/server/user/entity/MobilityAid.java(1 hunks)src/main/java/com/wayble/server/user/entity/User.java(2 hunks)src/main/java/com/wayble/server/user/exception/UserErrorCase.java(2 hunks)src/main/java/com/wayble/server/user/repository/UserRepository.java(1 hunks)src/main/java/com/wayble/server/user/service/UserInfoService.java(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 im...
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.318Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
Applied to files:
src/main/java/com/wayble/server/user/entity/DisabilityType.javasrc/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.javasrc/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.javasrc/main/java/com/wayble/server/user/entity/User.javasrc/main/java/com/wayble/server/user/service/UserInfoService.javasrc/main/java/com/wayble/server/user/controller/UserController.java
🔇 Additional comments (11)
src/main/java/com/wayble/server/user/repository/UserRepository.java (1)
15-15: LGTM! 올바른 Spring Data JPA 메서드 시그니처입니다.Spring Data JPA의 네이밍 컨벤션을 정확히 따르고 있으며, 닉네임 중복 확인 기능에 적합한 메서드입니다.
src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java (1)
5-12: 깔끔한 DTO record 설계입니다.Java record를 사용하여 불변 객체로 구현하였고, Swagger 문서화 애노테이션도 적절히 사용되었습니다. 필드명과 타입이 명확합니다.
src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
22-24: 닉네임 검증을 위한 적절한 오류 케이스들입니다.
- USER_INFO_NOT_EXISTS (404): 사용자 정보 없음에 적합
- NICKNAME_REQUIRED (400): 필수 파라미터 누락에 적합
- NICKNAME_DUPLICATED (409): 리소스 충돌에 적합
HTTP 상태 코드와 오류 메시지가 각 상황에 적절하게 설정되었습니다.
src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java (1)
12-22: 잘 구현된 응답 DTO입니다.Lombok의
@Builder와@Getter어노테이션을 적절히 사용했고, String 대신 enum 타입을 사용하여 타입 안전성을 확보한 점이 좋습니다. 주석 처리된profileImageUrl필드도 향후 확장성을 고려한 적절한 설계입니다.src/main/java/com/wayble/server/user/service/UserInfoService.java (1)
125-129: 깔끔한 닉네임 중복 확인 구현입니다.Repository의
existsByNickname메서드를 활용하여 간단하고 명확하게 구현했습니다. 반환값도 직관적입니다.src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java (1)
4-6: enum 타입 전환이 잘 구현되었습니다.
DisabilityType과MobilityAidenum을 사용하여 기존List<String>대신 타입 안전성을 확보한 점이 우수합니다.src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (1)
3-6: 일관된 enum 타입 적용이 잘되었습니다.다른 DTO들과 일관되게
DisabilityType과MobilityAidenum을 사용하여 타입 안전성을 향상시켰습니다.src/main/java/com/wayble/server/user/controller/UserController.java (2)
88-102: 사용자 정보 조회 엔드포인트가 잘 구현되었습니다.인증 확인, Swagger 문서화, 에러 처리가 모두 적절하게 구현되어 있습니다. 기존 패턴과 일관성도 유지되고 있습니다.
104-119: 닉네임 중복 확인 API가 견고하게 구현되었습니다.입력값 검증(
null및 빈 문자열 체크),trim()처리, 적절한 예외 처리가 모두 포함되어 있어 안정적인 API입니다. 응답 메시지도 사용자 친화적입니다.src/main/java/com/wayble/server/user/entity/User.java (2)
61-65: 변경사항이 적절합니다!
@ElementCollection과@Enumerated(EnumType.STRING)을 사용한 enum 리스트 구현이 JPA 베스트 프랙티스를 잘 따르고 있습니다. 특히EnumType.STRING사용은 데이터베이스 가독성과 enum 순서 변경에 대한 안정성을 제공합니다.
67-71: 일관된 구현으로 좋습니다!
mobilityAid필드도disabilityType과 동일한 패턴으로 구현되어 코드 일관성이 유지되고 있습니다.
| if (user.getNickname() == null || user.getBirthDate() == null || user.getGender() == null) { | ||
| throw new ApplicationException(UserErrorCase.USER_INFO_NOT_EXISTS); | ||
| } | ||
| return UserInfoResponseDto.builder() | ||
| .nickname(user.getNickname()) | ||
| .birthDate(user.getBirthDate() != null ? user.getBirthDate().toString() : null) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
불필요한 null 체크가 있습니다.
Line 111에서 이미 user.getBirthDate() == null을 확인했는데, Line 116에서 다시 user.getBirthDate() != null ? user.getBirthDate().toString() : null을 체크하고 있습니다. Line 111의 검증을 통과했다면 birthDate는 null이 아니므로 삼항 연산자가 불필요합니다.
- .birthDate(user.getBirthDate() != null ? user.getBirthDate().toString() : null)
+ .birthDate(user.getBirthDate().toString())📝 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 (user.getNickname() == null || user.getBirthDate() == null || user.getGender() == null) { | |
| throw new ApplicationException(UserErrorCase.USER_INFO_NOT_EXISTS); | |
| } | |
| return UserInfoResponseDto.builder() | |
| .nickname(user.getNickname()) | |
| .birthDate(user.getBirthDate() != null ? user.getBirthDate().toString() : null) | |
| if (user.getNickname() == null || user.getBirthDate() == null || user.getGender() == null) { | |
| throw new ApplicationException(UserErrorCase.USER_INFO_NOT_EXISTS); | |
| } | |
| return UserInfoResponseDto.builder() | |
| .nickname(user.getNickname()) | |
| .birthDate(user.getBirthDate().toString()) |
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/user/service/UserInfoService.java around
lines 111 to 116, remove the redundant null check for user.getBirthDate() in the
ternary operator on line 116 since line 111 already ensures birthDate is not
null. You can directly call user.getBirthDate().toString() without the
conditional check.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/main/java/com/wayble/server/user/controller/UserController.java (2)
5-5: 와일드카드 임포트 사용에 대한 고려사항DTO 패키지에서 와일드카드 임포트(
import com.wayble.server.user.dto.*;)를 사용하고 있습니다. 특정 클래스만 임포트하는 것이 코드의 명확성과 유지보수성 측면에서 더 좋을 수 있습니다.-import com.wayble.server.user.dto.*; +import com.wayble.server.user.dto.UserInfoRegisterRequestDto; +import com.wayble.server.user.dto.UserInfoUpdateRequestDto; +import com.wayble.server.user.dto.UserInfoResponseDto; +import com.wayble.server.user.dto.NicknameCheckResponse; +import com.wayble.server.user.dto.UserRegisterRequestDto;
88-102: 새로운 사용자 정보 조회 API가 잘 구현되었습니다!API 구현이 기존 패턴을 잘 따르고 있으며, 인증 처리와 에러 핸들링이 적절합니다. Swagger 문서화도 충분히 제공되어 있습니다.
인증 로직이 여러 메서드에서 중복되고 있습니다. 다음과 같이 헬퍼 메서드로 추출하면 코드 중복을 줄일 수 있습니다:
+ private Long getCurrentUserId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication.getPrincipal() instanceof Long userId)) { + throw new ApplicationException(UserErrorCase.FORBIDDEN); + } + return userId; + } + public CommonResponse<UserInfoResponseDto> getUserInfo() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication.getPrincipal() instanceof Long userId)) { - throw new ApplicationException(UserErrorCase.FORBIDDEN); - } + Long userId = getCurrentUserId(); UserInfoResponseDto info = userInfoService.getUserInfo(userId); return CommonResponse.success(info); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/main/java/com/wayble/server/user/controller/UserController.java(3 hunks)src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java(2 hunks)src/main/java/com/wayble/server/user/entity/DisabilityType.java(1 hunks)src/main/java/com/wayble/server/user/entity/MobilityAid.java(1 hunks)src/main/java/com/wayble/server/user/entity/User.java(2 hunks)src/main/java/com/wayble/server/user/exception/UserErrorCase.java(2 hunks)src/main/java/com/wayble/server/user/repository/UserRepository.java(1 hunks)src/main/java/com/wayble/server/user/service/UserInfoService.java(5 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 im...
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.318Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
Applied to files:
src/main/java/com/wayble/server/user/entity/DisabilityType.javasrc/main/java/com/wayble/server/user/service/UserInfoService.javasrc/main/java/com/wayble/server/user/exception/UserErrorCase.javasrc/main/java/com/wayble/server/user/entity/User.javasrc/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.javasrc/main/java/com/wayble/server/user/controller/UserController.javasrc/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java
🔇 Additional comments (17)
src/main/java/com/wayble/server/user/repository/UserRepository.java (1)
15-15: LGTM! 닉네임 중복 체크 메서드가 올바르게 구현되었습니다.Spring Data JPA의 네이밍 컨벤션을 잘 따르고 있으며, 기존 코드 스타일과 일관성을 유지하고 있습니다.
src/main/java/com/wayble/server/user/entity/DisabilityType.java (1)
3-8: LGTM! 장애 유형을 enum으로 정의한 것이 좋은 개선사항입니다.문자열 리스트에서 강타입 enum으로 전환하여 타입 안전성을 높였고, 한국어 주석으로 각 enum 값의 의미를 명확히 했습니다.
src/main/java/com/wayble/server/user/entity/MobilityAid.java (1)
3-8: LGTM! 보조기구 enum이 잘 정의되었습니다.DisabilityType과 일관된 패턴으로 구현되었고, NONE 값을 포함하여 보조기구가 없는 경우도 적절히 고려했습니다.
src/main/java/com/wayble/server/user/dto/NicknameCheckResponse.java (1)
5-12: LGTM! 닉네임 체크 응답 DTO가 잘 구현되었습니다.record 클래스를 사용하여 간결하고 현대적으로 구현했으며, Swagger 애노테이션으로 API 문서화도 적절히 되어 있습니다.
src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
22-24: LGTM! 새로운 에러 케이스들이 적절하게 정의되었습니다.각 에러 케이스의 HTTP 상태 코드와 메시지가 상황에 맞게 잘 정의되어 있습니다:
- USER_INFO_NOT_EXISTS: 404 Not Found
- NICKNAME_REQUIRED: 400 Bad Request
- NICKNAME_DUPLICATED: 409 Conflict
src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (2)
3-5: 타입 안전성 개선으로 코드 품질 향상
disabilityType과mobilityAid필드를List<String>에서 강타입 enum 리스트로 변경한 것은 타입 안전성을 크게 개선합니다. 이는 런타임 오류를 방지하고 유효하지 않은 값의 입력을 컴파일 타임에 차단할 수 있습니다.Also applies to: 18-19
20-23: 일관성 있는 미래 기능 준비
profileImageUrl필드를 주석 처리하고 URL 패턴 검증을 추가한 것은 다른 DTO들과 일관성을 유지하며 미래 기능 확장에 대비한 좋은 접근입니다.src/main/java/com/wayble/server/user/dto/UserInfoResponseDto.java (1)
12-22: 잘 설계된 응답 DTO 클래스새로운
UserInfoResponseDto클래스가 다음과 같은 좋은 설계 패턴을 보여줍니다:
- Lombok
@Builder패턴으로 유연한 객체 생성 지원- 다른 DTO들과 일관된 enum 타입 사용
- 미래 기능(프로필 이미지)에 대한 일관된 주석 처리 방식
src/main/java/com/wayble/server/user/dto/UserInfoRegisterRequestDto.java (2)
4-6: 일관된 타입 안전성 개선다른 DTO들과 동일하게
DisabilityType과MobilityAidenum을 사용하여 타입 안전성을 개선했습니다. 이는 전체 애플리케이션에서 일관된 데이터 타입 사용을 보장합니다.Also applies to: 32-34
36-39: 미래 확장성을 고려한 설계
profileImageUrl필드의 주석 처리와 URL 패턴 검증 준비는 다른 DTO들과 일관성을 유지하며 향후 기능 확장에 대비한 좋은 접근 방식입니다.src/main/java/com/wayble/server/user/entity/User.java (2)
61-65: JPA 엔티티 매핑이 올바르게 구성됨
@ElementCollection과@CollectionTable을 사용한 enum 컬렉션 매핑이 적절히 구성되었습니다:
FetchType.LAZY로 성능 최적화@Enumerated(EnumType.STRING)으로 가독성 확보- 별도 조인 테이블로 정규화된 구조
Also applies to: 67-71
126-128: setter 메서드가 적절히 업데이트됨enum 타입으로 변경된 필드들에 대한 setter 메서드가 올바르게 업데이트되었습니다.
src/main/java/com/wayble/server/user/service/UserInfoService.java (3)
30-30: 사용자 정보 등록 검증 로직 개선기존에
nickname만 확인하던 것을nickname,birthDate,gender모두 확인하도록 확장한 것은 더 포괄적인 중복 등록 방지 로직입니다.
107-123: 사용자 정보 조회 메서드 구현 완료
getUserInfo메서드가 적절히 구현되었습니다:
- 사용자 존재 여부 확인
- 필수 정보 존재 여부 검증
- Builder 패턴으로 응답 DTO 생성
@Transactional어노테이션으로 트랜잭션 관리
125-129: 닉네임 중복 확인 로직 및 메서드 정의 검증 완료
UserRepository에boolean existsByNickname(String nickname)메서드가 정상적으로 선언되어 있는 것이 확인되었습니다.UserInfoService.isNicknameAvailable()구현도 간결하며 의도한 대로 작동합니다.해당 변경사항은 문제없으므로 머지해도 좋습니다.
src/main/java/com/wayble/server/user/controller/UserController.java (2)
68-68: 문서화 개선이 잘 되었습니다!API 설명이 더 명확하고 구체적으로 작성되어 사용자가 이해하기 쉽게 개선되었습니다.
104-119: API 설계 검증 요청: 닉네임 중복 확인 응답 방식
현재 구현에서는
- 닉네임이 중복되면 ApplicationException을 통해 409 상태 코드를 반환
- 사용 가능할 때만 200 상태 코드와 CommonResponse.success(...) 형태로 응답
를 적용하고 있습니다.
“체크” API 관점에서 대안으로는, 항상 200 상태 코드를 유지하면서 응답 본문에
{ available: false }또는{ available: true }형식으로 중복 여부를 전달하는 방식도 있습니다.PR 목표 및 클라이언트 사용성을 고려했을 때, 현 구현 방식이 의도된 설계인지 확인 부탁드립니다.
|
|
||
| @Convert(converter = StringListConverter.class) | ||
| @ElementCollection(fetch = FetchType.LAZY) | ||
| @CollectionTable(name = "user_disability_type", joinColumns = @JoinColumn(name = "user_id")) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
테이블 명명 규칙 일관성 확인 필요
조인 테이블명이 user_disability_type, user_mobility_aid로 설정되어 있습니다. 프로젝트의 다른 테이블 명명 규칙과 일관성을 유지하는지 확인해 주세요.
다음 스크립트로 프로젝트 내 다른 테이블 명명 규칙을 확인할 수 있습니다:
Also applies to: 68-68
🏁 Script executed:
#!/bin/bash
# 프로젝트 내 다른 @Table, @CollectionTable 어노테이션의 명명 규칙 확인
rg -A 2 -B 1 "@(Table|CollectionTable)" --type javaLength of output: 6566
테이블 명명 규칙 일관성 검토 및 수정 필요
현재 프로젝트 내 테이블은 모두 snake_case로 통일되어 있으나, 매핑용 조인 테이블은 _mapping 접미사를 사용하고 있습니다.
반면 @CollectionTable로 생성된 user_disability_type, user_mobility_aid에는 해당 접미사가 빠져 있어 명명 규칙이 일관되지 않습니다.
-
수정 대상
- src/main/java/com/wayble/server/user/entity/User.java
- 62번 줄 (
@CollectionTable(name = "user_disability_type", …)) - 68번 줄 (
@CollectionTable(name = "user_mobility_aid", …))
- 62번 줄 (
- src/main/java/com/wayble/server/user/entity/User.java
-
권장 변경안
- @CollectionTable(name = "user_disability_type", joinColumns = @JoinColumn(name = "user_id")) + @CollectionTable(name = "user_disability_type_mapping", joinColumns = @JoinColumn(name = "user_id")) - @CollectionTable(name = "user_mobility_aid", joinColumns = @JoinColumn(name = "user_id")) + @CollectionTable(name = "user_mobility_aid_mapping", joinColumns = @JoinColumn(name = "user_id"))
위와 같이 _mapping 접미사를 추가하거나, 반대로 기존 UserDisabilityMapping, UserPlaceWaybleZoneMapping 등 매핑 테이블에서 _mapping을 제거하는 방향으로 프로젝트 전체 명명 규칙을 재검토하여 통일성을 확보해 주세요.
📝 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.
| @CollectionTable(name = "user_disability_type", joinColumns = @JoinColumn(name = "user_id")) | |
| // line 62 | |
| @CollectionTable( | |
| name = "user_disability_type_mapping", | |
| joinColumns = @JoinColumn(name = "user_id") | |
| ) | |
| // line 68 | |
| @CollectionTable( | |
| name = "user_mobility_aid_mapping", | |
| joinColumns = @JoinColumn(name = "user_id") | |
| ) |
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/user/entity/User.java at lines 62 and 68, the
@CollectionTable annotations use table names "user_disability_type" and
"user_mobility_aid" which lack the "_mapping" suffix used elsewhere for join
tables, causing inconsistency with the project's snake_case naming convention.
To fix this, rename these tables by adding the "_mapping" suffix to match the
convention, or alternatively, remove the "_mapping" suffix from other mapping
tables across the project to unify the naming scheme. Ensure the chosen approach
is applied consistently throughout the project.
| import com.wayble.server.common.exception.ErrorCase; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
사용되지 않는 import 확인이 필요합니다.
HttpStatus import가 추가되었지만 현재 코드에서 실제로 사용되지 않는 것 같습니다. 필요하지 않다면 제거하는 것이 좋겠습니다.
다음 스크립트로 HttpStatus가 실제로 사용되는지 확인해보겠습니다:
🏁 Script executed:
#!/bin/bash
# HttpStatus 사용 여부 확인
rg -n "HttpStatus" src/main/java/com/wayble/server/user/exception/UserErrorCase.javaLength of output: 130
미사용 import 제거 필요: HttpStatus 삭제
UserErrorCase.java 파일에서 HttpStatus가 참조되지 않으므로 아래 import 문을 제거해주세요.
- 파일:
src/main/java/com/wayble/server/user/exception/UserErrorCase.java - 제거 라인: 6 (
import org.springframework.http.HttpStatus;)
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/user/exception/UserErrorCase.java at line 6,
remove the unused import statement 'import org.springframework.http.HttpStatus;'
since HttpStatus is not referenced anywhere in the file.
✔️ 연관 이슈
📝 작업 내용
🖼️ 스크린샷 (선택)
닉네임 중복 X (성공)
닉네임 파라미터 X (실패)
닉네임 중복 (실패)
💬 리뷰 요구사항 (선택)
Summary by CodeRabbit
신규 기능
개선 사항
버그 수정
기타