[FEAT] 사용자 마이페이지 정보 조회/수정 api 구현#13
Conversation
Walkthrough사용자 마이페이지 조회(GET /users/me) 및 수정(PUT /users/me) API가 추가됨. UserService·UserController·요청/응답 DTO들이 도입되며 User 도메인에 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as UserController (GET /users/me)
participant S as UserService
participant R as UserRepository
participant U as User
C->>S: getUserInfo(userId)
S->>R: findById(userId)
alt found
R-->>S: User
S->>C: BaseResponse(UserResponse.from(User))
else not found
R-->>S: empty
S-->>C: throws EntityNotFoundException(USER_NOT_FOUND)
end
sequenceDiagram
autonumber
participant C as UserController (PUT /users/me)
participant S as UserService
participant R as UserRepository
participant U as User
C->>S: updateUserInfo(userId, UpdateUserInfoRequest)
S->>R: findById(userId)
alt found
R-->>S: User
S->>U: user.update(name, profileImageUrl, email, genderStr, termsAgreed)
note right of U #d1f0d1: Gender.from(genderStr) 호출\n유효하지 않으면 DomainRuleException 발생
S-->>C: BaseResponse<Void>
else not found
R-->>S: empty
S-->>C: throws EntityNotFoundException(USER_NOT_FOUND)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (7)
src/main/java/konkuk/chacall/global/common/security/oauth2/auth/AuthController.java (1)
6-6: 불필요한 import 제거현재 파일에서 사용되지 않는 import 입니다.
- import konkuk.chacall.domain.user.domain.repository.UserRepository; @@ -import static konkuk.chacall.global.common.exception.code.ErrorCode.API_INVALID_PARAM;Also applies to: 21-21
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (1)
17-19: 샘플/유효성 강화 제안
- 이메일 예시 도메인 오탈자로 보입니다: konkuk.ac.kr?
- URL 형식 검증은 @url(org.hibernate.validator.constraints.URL) 사용을 검토하세요. 의존성 상황에 따라 선택.
- @Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr") + @Schema(description = "사용자 이메일", example = "chacall@konkuk.ac.kr")Also applies to: 9-11
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)
29-31: UPDATE_USER_INFO에 검증 실패 코드 누락성별 변환 실패 시 USER_GENDER_MISMATCH가 발생하므로 스웨거 응답 설명에 포함하세요.
- UPDATE_USER_INFO(new LinkedHashSet<>(Set.of( - USER_NOT_FOUND - ))), + UPDATE_USER_INFO(new LinkedHashSet<>(Set.of( + USER_NOT_FOUND, + USER_GENDER_MISMATCH + ))),src/main/java/konkuk/chacall/domain/user/domain/model/Gender.java (1)
19-29: null/blank 입력 방어 로직 추가 제안컨트롤러 검증이 누락되거나 다른 경로에서 호출될 때 NPE를 방지하세요.
- public static Gender from(String value) { - return Arrays.stream(Gender.values()) - .filter(genderVal -> genderVal.getValue().equals(value.trim())) + public static Gender from(String value) { + if (value == null || value.isBlank()) { + throw new DomainRuleException(ErrorCode.USER_GENDER_MISMATCH, + new IllegalArgumentException("존재하지 않는 성별입니다. value: " + value)); + } + final String v = value.trim(); + return Arrays.stream(Gender.values()) + .filter(genderVal -> genderVal.getValue().equals(v)) .findFirst() .orElseThrow( () -> new DomainRuleException(ErrorCode.USER_GENDER_MISMATCH, new IllegalArgumentException( String.format("존재하지 않는 성별입니다. value: %s", value) )) ); }src/main/java/konkuk/chacall/domain/user/presentation/UserController.java (3)
33-36: PATCH 엔드포인트의 미디어 타입 명시 권장클라이언트-서버 간 계약을 명확히 하기 위해 consumes를 지정하는 것을 권장합니다.
- @PatchMapping("/me") + @PatchMapping(value = "/me", consumes = "application/json")또는 MediaType.APPLICATION_JSON_VALUE 사용 시
import org.springframework.http.MediaType;추가.
40-41: 응답 규약 정렬: 200+null 대신 204 No Content 고려성공 시 본문이 없는 수정 요청은 HTTP 204가 더 적합합니다. BaseResponse 컨벤션을 유지해야 한다면 OK+명시적 메시지 등 일관된 규약을 문서화해 주세요.
원하시면 ResponseEntity로 전환하는 패치도 제안드릴게요.
17-21: 검증/보안 메타데이터 보강 제안
- 클래스에 @validated 추가 시 DTO 메서드 파라미터 검증 패턴과 일관성이 좋아집니다.
- 스웨거에 보안 스킴을 노출하려면 @securityrequirement(name = "BearerAuth") 등을 붙이세요(프로젝트 설정에 맞게 이름 조정).
@RequiredArgsConstructor +@org.springframework.validation.annotation.Validated public class UserController {보안 스킴 이름/설정은 실제 OpenAPI 구성에 맞는지 확인 부탁드립니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/main/java/konkuk/chacall/domain/user/application/UserService.java(1 hunks)src/main/java/konkuk/chacall/domain/user/domain/model/Gender.java(2 hunks)src/main/java/konkuk/chacall/domain/user/domain/model/User.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/UserController.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/dto/response/GetUserInfoResponse.java(1 hunks)src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java(1 hunks)src/main/java/konkuk/chacall/global/common/security/oauth2/auth/AuthController.java(1 hunks)src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/konkuk/chacall/domain/user/application/UserService.java (1)
src/main/java/konkuk/chacall/global/common/exception/EntityNotFoundException.java (1)
EntityNotFoundException(6-11)
src/main/java/konkuk/chacall/domain/user/domain/model/Gender.java (1)
src/main/java/konkuk/chacall/domain/user/domain/model/User.java (1)
Getter(7-62)
🔇 Additional comments (7)
src/main/java/konkuk/chacall/global/common/security/oauth2/auth/AuthController.java (1)
38-38: ISSUE_TOKEN으로의 전환 LGTM엔드포인트 동작과 예외 설명이 일치합니다.
src/main/java/konkuk/chacall/global/common/exception/code/ErrorCode.java (1)
36-36: 신규 에러코드(USER_GENDER_MISMATCH) 추가 LGTM업데이트 API의 검증 실패 케이스에 적절합니다.
src/main/java/konkuk/chacall/global/common/swagger/SwaggerResponseDescription.java (1)
21-23: ISSUE_TOKEN 구문 수정 LGTM트레일링 콤마 제거로 초기화 일관성이 좋아졌습니다.
src/main/java/konkuk/chacall/domain/user/presentation/dto/response/GetUserInfoResponse.java (1)
12-20: DTO 매핑 LGTMnull‑safe 성별 문자열 변환과 약관 동의 노출이 의도와 일치합니다.
src/main/java/konkuk/chacall/domain/user/domain/model/User.java (1)
55-61: update 로직 LGTM도메인 내부에서 변환·검증을 캡슐화(Gender.from)하여 일관성이 좋습니다.
src/main/java/konkuk/chacall/domain/user/application/UserService.java (2)
20-24: getUserInfo 흐름 LGTM조회 → DTO 변환 → 404 매핑이 간결합니다.
26-32: updateUserInfo 트랜잭션/더티체킹 사용 LGTM엔티티 조회 후 도메인 메서드 호출로 변경 추적이 명확합니다.
| // 약관 동의 여부 컬럼 | ||
| @Column(nullable = false) | ||
| private boolean termsAgreed; | ||
|
|
There was a problem hiding this comment.
기존 데이터가 있는 테이블에 NOT NULL 컬럼 추가 시 마이그레이션 필요
nullable=false boolean 컬럼 추가는 운영 DB에서 실패할 수 있습니다. 기본값/백필 전략을 포함한 마이그레이션을 선반영하세요.
예시 SQL(선반영 후 제약 강화):
-- 1) 컬럼 추가(임시 default)
ALTER TABLE users ADD COLUMN terms_agreed BOOLEAN DEFAULT FALSE;
-- 2) 기존 로우 백필(필요 시 조건부 업데이트)
UPDATE users SET terms_agreed = FALSE WHERE terms_agreed IS NULL;
-- 3) NOT NULL 제약 강화 및 기본값 제거(선택)
ALTER TABLE users ALTER COLUMN terms_agreed SET NOT NULL;
ALTER TABLE users ALTER COLUMN terms_agreed DROP DEFAULT;🤖 Prompt for AI Agents
src/main/java/konkuk/chacall/domain/user/domain/model/User.java lines 40-43: 현재
nullable=false로 boolean 컬럼을 바로 추가하면 운영 DB 마이그레이션에서 실패할 수 있으니 마이그레이션을 선행해 처리하세요;
DB 마이그레이션 스크립트를 만들어(1) terms_agreed 컬럼을 DEFAULT FALSE로 추가하고(2) 기존 로우에 대해 NULL인
값들을 FALSE로 백필한 다음(3) ALTER로 NOT NULL 제약을 설정하고 필요하면 DEFAULT를 제거하는 단계를 적용하고,
애플리케이션 코드와 마이그레이션이 일관되도록 배포 전 로컬/스테이징에서 검증하세요.
| @Schema(description = "약관 동의 여부", example = "true") | ||
| @NotBlank(message = "약관 동의 여부는 비어 있을 수 없습니다.") | ||
| boolean termAgreed |
There was a problem hiding this comment.
boolean 필드에 @notblank 사용 → 런타임 검증 예외 위험
@notblank는 CharSequence 전용입니다. primitive boolean에 적용 시 UnexpectedTypeException이 발생할 수 있습니다. 필드 타입을 Boolean으로 바꾸고 @NotNull을 적용하세요. 이메일은 @Email로 기본 검증 추가 권장.
package konkuk.chacall.domain.user.presentation.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotNull;
@@
@Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr")
- @NotBlank(message = "이메일은 비어 있을 수 없습니다.")
+ @NotBlank(message = "이메일은 비어 있을 수 없습니다.")
+ @Email(message = "올바른 이메일 형식이 아닙니다.")
String email,
@@
@Schema(description = "약관 동의 여부", example = "true")
- @NotBlank(message = "약관 동의 여부는 비어 있을 수 없습니다.")
- boolean termAgreed
+ @NotNull(message = "약관 동의 여부는 비어 있을 수 없습니다.")
+ Boolean termAgreed
) {
}📝 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.
| @Schema(description = "약관 동의 여부", example = "true") | |
| @NotBlank(message = "약관 동의 여부는 비어 있을 수 없습니다.") | |
| boolean termAgreed | |
| package konkuk.chacall.domain.user.presentation.dto.request; | |
| import io.swagger.v3.oas.annotations.media.Schema; | |
| import jakarta.validation.constraints.NotBlank; | |
| import jakarta.validation.constraints.Email; | |
| import jakarta.validation.constraints.NotNull; | |
| public record UpdateUserInfoRequest( | |
| @Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr") | |
| @NotBlank(message = "이메일은 비어 있을 수 없습니다.") | |
| @Email(message = "올바른 이메일 형식이 아닙니다.") | |
| String email, | |
| @Schema(description = "약관 동의 여부", example = "true") | |
| @NotNull(message = "약관 동의 여부는 비어 있을 수 없습니다.") | |
| Boolean termAgreed | |
| ) { | |
| } |
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java
around lines 25-27, the primitive boolean field annotated with @NotBlank is
invalid (UnexpectedTypeException) because @NotBlank is for CharSequence; change
the field type from boolean to Boolean and replace @NotBlank with @NotNull to
allow proper validation, and additionally add @Email to the email field (where
applicable) to enforce basic email format validation.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/main/java/konkuk/chacall/domain/user/presentation/dto/response/UserResponse.java (2)
12-20: null 입력 방지: from(User)에서 명시적으로 가드하세요
user가 null이면 NPE가 발생합니다. 방어 로직을 추가해 원인 파악이 쉬운 예외로 전환하세요.public static UserResponse from(User user) { + Objects.requireNonNull(user, "user must not be null"); return new UserResponse( user.getProfileImageUrl(), user.getName(), user.getEmail(), user.getGender() == null ? null : user.getGender().getValue(), user.isTermsAgreed() ); }추가 import(파일 상단):
import java.util.Objects;
17-17: gender 직렬화 값의 안정성 확인(코드값 vs. 로컬라이즈드 값)
getValue()가 로케일에 따라 바뀌는 문자열(예: "남성/여성")이라면 프런트/문서와 불일치 위험이 있습니다. 변경 불가라면 허용 값 명세를 스웨거에 명시해 주세요.선택사항 1: 스키마에 허용값 문서화
public record UserResponse( String profileImageUrl, String name, String email, - String gender, + @io.swagger.v3.oas.annotations.media.Schema(description = "성별 코드: MALE|FEMALE|null") + String gender, boolean termsAgreed ) { ... }선택사항 2: 값의 불변성이 중요하면
user.getGender().name()으로 코드값을 반환하는 방식을 검토하세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/main/java/konkuk/chacall/domain/user/application/UserService.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/UserController.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/dto/response/UserResponse.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/main/java/konkuk/chacall/domain/user/application/UserService.java
- src/main/java/konkuk/chacall/domain/user/presentation/UserController.java
| public record UserResponse( | ||
| String profileImageUrl, | ||
| String name, | ||
| String email, | ||
| String gender, | ||
| boolean termAgreed | ||
| ) { |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
응답 필드명 일관성: termAgreed → termsAgreed로 변경 권장
도메인(User.isTermsAgreed()), PR 설명(컬럼명 termsAgreed)과 응답 DTO 필드(termAgreed)가 불일치합니다. API 계약 혼동을 막기 위해 복수형으로 통일하세요.
아래 diff 적용 후, 해당 접근자(termsAgreed())를 사용하는 컨트롤러/테스트/문서도 함께 갱신해 주세요.
public record UserResponse(
String profileImageUrl,
String name,
String email,
String gender,
- boolean termAgreed
+ boolean termsAgreed
) {검증 스크립트:
🏁 Script executed:
#!/bin/bash
# 'termAgreed' 잔존 사용처 점검
rg -nP -C2 '\btermAgreed\b|\.termAgreed\(\)'Length of output: 1782
필드명 일관성 확보 — termAgreed → termsAgreed로 전파 (필수)
아래 파일들이 아직 termAgreed를 사용중이므로 UserResponse 필드명 변경 시 모든 참조(요청 DTO, 서비스 호출, 테스트, 문서 등)를 일괄 갱신해야 함.
- 수정 대상(발견된 참조):
- src/main/java/konkuk/chacall/domain/user/presentation/dto/response/UserResponse.java — boolean termAgreed → boolean termsAgreed (record 생성자 및 from(User) 매핑)
- src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java — boolean termAgreed → boolean termsAgreed
- src/main/java/konkuk/chacall/domain/user/application/UserService.java — request.termAgreed() → request.termsAgreed() (user.update(...) 호출부)
원본 diff(적용 필요):
public record UserResponse(
String profileImageUrl,
String name,
String email,
String gender,
- boolean termAgreed
+ boolean termsAgreed
) {📝 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.
| public record UserResponse( | |
| String profileImageUrl, | |
| String name, | |
| String email, | |
| String gender, | |
| boolean termAgreed | |
| ) { | |
| public record UserResponse( | |
| String profileImageUrl, | |
| String name, | |
| String email, | |
| String gender, | |
| boolean termsAgreed | |
| ) { |
🤖 Prompt for AI Agents
In
src/main/java/konkuk/chacall/domain/user/presentation/dto/response/UserResponse.java
around lines 5 to 11, rename the record field and constructor parameter
termAgreed to termsAgreed, update any internal mapping (e.g., from(User)
factory/mapping) to call user.isTermsAgreed() or equivalent, and then propagate
this rename to referenced files:
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java
(boolean termAgreed → boolean termsAgreed and accessor rename), and
src/main/java/konkuk/chacall/domain/user/application/UserService.java
(request.termAgreed() → request.termsAgreed() where user.update(...) is
invoked); run and update related tests and any docs that reference termAgreed to
use termsAgreed.
| @Operation(summary = "[마이페이지] 회원 정보 조회", description = "사용자(고객)의 정보를 조회합니다. (사장님, 일반유저 무관)") | ||
| @ExceptionDescription(SwaggerResponseDescription.GET_USER_INFO) | ||
| @GetMapping("/me") | ||
| public BaseResponse<UserResponse> getUserInfo() { | ||
| // todo 추후에 토큰 추가될 시 id 값은 토큰에서 추출하여 전달 | ||
| return BaseResponse.ok(userService.getUserInfo(1L)); | ||
| } | ||
|
|
||
| @Operation(summary = "[마이페이지] 회원 정보 수정", description = "사용자(고객)의 정보를 수정합니다. (사장님, 일반유저 무관)") | ||
| @ExceptionDescription(SwaggerResponseDescription.UPDATE_USER_INFO) | ||
| @PatchMapping("/me") | ||
| public BaseResponse<Void> updateUserInfo( | ||
| final @RequestBody @Valid UpdateUserInfoRequest request | ||
| ) { | ||
| // todo 추후에 토큰 추가될 시 id 값은 토큰에서 추출하여 전달 | ||
| userService.updateUserInfo(1L, request); | ||
|
|
||
| return BaseResponse.ok(null); |
| @NotBlank(message = "약관 동의 여부는 비어 있을 수 없습니다.") | ||
| boolean termAgreed |
There was a problem hiding this comment.
어차피 프리미티브 타입으로 설정해둬서 null 이 들어갈 수 없기 때문에 여기에는 별도의 Validation 은 걸지 않아도 될 것 같아요!
There was a problem hiding this comment.
맞네요. 뭐지 그러면 래퍼 객체로 선언하고 NotNull로 수정할까요??
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/java/konkuk/chacall/domain/user/presentation/UserController.java (1)
36-37: PATCH 소비 미디어 타입(consumes) 명시로 415/모호성 예방JSON PATCH 요청임을 명시하면 클라이언트·게이트웨이에서 콘텐츠 협상이 명확해집니다.
- @PatchMapping("/me") + @PatchMapping(value = "/me", consumes = org.springframework.http.MediaType.APPLICATION_JSON_VALUE)(선호 시 import 추가)
+import org.springframework.http.MediaType; -@PatchMapping("/me") +@PatchMapping(value = "/me", consumes = MediaType.APPLICATION_JSON_VALUE)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/java/konkuk/chacall/domain/user/presentation/UserController.java(1 hunks)src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java
🔇 Additional comments (2)
src/main/java/konkuk/chacall/domain/user/presentation/UserController.java (2)
25-32: 하드코딩 제거 및 사용자 컨텍스트 주입이 잘 반영됨@userid로 인증 사용자 ID를 주입하고 Swagger 파라미터를 숨긴 처리, 적절합니다.
3-15: 불필요 — OpenAPI 전역 보안 스키마/요구가 이미 설정되어 있음src/main/java/konkuk/chacall/global/config/OpenApiConfig.java에서 securitySchemaName="JWT"로 SecurityScheme를 등록하고 openAPI()에서 .addSecurityItem(setSecurityItems())로 전역 SecurityRequirement를 설정하고 있습니다. 따라서 컨트롤러에 @securityrequirement를 추가할 필요가 없습니다. (개별 표기를 원하면 @securityrequirement(name = "JWT") 사용)
Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (1)
18-20: 이메일 형식 검증 추가 (@Email) 제안현재 @notblank만으로는 형식 검증이 되지 않습니다. 기본 수준의 형식 검증을 위해 @Email 추가를 권장합니다.
import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Email; @@ @Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr") - @NotBlank(message = "이메일은 비어 있을 수 없습니다.") + @NotBlank(message = "이메일은 비어 있을 수 없습니다.") + @Email(message = "올바른 이메일 형식이 아닙니다.") String email,Also applies to: 3-6
🧹 Nitpick comments (5)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (5)
22-24: 성별 값 제약 명시 필요 (Enum 또는 허용값/패턴 지정)현재 String + @notblank만으로는 허용값이 열려 있습니다. 서비스 단의 Gender.from(...) 규칙과 일치하도록 다음 중 하나를 권장합니다:
- 요청 DTO에서 Enum 타입 사용, 또는
- @Schema(allowableValues=...) 혹은 @pattern으로 허용값 제한.
또한 예시 값("남성")이 실제 허용 토큰과 일치하는지 확인 바랍니다.
10-12: 프로필 이미지 URL 형식 검증 추가 권장URL 필드에는 형식 검증이 있으면 좋습니다. Hibernate Validator 사용 중이라면 @url을, 아니라면 간단한 @pattern이라도 고려해 주세요.
+import org.hibernate.validator.constraints.URL; @@ @Schema(description = "프로필 이미지 URL", example = "https://example.com/profile.jpg") - @NotBlank(message = "프로필 이미지 URL은 비어 있을 수 없습니다.") + @NotBlank(message = "프로필 이미지 URL은 비어 있을 수 없습니다.") + @URL(message = "올바른 URL 형식이 아닙니다.") String profileImageUrl,
8-29: PATCH 의미상 필드 ‘전부 필수’인지 확인 필요현재 @NotBlank/@NotNull로 모든 컴포넌트가 필수입니다. PATCH(/users/me)라면 부분 업데이트 허용이 일반적입니다. 요구사항이 ‘전체 갱신’인지 확인 부탁드립니다. 부분 업데이트라면 필드 Nullable 허용 + 서비스 레벨에서 null 무시 처리(merge) 또는 별도 Partial DTO 도입을 권장합니다.
18-18: 예시 도메인 오타 추정: kokuk → konkuk패키지명은 konkuk인데 예시 이메일 도메인은 kokuk으로 보입니다. 오타라면 교정해 주세요.
- @Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr") + @Schema(description = "사용자 이메일", example = "chacall@konkuk.ac.kr")
10-28: Swagger에서 ‘필수 여부’가 확실히 드러나야 합니다springdoc가 Bean Validation을 반영하긴 하지만, 명확성을 위해 필수 항목에는 @Schema(requiredMode = REQUIRED) 지정도 고려해 주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java(1 hunks)
🔇 Additional comments (1)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (1)
26-28: Boolean 필드 전환(+@NotNull) 적용은 적절합니다primitive → 래퍼(Boolean)로 전환하고 @NotNull을 둔 점은 검증·문서화 측면에서 타당합니다.
단, 도메인 모델 필드명이
termsAgreed로 알려져 있습니다(AI 요약). 요청 DTO의termAgreed와 naming이 다르면 혼동 여지 있습니다. 의도된 불일치인지 확인 바랍니다.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (1)
28-30: 지난 코멘트 반영 굿: boolean → Boolean + @NotNull 적용이전 리뷰에서 지적됐던 @NotBlank/primitive boolean 문제를 정확히 수정하셨습니다. DTO-검증 관점에서 안정적입니다.
🧹 Nitpick comments (4)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (4)
19-22: 스웨거 예시 오타로 보임: kokuk → konkuk학교 도메인 표기가 패키지명과 상이합니다. 오타라면 예시를 교정해 주세요.
- @Schema(description = "사용자 이메일", example = "chacall@kokuk.ac.kr") + @Schema(description = "사용자 이메일", example = "chacall@konkuk.ac.kr")
11-30: 검증 메시지 i18n 리소스 분리 제안하드코딩된 한글 메시지는 다국어/운영 변경에 취약합니다. 메시지 코드를 사용해 messages.properties로 분리하는 것을 권장합니다.
28-30: 필드명 일관성: termAgreed ↔ termsAgreed 통일 필요DTO/응답(src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java, src/main/java/konkuk/chacall/domain/user/presentation/dto/response/UserResponse.java)은 termAgreed, 도메인/서비스(src/main/java/konkuk/chacall/domain/user/domain/model/User.java, src/main/java/konkuk/chacall/domain/user/application/UserService.java)는 termsAgreed로 불일치합니다 — 팀 규약(단수/복수)에 맞춰 명명 통일하세요.
24-26: 성별 값 검증 강화 — 허용값을 '남성'/'여성'로 제한하세요Gender.from(String)는 enum Gender { M("남성"), F("여성") }의 value("남성"/"여성")를 기대합니다. 현재 UpdateUserInfoRequest.gender는 String + @notblank로 임의 문자열이 통과해 런타임에 DomainRuleException이 발생할 수 있습니다.
- 권장(명확): DTO의 gender 타입을 Gender로 변경. (주의: 기본 바인딩은 enum 이름(M/F)을 사용하므로 클라이언트 또는 컨버터 조정 필요)
- 대안: UpdateUserInfoRequest.gender에 @Schema(allowableValues = {"남성","여성"}) 및/또는 @pattern(regexp="^(남성|여성)$", message="허용값: 남성 또는 여성") 추가로 문서·검증 반영
파일: src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java
참고: src/main/java/konkuk/chacall/domain/user/domain/model/Gender.java
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java(1 hunks)
🔇 Additional comments (2)
src/main/java/konkuk/chacall/domain/user/presentation/dto/request/UpdateUserInfoRequest.java (2)
15-17: 이름 길이 상한을 DB 스키마와 일치시키세요UpdateUserInfoRequest.name 필드에 @SiZe(max=...)를 추가해 DB의 name 컬럼 길이와 일치시키세요. 저장소에서 User 엔티티/DDL의 name 컬럼 길이를 찾지 못했으니(검색 결과 없음) 먼저 DB/schema 또는 User 엔티티에서 실제 컬럼 길이를 확인하고 그 값으로 max를 설정하세요.
11-13: 프로필 이미지 URL에 URL 형식 검증 추가 — 의존성 확인 필요프로필 이미지 URL 필드에 @url 어노테이션으로 URL 형식 검증을 추가하세요. 레포 루트(pom.xml 또는 build.gradle(.kts))에 hibernate-validator 또는 spring-boot-starter-validation 의존성 포함 여부를 확인하세요(제공된 스크립트 실행 결과 'pom.xml: No such file or directory'로 자동 확인 실패).
import org.hibernate.validator.constraints.URL; @Schema(description = "프로필 이미지 URL", example = "https://example.com/profile.jpg") @NotBlank(message = "프로필 이미지 URL은 비어 있을 수 없습니다.") @URL(message = "유효한 URL 형식이 아닙니다.") String profileImageUrl,확인 예시 명령: 루트에서
rg -n 'hibernate-validator|spring-boot-starter-validation' -S
또는 pom.xml / build.gradle(.kts) 파일 내용을 제공.
ksg1227
left a comment
There was a problem hiding this comment.
메서드 PUT 으로 바꾸는 걸로 통일하시져 굿
#️⃣연관된 이슈
closes #11
📝작업 내용
마이페이지 정보에서 약관 동의 항목이 존재해서 사용자 테이블에 약관 동의 여부를 판단하는 컬럼을 추가했습니다!
그것말고는 딱히 특이사항은 없습니다~
스크린샷
💬리뷰 요구사항(선택)
Summary by CodeRabbit
신기능
오류 처리
문서