[feat] 유저 정보 수정 API 구현 #74
Conversation
|
""" Walkthrough사용자가 자신의 상세 정보를 수정할 수 있도록 하는 PATCH 엔드포인트( Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserController
participant UserInfoService
participant UserRepository
participant User
Client->>UserController: PATCH /api/v1/users/info (UserInfoUpdateRequestDto)
UserController->>UserInfoService: updateUserInfo(userId, dto)
UserInfoService->>UserRepository: findById(userId)
UserRepository-->>UserInfoService: User
UserInfoService->>User: set* (필드별 조건부 업데이트)
UserInfoService->>UserRepository: save(User)
UserInfoService-->>UserController: void
UserController-->>Client: 성공 응답 반환
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related issues
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. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/main/java/com/wayble/server/user/controller/UserController.java (1)
141-163: 새로운 PATCH 엔드포인트 구현이 올바릅니다.사용자 정보 수정 API가 적절하게 구현되었습니다. 기존 코드 패턴을 따르고 있으며 OpenAPI 문서화도 완료되었습니다.
인증 처리 로직(lines 155-159)이 기존 registerUserInfo 메서드와 중복됩니다. 향후 리팩토링을 고려해보세요.
중복된 인증 로직을 헬퍼 메서드로 추출할 수 있습니다:
+ private Long getCurrentUserId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication.getPrincipal() instanceof Long userId)) { + throw new ApplicationException(UserErrorCase.FORBIDDEN); + } + return userId; + } public CommonResponse<String> updateUserInfo( @RequestBody @Valid UserInfoUpdateRequestDto dto ) { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (!(authentication.getPrincipal() instanceof Long)) { - throw new ApplicationException(UserErrorCase.FORBIDDEN); - } - Long userId = (Long) authentication.getPrincipal(); + Long userId = getCurrentUserId(); userInfoService.updateUserInfo(userId, dto); return CommonResponse.success("내 정보 수정 완료"); }src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java (1)
1-15: DTO 구조는 적절하지만 검증 로직 추가를 고려하세요.PATCH 작업을 위한 nullable 필드 설계가 적절합니다. 하지만 다음 개선사항을 고려해보세요:
birthDate필드에 대한 형식 검증 추가userType이DISABLED가 아닐 때disabilityType,mobilityAid가 null인지 검증- 테스트 용이성을 위한 생성자 또는 빌더 패턴 추가
검증 어노테이션을 추가할 수 있습니다:
+import jakarta.validation.constraints.Pattern; + @Getter public class UserInfoUpdateRequestDto { private String nickname; + @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "생년월일은 YYYY-MM-DD 형식이어야 합니다") private String birthDate; // YYYY-MM-DD (nullable) private Gender gender; // MALE, FEMALE, UNKNOWN (nullable) private UserType userType; // GENERAL, DISABLED, COMPANION (nullable) private String disabilityType; // userType이 DISABLED일 때만 값, 아니면 null private String mobilityAid; // userType이 DISABLED일 때만 값, 아니면 null }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/main/java/com/wayble/server/user/controller/UserController.java(2 hunks)src/main/java/com/wayble/server/user/dto/UserInfoUpdateRequestDto.java(1 hunks)src/main/java/com/wayble/server/user/entity/User.java(1 hunks)src/main/java/com/wayble/server/user/service/UserInfoService.java(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/main/java/com/wayble/server/user/service/UserInfoService.java (1)
Learnt from: seung-in-Yoo
PR: #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 없이 사용 가능하다.
🔇 Additional comments (4)
src/main/java/com/wayble/server/user/entity/User.java (1)
98-106: 코드 포매팅 개선이 적절합니다.setter 메서드들을 단일 라인 형태로 리팩토링한 것이 코드 간결성을 향상시키면서 기능은 그대로 유지하고 있습니다.
src/main/java/com/wayble/server/user/controller/UserController.java (1)
7-7: 새로운 DTO import가 적절합니다.UserInfoUpdateRequestDto가 올바르게 import되었습니다.
src/main/java/com/wayble/server/user/service/UserInfoService.java (2)
6-6: 새로운 DTO import가 적절합니다.UserInfoUpdateRequestDto가 올바르게 import되었습니다.
54-86: 전체적인 메서드 구현이 적절합니다.사용자 정보 선택적 업데이트 로직이 올바르게 구현되었습니다.
@Transactional어노테이션과 null 체크를 통한 조건부 업데이트가 적절합니다.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/main/java/com/wayble/server/user/service/UserInfoService.java (1)
54-97: 사용자 정보 업데이트 메서드가 잘 구현되었습니다.메서드 구조와 로직이 전반적으로 잘 설계되었고, 이전 리뷰 코멘트의 문제점들이 적절히 해결되었습니다:
- 날짜 파싱 예외 처리가 추가되었습니다
- 장애 관련 필드 업데이트 로직이 개선되었습니다
다만, 한 가지 잠재적 이슈가 있습니다: 현재 사용자가
DISABLED타입이고dto.getUserType()이 null이지만,dto.getDisabilityType()또는dto.getMobilityAid()를 null로 명시적으로 설정하여 해당 필드들을 지우고 싶은 경우에 대한 처리가 불완전합니다.다음과 같이 개선할 수 있습니다:
UserType finalUserType = dto.getUserType() != null ? dto.getUserType() : user.getUserType(); if (finalUserType == UserType.DISABLED) { - if (dto.getDisabilityType() != null) { + if (dto.getDisabilityType() != null || (dto.getUserType() == null && dto.getDisabilityType() == null)) { user.setDisabilityType(dto.getDisabilityType()); } - if (dto.getMobilityAid() != null) { + if (dto.getMobilityAid() != null || (dto.getUserType() == null && dto.getMobilityAid() == null)) { user.setMobilityAid(dto.getMobilityAid()); } } else if (dto.getUserType() != null) { user.setDisabilityType(null); user.setMobilityAid(null); }하지만 현재 구현도 일반적인 사용 시나리오에서는 충분히 작동합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/com/wayble/server/user/service/UserInfoService.java(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/main/java/com/wayble/server/user/service/UserInfoService.java (1)
Learnt from: seung-in-Yoo
PR: #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 없이 사용 가능하다.
🔇 Additional comments (1)
src/main/java/com/wayble/server/user/service/UserInfoService.java (1)
6-6: 새로운 DTO import가 적절하게 추가되었습니다.
UserInfoUpdateRequestDtoimport가 올바르게 추가되어 새로운 업데이트 메서드에서 사용할 수 있습니다.
#️⃣ 연관된 이슈
#73
📝 작업 내용
🖼️ 스크린샷 (선택)
💬 리뷰 요구사항 (선택)
Summary by CodeRabbit
신규 기능
/api/v1/users/info)가 추가되었습니다.스타일