-
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 7 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
|
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. 우리 CQRS 패턴으로 작업중이라서 Request/Response Dto 패키지 따로 만들어서 관리해야 해. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package ssurent.ssurentbe.domain.users.controller; | ||
|
|
||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
| import org.springframework.security.core.userdetails.UserDetails; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import ssurent.ssurentbe.common.base.BaseResponse; | ||
| import ssurent.ssurentbe.common.status.SuccessStatus; | ||
| import ssurent.ssurentbe.domain.users.dto.request.UpdatePhoneNumberRequest; | ||
| import ssurent.ssurentbe.domain.users.dto.response.UserInfoResponse; | ||
| import ssurent.ssurentbe.domain.users.dto.response.UserPenaltyResponse; | ||
| import ssurent.ssurentbe.domain.users.service.UserQueryService; | ||
| import ssurent.ssurentbe.domain.users.service.UserCommandService; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/v1/api/users") | ||
| public class UserController { | ||
| private final UserQueryService userQueryService; | ||
| private final UserCommandService userCommandService; | ||
|
|
||
| @GetMapping | ||
| public UserInfoResponse getMyInfo(@AuthenticationPrincipal UserDetails userDetails) { | ||
| return userQueryService.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 ResponseEntity<Void> updatePhoneNumber( | ||
| @AuthenticationPrincipal UserDetails userDetails, | ||
| @Valid @RequestBody UpdatePhoneNumberRequest request | ||
| ) { | ||
| userCommandService.updatePhoneNumber( | ||
| userDetails.getUsername(), | ||
| request.phoneNum() | ||
| ); | ||
| return ResponseEntity.noContent().build(); | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| @GetMapping("/penalties") | ||
| public ResponseEntity<BaseResponse<List<UserPenaltyResponse>>> getMyPenalties( | ||
| @AuthenticationPrincipal UserDetails userDetails | ||
| ) { | ||
| List<UserPenaltyResponse> data = userQueryService.getMyPenalties(userDetails.getUsername()); | ||
| SuccessStatus status = SuccessStatus.PANELTY_CHECK_SUCCESS; | ||
|
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.
🤖 Prompt for AI Agents |
||
| return ResponseEntity.status(status.getHttpStatus()) | ||
| .body(BaseResponse.success(status, data)); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package ssurent.ssurentbe.domain.users.dto.request; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Pattern; | ||
|
|
||
| public record UpdatePhoneNumberRequest( | ||
| @NotBlank(message = "전화번호는 필수 입력값입니다.") | ||
| @Pattern(regexp = "^01[016789]-?\\d{3,4}-?\\d{4}$", message = "올바른 전화번호 형식이 아닙니다.") | ||
| String phoneNum | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package ssurent.ssurentbe.domain.users.dto.response; | ||
|
|
||
| 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 |
|---|---|---|
| @@ -1,25 +1,24 @@ | ||
| package ssurent.ssurentbe.domain.users.dto.response; | ||
|
|
||
| import ssurent.ssurentbe.domain.item.entity.Items; | ||
| import ssurent.ssurentbe.domain.users.entity.UserPenaltyLog; | ||
| import ssurent.ssurentbe.domain.users.entity.UserPanaltyLog; | ||
| import ssurent.ssurentbe.domain.users.enums.PanaltyTypes; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| public record UserPenaltyResponse( | ||
| Long userPenaltyId, | ||
| LocalDateTime createdAt, | ||
| String itemName, | ||
| String penaltyType | ||
| Long penaltyId, | ||
| PanaltyTypes penaltyType, | ||
| Long itemId, | ||
| Long rentalHistoryId, | ||
| LocalDateTime createdAt | ||
| ) { | ||
| public static UserPenaltyResponse from(UserPenaltyLog userPenaltyLog) { | ||
| Items item = userPenaltyLog.getItemsId(); | ||
| String itemInfo = item.getName() + " (" + item.getItemNum() + ")"; | ||
|
|
||
| public static UserPenaltyResponse from(UserPanaltyLog log) { | ||
| return new UserPenaltyResponse( | ||
| userPenaltyLog.getId(), | ||
| userPenaltyLog.getCreatedAt(), | ||
| itemInfo, | ||
| userPenaltyLog.getPenaltyType().getDescription() | ||
| 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); | ||
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package ssurent.ssurentbe.domain.users.service; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import ssurent.ssurentbe.common.exception.GeneralException; | ||
| import ssurent.ssurentbe.common.status.ErrorStatus; | ||
| import ssurent.ssurentbe.domain.users.entity.Users; | ||
| import ssurent.ssurentbe.domain.users.repository.UserRepository; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Transactional(readOnly = true) | ||
| public class UserCommandService { | ||
| private final UserRepository userRepository; | ||
|
|
||
| public Users getUserInfo(String username) { | ||
| return userRepository.findByStudentNumAndDeletedFalse(username) | ||
| .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); | ||
| } | ||
| @Transactional | ||
| public void updatePhoneNumber(String username, String phoneNum) { | ||
| Users user = getUserInfo(username); | ||
|
|
||
| user.updatePhoneNumber(phoneNum); | ||
| } | ||
| } |
|
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. 서비스도 CQRS 패턴 적용해서 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package ssurent.ssurentbe.domain.users.service; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import ssurent.ssurentbe.common.exception.GeneralException; | ||
| import ssurent.ssurentbe.common.status.ErrorStatus; | ||
| import ssurent.ssurentbe.domain.users.dto.response.UserInfoResponse; | ||
| import ssurent.ssurentbe.domain.users.dto.response.UserPenaltyResponse; | ||
| 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 java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Transactional(readOnly = true) | ||
| public class UserQueryService { | ||
| private final UserRepository userRepository; | ||
| private final UserPanaltyLogRepository userPanaltyLogRepository; | ||
|
|
||
| public Users getUserInfo(String username) { | ||
| return userRepository.findByStudentNumAndDeletedFalse(username) | ||
| .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); | ||
| } | ||
| public UserInfoResponse getMyInfo(String username) { | ||
| Users user = getUserInfo(username); | ||
| return UserInfoResponse.from(user); | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public List<UserPenaltyResponse> getMyPenalties(String username) { | ||
| Users user = getUserInfo(username); | ||
|
|
||
| List<UserPanaltyLog> logs = userPanaltyLogRepository.findByUserIdOrderByCreatedAtDesc(user); | ||
|
|
||
| return logs.stream() | ||
| .map(UserPenaltyResponse::from) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,22 +1,21 @@ | ||||||||||
| # Server | ||||||||||
| server: | ||||||||||
| port: 8080 | ||||||||||
| port: 8080 | ||||||||||
|
|
||||||||||
| # Profiles | ||||||||||
| spring: | ||||||||||
| profiles: | ||||||||||
| active: prod | ||||||||||
| profiles: | ||||||||||
| active: prod | ||||||||||
|
Comment on lines
+7
to
+8
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. 기본 프로파일이
기본값은 🛡️ 수정 제안 spring:
profiles:
- active: prod
+ active: local📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| # Swagger (Springdoc OpenAPI) | ||||||||||
| springdoc: | ||||||||||
| api-docs: | ||||||||||
| path: /api-docs | ||||||||||
| swagger-ui: | ||||||||||
| path: /swagger-ui.html | ||||||||||
| operations-sorter: method | ||||||||||
| tagsSorter: alpha | ||||||||||
| api-docs: | ||||||||||
| path: /api-docs | ||||||||||
| swagger-ui: | ||||||||||
| path: /swagger-ui.html | ||||||||||
| operations-sorter: method | ||||||||||
|
|
||||||||||
| # JWT | ||||||||||
| jwt: | ||||||||||
| access-token-validity: 3600000 | ||||||||||
| refresh-token-validity: 604800000 | ||||||||||
| access-token-validity: 3600000 | ||||||||||
| refresh-token-validity: 604800000 | ||||||||||
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.
오타:
PANELTY→PENALTYPANELTY_CHECK_SUCCESS와 코드"PANELTY_200"모두 "PENALTY"의 오타입니다. API 응답 코드에 포함되는 값이므로 수정이 필요합니다.🐛 수정 제안
📝 Committable suggestion
🤖 Prompt for AI Agents