Skip to content

[FEAT] 닉네임, 이메일 중복검사 API 개발#100

Merged
Be-HinD merged 2 commits intomainfrom
feat/validate-duplicate
Dec 12, 2025
Merged

[FEAT] 닉네임, 이메일 중복검사 API 개발#100
Be-HinD merged 2 commits intomainfrom
feat/validate-duplicate

Conversation

@Be-HinD
Copy link
Member

@Be-HinD Be-HinD commented Dec 12, 2025

📝 Pull Request

📌 PR 종류

해당하는 항목에 체크해주세요.

  • 기능 추가 (Feature)
  • 버그 수정 (Fix)
  • 문서 수정 (Docs)
  • 코드 리팩터링 (Refactor)
  • 테스트 추가 (Test)
  • 기타 변경 (Chore)

✨ 변경 내용

  • 이메일 중복검사 API 개발

  • 닉네임 중복검사 API 개발

  • MissingServletRequestParameterException 에러 핸들링


🔍 관련 이슈

해당 PR이 해결하는 이슈가 있다면 연결해주세요.
Closes #86


🧪 테스트

변경된 기능에 대한 테스트 범위 또는 테스트 결과를 작성해주세요.

  • 유닛 테스트 추가 / 수정
  • 통합 테스트 검증
  • 수동 테스트 완료
image

🚨 확인해야 할 사항 (Checklist)

PR을 제출하기 전에 아래 항목들을 확인해주세요.

  • 코드 포매팅 완료
  • 불필요한 파일/코드 제거
  • 로직 검증 완료
  • 프로젝트 빌드 성공
  • 린트/정적 분석 통과 (해당 시)

🙋 기타 참고 사항

리뷰어가 참고하면 좋을 만한 추가 설명이 있다면 적어주세요.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 프로필 이미지 업로드, 프로필 정보 수정, 알림 설정 변경 추가
    • 팔로우/언팔로우 API 추가
    • 이메일·닉네임 중복 확인 API 추가 (AvailabilityResponse 반환)
  • 보안

    • 공개 사용자 엔드포인트 접근 범위가 /api/v1/users/**로 확대됨
  • 버그 수정 / 예외 처리

    • 누락된 요청 파라미터에 대한 400 응답 처리 추가
  • 기타

    • 테스트 엔드포인트 제거 및 테스트 시나리오 업데이트

✏️ Tip: You can customize this high-level summary in your review settings.

@Be-HinD Be-HinD self-assigned this Dec 12, 2025
@Be-HinD Be-HinD added the ✨enhancement New feature or request label Dec 12, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 12, 2025

Walkthrough

사용자 관련 API에 이메일/닉네임 중복 검사와 프로필(이미지/정보/알림) 및 팔로우/언팔로우 엔드포인트를 추가하고, /api/v1/users 경로의 보안 공개 패턴을 /api/v1/users/**로 확장했으며 테스트 엔드포인트를 제거했습니다.

Changes

Cohort / File(s) Change Summary
보안 설정 변경
src/main/java/team/wego/wegobackend/common/security/JwtAuthenticationFilter.java, src/main/java/team/wego/wegobackend/common/security/SecurityConfig.java
GET /api/v1/users 공개 엔드포인트 패턴을 /api/v1/users/*에서 /api/v1/users/**로 확장(모든 하위 경로를 공개 대상으로 포함)
가용성 확인 도메인 추가
src/main/java/team/wego/wegobackend/user/application/UserService.java, src/main/java/team/wego/wegobackend/user/application/dto/response/AvailabilityResponse.java
이메일/닉네임 가용성 확인용 메서드 2개 추가(@Transactional(readOnly = true)) 및 AvailabilityResponse 레코드 추가
사용자 컨트롤러 확장
src/main/java/team/wego/wegobackend/user/presentation/UserController.java, src/main/java/team/wego/wegobackend/user/presentation/UserControllerDocs.java
프로필 이미지/정보/알림 수정, 팔로우/언팔로우, 이메일/닉네임 가용성 검사 등 여러 엔드포인트 추가 및 기존 테스트 엔드포인트 제거
예외 처리 추가
src/main/java/team/wego/wegobackend/common/exception/AppErrorCode.java, src/main/java/team/wego/wegobackend/common/exception/GlobalExceptionHandler.java
NOT_FOUND_PARAMETER AppErrorCode 추가 및 MissingServletRequestParameterException에 대한 핸들러 추가(400 응답)
테스트 시나리오 업데이트
src/test/http/user/user-api.http
회원가입 페이로드 일부 수정(이메일/닉네임) 및 이메일/닉네임 가용성 호출 시나리오 추가

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 검토 포인트:
    • 보안 설정에서 /api/v1/users/**로 패턴 확장 의도 확인(공개 범위 범함).
    • 새 가용성 메서드의 DB 존재 체크(Repository 메서드 이름 일치 및 성능) 확인.
    • UserController의 새 엔드포인트들에 대한 입력 검증과 예외 처리(특히 MultipartFile, @RequestParam 필수 여부).
    • MissingServletRequestParameterException 핸들러가 기존 오류 응답 포맷과 일관되는지 확인.

Possibly related PRs

Poem

🐰 냠냠, 중복 검사 뚝딱했네,
이메일과 닉네임 깔끔히 살피고,
프로필 고치고 팔로우도 척척,
경로는 넓혔으니 모두 모여라,
당근 키우며 배포 축하해! 🥕🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.03% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 핵심 내용인 이메일 및 닉네임 중복검사 API 개발을 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed 이메일과 닉네임 중복검사 API 개발 요구사항이 모두 구현되었으며, 관련된 예외 처리와 보안 설정도 추가되었습니다.
Out of Scope Changes check ✅ Passed 공개 엔드포인트 경로 패턴 변경(/api/v1/users/* → /api/v1/users/**)은 새로운 엔드포인트 접근을 위한 필요한 설정이며, 기타 모든 변경사항이 중복검사 기능 개발과 관련이 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/validate-duplicate

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/team/wego/wegobackend/common/security/SecurityConfig.java (1)

35-44: SecurityConfig에서 GET /api/v1/users/** permitAll은 민감한 사용자 정보를 과도하게 노출함

현재 GET /api/v1/users/** 전체를 permitAll로 허용하면, 중복검사 엔드포인트(/email/availability, /nickname/availability)뿐만 아니라 사용자 프로필 조회 엔드포인트(GET /{userId})도 공개됩니다. 프로필 조회는 email, mbti, 알림 설정 여부 등 민감한 사용자 정보를 포함한 UserInfoResponse를 반환하므로, 인증 없이 누구나 모든 사용자의 이메일을 조회할 수 있게 됩니다.

권장사항: 중복검사 엔드포인트만 명시적으로 허용하고 나머지 사용자 관련 GET 요청은 인증을 요구하도록 수정하세요.

.requestMatchers(HttpMethod.GET, "/api/v1/users/email/availability").permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/users/nickname/availability").permitAll()

(JwtAuthenticationFilter의 라인 126-128 TODO 주석도 이 관리 포인트 개선이 필요함을 언급하고 있습니다.)

src/main/java/team/wego/wegobackend/common/security/JwtAuthenticationFilter.java (1)

118-142: /api/v1/group (단수형) 라인 135는 실제 컨트롤러 매핑이 없는 데드코드임
SecurityConfig 및 GroupController 모두 /api/v1/groups (복수형)으로 정의되어 있으나, JwtAuthenticationFilter 라인 135의 /api/v1/group (단수형)은 어디에도 매핑되지 않은 패턴입니다. 이는 의도하지 않은 타이핑 오류이거나 제거되지 않은 레거시 코드로 보이며, 정확한 의도 확인 후 제거하거나 수정이 필요합니다.

(참고: GET /api/v1/users/**는 SecurityConfig 라인 38에서 명시적으로 permitAll()로 설정되어 있고, 해당 엔드포인트들(/{userId}, /email/availability, /nickname/availability)이 모두 인증 장식자 없이 설계되어 있으므로 의도된 공개 설정입니다.)

🧹 Nitpick comments (2)
src/main/java/team/wego/wegobackend/user/application/dto/response/AvailabilityResponse.java (1)

1-5: JavaDoc 추가를 고려하세요.

available 필드의 의미(true = 사용 가능, false = 이미 사용 중)를 명확히 하기 위해 JavaDoc 추가를 권장합니다. 이는 API를 사용하는 개발자의 혼동을 방지할 수 있습니다.

다음과 같이 JavaDoc을 추가할 수 있습니다:

 package team.wego.wegobackend.user.application.dto.response;
 
+/**
+ * 이메일 또는 닉네임 사용 가능 여부를 나타내는 응답 DTO
+ *
+ * @param available true인 경우 사용 가능, false인 경우 이미 사용 중
+ */
 public record AvailabilityResponse(boolean available) {
 
 }
src/main/java/team/wego/wegobackend/user/presentation/UserControllerDocs.java (1)

55-55: API 설명을 더 명확하게 작성하세요.

@Operation 설명에서 "bool값"이라고만 표현되어 있어, true/false가 각각 무엇을 의미하는지 명확하지 않습니다. API 사용자의 이해를 돕기 위해 더 자세한 설명을 권장합니다.

다음과 같이 설명을 개선할 수 있습니다:

-    @Operation(summary = "이메일 중복 검사 API", description = "이메일 중복검사에 대한 응답은 bool값입니다.")
+    @Operation(summary = "이메일 중복 검사 API", description = "이메일 사용 가능 여부를 확인합니다. available=true인 경우 사용 가능, false인 경우 이미 사용 중입니다.")
     ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
         @RequestParam("email") String email
     );
 
-    @Operation(summary = "닉네임 중복 검사 API", description = "닉네임 중복검사에 대한 응답은 bool값입니다.")
+    @Operation(summary = "닉네임 중복 검사 API", description = "닉네임 사용 가능 여부를 확인합니다. available=true인 경우 사용 가능, false인 경우 이미 사용 중입니다.")
     ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
         @RequestParam("nickname") String nickname
     );

Also applies to: 60-60

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff87025 and 9e205f6.

📒 Files selected for processing (7)
  • src/main/java/team/wego/wegobackend/common/security/JwtAuthenticationFilter.java (1 hunks)
  • src/main/java/team/wego/wegobackend/common/security/SecurityConfig.java (1 hunks)
  • src/main/java/team/wego/wegobackend/user/application/UserService.java (3 hunks)
  • src/main/java/team/wego/wegobackend/user/application/dto/response/AvailabilityResponse.java (1 hunks)
  • src/main/java/team/wego/wegobackend/user/presentation/UserController.java (7 hunks)
  • src/main/java/team/wego/wegobackend/user/presentation/UserControllerDocs.java (2 hunks)
  • src/test/http/user/user-api.http (2 hunks)
🔇 Additional comments (2)
src/test/http/user/user-api.http (1)

74-78: 새로운 중복 검사 엔드포인트가 올바르게 추가되었습니다.

이메일과 닉네임 중복 검사를 위한 공개 엔드포인트가 적절하게 추가되었습니다. 인증 헤더가 없는 것은 회원가입 전에 중복 검사를 수행해야 하는 요구사항에 부합합니다.

src/main/java/team/wego/wegobackend/user/presentation/UserController.java (1)

39-41: 메서드 주석이 추가되어 가독성이 향상되었습니다.

각 엔드포인트에 한글 주석이 추가되어 코드의 가독성과 유지보수성이 개선되었습니다.

Also applies to: 53-55, 69-71, 85-87, 102-104, 118-120, 134-136, 149-151

@@ -1,5 +1,6 @@
package team.wego.wegobackend.user.application;

import java.util.Optional;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

사용하지 않는 import를 제거하세요.

java.util.Optional import가 추가되었지만 파일 내에서 사용되지 않습니다.

다음 diff를 적용하여 제거하세요:

 package team.wego.wegobackend.user.application;
 
-import java.util.Optional;
 import lombok.RequiredArgsConstructor;
🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/application/UserService.java around
line 3, remove the unused import statement "import java.util.Optional;" since
Optional is not referenced in this file; update the imports by deleting that
line so the file compiles without unused-import warnings.

Comment on lines +81 to +85
@Transactional(readOnly = true)
public AvailabilityResponse checkEmailAvailability(String email) {

return new AvailabilityResponse(!userRepository.existsByEmail(email));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

입력 검증 로직을 추가하세요.

이메일 중복 검사 메서드에 입력 검증이 전혀 없습니다. null, 빈 문자열, 잘못된 형식의 이메일이 전달될 경우 예기치 않은 동작이나 NPE가 발생할 수 있습니다. 컨트롤러 레벨의 검증만으로는 부족하며, 서비스 레벨에서도 방어적 검증이 필요합니다.

다음 diff를 적용하여 입력 검증을 추가하세요:

+import org.springframework.util.StringUtils;
+import team.wego.wegobackend.common.exception.InvalidInputException;
+
     @Transactional(readOnly = true)
     public AvailabilityResponse checkEmailAvailability(String email) {
-
+        if (!StringUtils.hasText(email)) {
+            throw new InvalidInputException("이메일은 필수 입력값입니다.");
+        }
+        
+        // 추가적으로 이메일 형식 검증 로직이 있다면 여기에 추가
+        
         return new AvailabilityResponse(!userRepository.existsByEmail(email));
     }

참고: InvalidInputException이 존재하지 않는다면 적절한 커스텀 예외를 생성하거나 IllegalArgumentException을 사용할 수 있습니다.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/application/UserService.java around
lines 81 to 85, add defensive input validation to checkEmailAvailability: verify
that email is not null and not blank, validate it matches a reasonable email
pattern (or use a standard email validator), and if validation fails throw
InvalidInputException (or IllegalArgumentException if no custom exception
exists); only after validation call userRepository.existsByEmail(email) and
return the AvailabilityResponse. Ensure the validation logic is service-level
(in this method) so null/empty/invalid formats are rejected before repository
access.

Comment on lines +87 to +91
@Transactional(readOnly = true)
public AvailabilityResponse checkNicknameAvailability(String nickname) {

return new AvailabilityResponse(!userRepository.existsByNickName(nickname));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

입력 검증 로직을 추가하세요.

닉네임 중복 검사 메서드에도 입력 검증이 누락되어 있습니다. null이나 빈 문자열이 전달될 경우 문제가 발생할 수 있습니다.

다음 diff를 적용하여 입력 검증을 추가하세요:

     @Transactional(readOnly = true)
     public AvailabilityResponse checkNicknameAvailability(String nickname) {
-
+        if (!StringUtils.hasText(nickname)) {
+            throw new InvalidInputException("닉네임은 필수 입력값입니다.");
+        }
+        
         return new AvailabilityResponse(!userRepository.existsByNickName(nickname));
     }
📝 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.

Suggested change
@Transactional(readOnly = true)
public AvailabilityResponse checkNicknameAvailability(String nickname) {
return new AvailabilityResponse(!userRepository.existsByNickName(nickname));
}
@Transactional(readOnly = true)
public AvailabilityResponse checkNicknameAvailability(String nickname) {
if (!StringUtils.hasText(nickname)) {
throw new InvalidInputException("닉네임은 필수 입력값입니다.");
}
return new AvailabilityResponse(!userRepository.existsByNickName(nickname));
}
🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/application/UserService.java around
lines 87-91, the checkNicknameAvailability method lacks input validation for
null or empty nicknames; add validation at the start to reject null/blank values
(e.g., trim and check empty or use StringUtils.hasText) and throw an
IllegalArgumentException (or a domain-specific exception) with a clear message
like "nickname must not be null or empty" before proceeding to call
userRepository.existsByNickName; then keep returning new
AvailabilityResponse(!userRepository.existsByNickName(nickname.trim())).

Comment on lines +137 to +147
@GetMapping("/email/availability")
public ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") String email
) {

AvailabilityResponse response = userService.checkEmailAvailability(email);

//TODO : 팔로워 목록 조회 API
return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(200, response));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's read the UserController file to see the current state
cat -n src/main/java/team/wego/wegobackend/user/presentation/UserController.java | sed -n '130,155p'

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 1020


🏁 Script executed:

#!/bin/bash
# Check the imports in UserController
cat -n src/main/java/team/wego/wegobackend/user/presentation/UserController.java | head -50

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 2636


🏁 Script executed:

#!/bin/bash
# Find Spring Security configuration files
fd -e java -path '*/config/*' | rg -i security | head -20

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 238


🏁 Script executed:

#!/bin/bash
# Check for validation annotations usage in the project
rg '@NotBlank|@Email' --type=java -l | head -10

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 416


🏁 Script executed:

#!/bin/bash
# Look for Spring Security permitAll or authentication configuration
rg -n 'permitAll|anonymous|WebSecurityConfigurerAdapter' --type=java -A3 -B3 | head -100

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 1562


🏁 Script executed:

#!/bin/bash
# Check how other endpoints handle email validation in request DTOs
cat src/main/java/team/wego/wegobackend/auth/application/dto/request/SignupRequest.java

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 971


🏁 Script executed:

#!/bin/bash
# Check if UserService validates the email parameter
rg -n 'checkEmailAvailability' -A10 src/main/java/team/wego/wegobackend/user/application/UserService.java

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 477


🏁 Script executed:

#!/bin/bash
# Look for validation configuration in the project
rg -n '@Configuration|@Bean|Validator' --type=java src/main/java/team/wego/wegobackend/common | head -30

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 752


🏁 Script executed:

#!/bin/bash
# Check if there are any global exception handlers for validation errors
rg -n '@ControllerAdvice|@ExceptionHandler|MethodArgumentNotValidException' --type=java -A5 | head -50

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 6066


🏁 Script executed:

#!/bin/bash
# Verify if @Validated is present at class or method level
rg -n '@Validated' src/main/java/team/wego/wegobackend/user/presentation/UserController.java

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Check the complete GlobalExceptionHandler to see if ConstraintViolationException is truly handled
cat -n src/main/java/team/wego/wegobackend/common/exception/GlobalExceptionHandler.java | sed -n '73,90p'

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 1008


🏁 Script executed:

#!/bin/bash
# Check if any controller in the project uses @Validated
rg -n '@Validated' src/main/java/team/wego/wegobackend --type=java -B2 | head -40

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 52


🏁 Script executed:

#!/bin/bash
# Check how other controllers handle parameter validation
rg -n '@RequestParam.*@' src/main/java/team/wego/wegobackend --type=java -B1 -A1 | head -50

Repository: WeGo-Together/WeGo_BackEnd

Length of output: 52


입력 검증 어노테이션을 추가하되, @validated 선언이 필요합니다.

이메일 중복 검사 엔드포인트에 입력 검증이 누락되어 있습니다.

  1. 입력 검증 누락: @RequestParam("email")@NotBlank@Email 어노테이션이 없어 잘못된 형식의 요청을 처리할 수 있습니다.

다음 수정이 필요합니다:

+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+
+@Validated
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/v1/users")
 public class UserController implements UserControllerDocs {
     
     @GetMapping("/email/availability")
     public ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
-        @RequestParam("email") String email
+        @RequestParam("email") @NotBlank @Email String email
     ) {

또한 닉네임 검증 엔드포인트(line 152-155)도 동일하게 @NotBlank 어노테이션을 추가하세요.

참고: 현재 Spring Security 설정에서 GET /api/v1/users/** 경로는 이미 공개로 설정되어 있어 보안 설정은 올바릅니다.

📝 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.

Suggested change
@GetMapping("/email/availability")
public ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") String email
) {
AvailabilityResponse response = userService.checkEmailAvailability(email);
//TODO : 팔로워 목록 조회 API
return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(200, response));
}
@GetMapping("/email/availability")
public ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") @NotBlank @Email String email
) {
AvailabilityResponse response = userService.checkEmailAvailability(email);
return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(200, response));
}
🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/presentation/UserController.java
around lines 137-147, the email availability endpoint lacks parameter
validation: add @NotBlank and @Email to the @RequestParam("email") parameter
(and import javax.validation.constraints.*), and ensure the controller class is
annotated with @Validated to enable method-level validation; also apply
@NotBlank to the nickname availability endpoint at lines 152-155, import any
necessary validation annotations, and keep existing method signatures otherwise
unchanged.

Comment on lines +152 to +162
@GetMapping("/nickname/availability")
public ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
@RequestParam("nickname") String nickname
) {

AvailabilityResponse response = userService.checkNicknameAvailability(nickname);

return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(200, response));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

입력 검증 어노테이션을 추가하세요.

닉네임 중복 검사 엔드포인트에도 입력 검증이 누락되어 있습니다. 빈 문자열이나 null 값이 전달될 경우 적절한 에러 처리가 되지 않습니다.

다음 diff를 적용하여 검증을 추가하세요:

     @GetMapping("/nickname/availability")
     public ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
-        @RequestParam("nickname") String nickname
+        @RequestParam("nickname") @NotBlank String nickname
     ) {
🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/presentation/UserController.java
around lines 152 to 162, the nickname availability endpoint lacks input
validation; add javax/jakarta validation to ensure empty or null nicknames are
rejected by: annotate the controller class with @Validated (add import), change
the @RequestParam parameter to @NotBlank(message = "nickname must not be blank")
String nickname (add import), and ensure the project has a global/appropriate
exception handler for
MethodArgumentNotValidException/ConstraintViolationException so validation
failures return proper error responses.

Comment on lines +54 to +63

@Operation(summary = "이메일 중복 검사 API", description = "이메일 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") String email
);

@Operation(summary = "닉네임 중복 검사 API", description = "닉네임 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
@RequestParam("nickname") String nickname
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

입력 검증 어노테이션 추가가 필요합니다.

새로운 중복 검사 엔드포인트에 입력 검증이 누락되어 있습니다. 이메일 파라미터에는 @Email 검증이, 두 파라미터 모두에 @NotBlank 검증이 필요합니다. 이를 통해 잘못된 형식의 요청을 조기에 차단하고 명확한 에러 메시지를 제공할 수 있습니다.

다음 diff를 적용하여 검증 어노테이션을 추가하세요:

+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+
 @Tag(name = "유저 API", description = "유저와 관련된 API 리스트 \uD83D\uDC08")
 public interface UserControllerDocs {
 
     @Operation(summary = "이메일 중복 검사 API", description = "이메일 중복검사에 대한 응답은 bool값입니다.")
     ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
-        @RequestParam("email") String email
+        @RequestParam("email") @NotBlank @Email String email
     );
 
     @Operation(summary = "닉네임 중복 검사 API", description = "닉네임 중복검사에 대한 응답은 bool값입니다.")
     ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
-        @RequestParam("nickname") String nickname
+        @RequestParam("nickname") @NotBlank String nickname
     );
📝 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.

Suggested change
@Operation(summary = "이메일 중복 검사 API", description = "이메일 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") String email
);
@Operation(summary = "닉네임 중복 검사 API", description = "닉네임 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
@RequestParam("nickname") String nickname
);
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
@Tag(name = "유저 API", description = "유저와 관련된 API 리스트 \uD83D\uDC08")
public interface UserControllerDocs {
@Operation(summary = "이메일 중복 검사 API", description = "이메일 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkEmailAvailability(
@RequestParam("email") @NotBlank @Email String email
);
@Operation(summary = "닉네임 중복 검사 API", description = "닉네임 중복검사에 대한 응답은 bool값입니다.")
ResponseEntity<ApiResponse<AvailabilityResponse>> checkNicknameAvailability(
@RequestParam("nickname") @NotBlank String nickname
);
}
🤖 Prompt for AI Agents
In src/main/java/team/wego/wegobackend/user/presentation/UserControllerDocs.java
around lines 54 to 63, the request parameter validation is missing for the new
availability endpoints; add javax.validation annotations by adding @NotBlank to
both parameters and @Email to the email parameter (i.e., change the email param
to @RequestParam("email") @NotBlank @Email String email and the nickname param
to @RequestParam("nickname") @NotBlank String nickname) and ensure corresponding
imports for javax.validation.constraints.NotBlank and
javax.validation.constraints.Email are added at the top of the file.

Comment on lines 5 to 9
{
"email": "test@example.com",
"email": "test@test.com",
"password": "Test1234!@#",
"nickName": "Beemo"
"nickName": "test"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

테스트 데이터 불일치 문제를 수정하세요.

회원가입 테스트의 이메일이 test@test.com으로 변경되었지만, 11번째 줄의 로그인 테스트는 여전히 test@example.com을 사용하고 있습니다. 이로 인해 회원가입 후 로그인 테스트가 실패할 수 있습니다.

다음 diff를 적용하여 로그인 테스트 데이터를 일치시키세요:

 ### 로그인
 POST http://localhost:8080/api/v1/auth/login
 Content-Type: application/json
 
 {
-  "email": "test@example.com",
+  "email": "test@test.com",
   "password": "Test1234!@#"
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/test/http/user/user-api.http around lines 5 to 9 (signup payload) and
line 11 (login test), the email values are inconsistent: signup uses
"test@test.com" but the login test still uses "test@example.com"; update the
login test email on line 11 to "test@test.com" so the login request matches the
account created by the signup test.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/team/wego/wegobackend/common/exception/GlobalExceptionHandler.java (1)

235-256: 누락된 파라미터 이름을 포함하여 디버깅 개선을 권장합니다.

핸들러 구현이 기존 패턴을 잘 따르고 있습니다. 다만, MissingServletRequestParameterException은 누락된 파라미터 이름(ex.getParameterName())과 타입(ex.getParameterType()) 정보를 제공하는데, 이를 로그나 에러 응답에 포함하면 디버깅에 도움이 됩니다.

다음 diff를 적용하여 로그 메시지를 개선할 수 있습니다:

     @ExceptionHandler(MissingServletRequestParameterException.class)
     public ResponseEntity<ErrorResponse> handleNotParameter(
         MissingServletRequestParameterException ex,
         HttpServletRequest request) {
-        log.warn("입력 파라메터 X (400): {}", rootCauseMessage(ex));
+        log.warn("필수 파라미터 누락 (400) - parameter: '{}', type: {}, message: {}", 
+            ex.getParameterName(), ex.getParameterType(), rootCauseMessage(ex));
 
         AppErrorCode code = AppErrorCode.NOT_FOUND_PARAMETER;

선택적으로, 클라이언트에게 더 명확한 피드백을 제공하기 위해 FieldError를 활용할 수도 있습니다:

+        List<FieldError> errors = List.of(
+            FieldError.of(ex.getParameterName(), 
+                String.format("필수 파라미터 '%s'가 누락되었습니다.", ex.getParameterName()))
+        );
+
         return ResponseEntity.status(code.getHttpStatus())
             .body(ErrorResponse.of(
                 type,
                 title,
                 code.getHttpStatus(),
                 code.getMessageTemplate(),
                 instance,
                 title,
-                null
+                errors
             ));
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e205f6 and d33a290.

📒 Files selected for processing (3)
  • src/main/java/team/wego/wegobackend/common/exception/AppErrorCode.java (1 hunks)
  • src/main/java/team/wego/wegobackend/common/exception/GlobalExceptionHandler.java (9 hunks)
  • src/test/http/user/user-api.http (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/http/user/user-api.http
🔇 Additional comments (2)
src/main/java/team/wego/wegobackend/common/exception/AppErrorCode.java (1)

18-18: 변경사항이 적절합니다.

새로운 NOT_FOUND_PARAMETER 에러 코드가 올바르게 정의되었습니다. HTTP 상태와 메시지가 누락된 요청 파라미터 처리에 적합합니다.

src/main/java/team/wego/wegobackend/common/exception/GlobalExceptionHandler.java (1)

16-16: import가 적절합니다.

MissingServletRequestParameterException import가 올바르게 추가되었습니다.

@Be-HinD Be-HinD merged commit 5a13711 into main Dec 12, 2025
1 check passed
@Be-HinD Be-HinD deleted the feat/validate-duplicate branch December 12, 2025 12:43
@github-project-automation github-project-automation bot moved this from Backlog to Done in WeGo-Together Backend Dec 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[FEAT] 이메일, 닉네임 중복검증 API 개발

1 participant