-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] user API 기능 #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
6c0a811
ea995f3
908a8c1
19511d9
fddc32e
bf94cf7
1d650fe
ba56530
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| package ssurent.ssurentbe.domain.users.controller; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
| import org.springframework.security.core.userdetails.UserDetails; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import ssurent.ssurentbe.domain.users.dto.UpdatePhoneNumberRequest; | ||
| import ssurent.ssurentbe.domain.users.dto.UserInfoResponse; | ||
| import ssurent.ssurentbe.domain.users.dto.UserPenaltyResponse; | ||
| import ssurent.ssurentbe.domain.users.entity.Users; | ||
| import ssurent.ssurentbe.domain.users.service.UserService; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/v1/api/users") | ||
| public class UserController { | ||
| private final UserService userService; | ||
|
|
||
| @GetMapping | ||
| public UserInfoResponse getMyInfo(@AuthenticationPrincipal UserDetails userDetails) { | ||
| return userService.getMyInfo(userDetails.getUsername()); | ||
| } | ||
|
Comment on lines
+26
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
♻️ 수정 제안 `@GetMapping`
- public UserInfoResponse getMyInfo(`@AuthenticationPrincipal` UserDetails userDetails) {
- return userQueryService.getMyInfo(userDetails.getUsername());
+ public ResponseEntity<BaseResponse<UserInfoResponse>> getMyInfo(`@AuthenticationPrincipal` UserDetails userDetails) {
+ UserInfoResponse data = userQueryService.getMyInfo(userDetails.getUsername());
+ SuccessStatus status = SuccessStatus.COMM_SUCCESS_STATUS;
+ return ResponseEntity.status(status.getHttpStatus())
+ .body(BaseResponse.success(status, data));
}🤖 Prompt for AI Agents |
||
|
|
||
| @PatchMapping("/phone-number") | ||
| public void updatePhoneNumber( | ||
| @AuthenticationPrincipal UserDetails userDetails, | ||
| @RequestBody UpdatePhoneNumberRequest request | ||
| ) { | ||
| userService.updatePhoneNumber( | ||
| userDetails.getUsername(), | ||
| request.phoneNum() | ||
| ); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| @GetMapping("/penalties") | ||
| public List<UserPenaltyResponse> getMyPenalties( | ||
| @AuthenticationPrincipal UserDetails userDetails | ||
| ) { | ||
| return userService.getMyPenalties(userDetails.getUsername()); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package ssurent.ssurentbe.domain.users.dto; | ||
|
|
||
| public record UpdatePhoneNumberRequest( | ||
| String phoneNum | ||
| ) { | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전화번호 입력값 검증이 누락되었습니다.
제안 수정사항+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+
public record UpdatePhoneNumberRequest(
- String phoneNum
+ `@NotBlank`(message = "전화번호는 필수 입력값입니다.")
+ `@Pattern`(regexp = "^01[016789]-?\\d{3,4}-?\\d{4}$", message = "올바른 전화번호 형식이 아닙니다.")
+ String phoneNum
) {
}🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package ssurent.ssurentbe.domain.users.dto; | ||
|
|
||
| import ssurent.ssurentbe.domain.users.entity.Users; | ||
| import ssurent.ssurentbe.domain.users.enums.Role; | ||
| import ssurent.ssurentbe.domain.users.enums.Status; | ||
|
|
||
| public record UserInfoResponse( | ||
| String studentNum, | ||
| String name, | ||
| String phoneNum, | ||
| Status status, | ||
| Role role | ||
| ) { | ||
| public static UserInfoResponse from(Users user) { | ||
| return new UserInfoResponse( | ||
| user.getStudentNum(), | ||
| user.getName(), | ||
| user.getPhoneNum(), | ||
| user.getStatus(), | ||
| user.getRole() | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package ssurent.ssurentbe.domain.users.dto; | ||
|
|
||
| import ssurent.ssurentbe.domain.users.entity.UserPanaltyLog; | ||
| import ssurent.ssurentbe.domain.users.enums.PanaltyTypes; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| public record UserPenaltyResponse( | ||
| Long penaltyId, | ||
| PanaltyTypes penaltyType, | ||
| Long itemId, | ||
| Long rentalHistoryId, | ||
| LocalDateTime createdAt | ||
| ) { | ||
| public static UserPenaltyResponse from(UserPanaltyLog log) { | ||
| return new UserPenaltyResponse( | ||
| log.getId(), | ||
| log.getPanaltyType(), | ||
| log.getItemsId() != null ? log.getItemsId().getId() : null, | ||
| log.getRentalHistoryId() != null ? log.getRentalHistoryId().getId() : null, | ||
| log.getCreatedAt() | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package ssurent.ssurentbe.domain.users.repository; | ||
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import ssurent.ssurentbe.domain.users.entity.UserPanaltyLog; | ||
| import ssurent.ssurentbe.domain.users.entity.Users; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| public interface UserPanaltyLogRepository extends JpaRepository<UserPanaltyLog, Long> { | ||
|
|
||
| List<UserPanaltyLog> findByUserIdOrderByCreatedAtDesc(Users user); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chain🏁 Script executed: find . -name "UserPanaltyLog.java" -type fRepository: SSURENT/SSURENT-BE Length of output: 135 🏁 Script executed: cat -n ./src/main/java/ssurent/ssurentbe/domain/users/entity/UserPanaltyLog.javaRepository: SSURENT/SSURENT-BE Length of output: 1330 🏁 Script executed: # Check if there are other entities with similar naming patterns
rg "private \w+ \w+Id;" --type java -A 1 -B 1 | head -50Repository: SSURENT/SSURENT-BE Length of output: 2302 🏁 Script executed: # Check for "Panalty" vs "Penalty" usage throughout the codebase
rg "Panalty|Penalty" --type java | head -30Repository: SSURENT/SSURENT-BE Length of output: 2958 🏁 Script executed: # Verify how Spring Data JPA resolves the method - check if this pattern works elsewhere in the codebase
rg "findBy.*OrderBy.*Desc\(" --type java -A 1Repository: SSURENT/SSURENT-BE Length of output: 551 🏁 Script executed: # Check the extent of the typo - count usages
rg "Panalty" --type java | wc -lRepository: SSURENT/SSURENT-BE Length of output: 64 "Panalty" 오타 수정 필요 클래스명, 엔티티명, 리포지토리에서 🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||
| package ssurent.ssurentbe.domain.users.service; | ||||||||||||||
|
|
||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||
| import org.springframework.stereotype.Service; | ||||||||||||||
| import org.springframework.transaction.annotation.Transactional; | ||||||||||||||
| import ssurent.ssurentbe.domain.users.entity.UserPanaltyLog; | ||||||||||||||
| import ssurent.ssurentbe.domain.users.entity.Users; | ||||||||||||||
| import ssurent.ssurentbe.domain.users.repository.UserPanaltyLogRepository; | ||||||||||||||
| import ssurent.ssurentbe.domain.users.repository.UserRepository; | ||||||||||||||
| import ssurent.ssurentbe.domain.users.dto.*; | ||||||||||||||
| import java.util.stream.Collectors; | ||||||||||||||
|
|
||||||||||||||
| import java.util.List; | ||||||||||||||
|
|
||||||||||||||
| @Service | ||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||
| @Transactional(readOnly = true) | ||||||||||||||
| public class UserService { | ||||||||||||||
| private final UserRepository userRepository; | ||||||||||||||
| private final UserPanaltyLogRepository userPanaltyLogRepository; | ||||||||||||||
|
|
||||||||||||||
| public UserInfoResponse getMyInfo(String username) { | ||||||||||||||
| Users user = userRepository.findByStudentNumAndDeletedFalse(username) | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 문장이 반복되는거 같으니까 함수화해서 적용하면 좋을 듯 |
||||||||||||||
| .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 커스텀 에러 사용하기스텀 에러 사용하기 |
||||||||||||||
| UserInfoResponse response = UserInfoResponse.from(user); | ||||||||||||||
| return UserInfoResponse.from(user); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| @Transactional | ||||||||||||||
| public void updatePhoneNumber(String username, String phoneNum) { | ||||||||||||||
| Users user = userRepository.findByStudentNumAndDeletedFalse(username) | ||||||||||||||
| .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동일하게 커스텀 에러 사용 |
||||||||||||||
|
|
||||||||||||||
| user.updatePhoneNumber(phoneNum); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| public List<UserPenaltyResponse> getMyPenalties(String username) { | ||||||||||||||
| Users user = userRepository.findByStudentNum(username) | ||||||||||||||
| .orElseThrow(() -> new RuntimeException("User not found")); | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. soft-delete 필터링 누락 및 예외 타입 불일치 두 가지 일관성 문제가 있습니다:
🔧 수정 제안 public List<UserPenaltyResponse> getMyPenalties(String username) {
- Users user = userRepository.findByStudentNum(username)
- .orElseThrow(() -> new RuntimeException("User not found"));
+ Users user = userRepository.findByStudentNumAndDeletedFalse(username)
+ .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| List<UserPanaltyLog> logs = userPanaltyLogRepository.findByUserIdOrderByCreatedAtDesc(user); | ||||||||||||||
|
|
||||||||||||||
| return logs.stream() | ||||||||||||||
| .map(UserPenaltyResponse::from) | ||||||||||||||
| .collect(Collectors.toList()); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| } | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
우리 CQRS 패턴으로 작업중이라서 Request/Response Dto 패키지 따로 만들어서 관리해야 해.