[feat] 사용자 정보 수정 api 개발#124
Conversation
Walkthrough이번 변경은 사용자 닉네임 업데이트 기능의 도메인, 애플리케이션, 어댑터 계층을 전반적으로 확장합니다. 닉네임 변경 시 유효성 검사(길이, 중복, 빈 값, 6개월 제한 등)를 도입하고, 관련 예외 코드와 API 문서를 추가했습니다. 테스트 코드와 엔터티, 매퍼, 포트, 서비스, 컨트롤러 전반에 걸쳐 닉네임 변경일 필드가 반영되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Controller as UserCommandController
participant Service as UserUpdateService
participant Port as UserCommandPort/UserQueryPort
participant Repo as UserJpaRepository/AliasJpaRepository
Client->>Controller: PATCH /users (UserUpdateRequest)
Controller->>Service: updateUser(UserUpdateCommand)
Service->>Port: findById(userId)
Port->>Repo: findById(userId)
Repo-->>Port: UserJpaEntity
Port-->>Service: User
Service->>Service: validate nickname & alias (중복, 길이, 6개월 등)
Service->>Port: existsByNicknameAndUserIdNot(nickname, userId)
Port->>Repo: existsByNicknameAndUserIdNot
Repo-->>Port: Boolean
Service->>Port: update(User)
Port->>Repo: updateIncludeAliasFrom
Repo-->>Port: 저장 완료
Service-->>Controller: 완료
Controller-->>Client: BaseResponse<Void>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes 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
🪧 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: 5
🧹 Nitpick comments (14)
src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java (1)
69-70: 닉네임 날짜 설정 중복 제거 고려
여기서nicknameUpdatedAt(LocalDate.now().minusMonths(7))을 직접 지정하고 있습니다. 동일한 패턴이 여러 테스트 클래스에 반복되고 있으므로
TestEntityFactory쪽에 “닉네임 변경 가능 사용자” 생성 메서드를 추가하거나- 테스트 클래스 내에
static final LocalDate NICKNAME_UPDATED_AT = LocalDate.now().minusMonths(7);를 두고 재사용하는 편이 가독성과 유지보수에 더 좋습니다.src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java (1)
79-100: 세 사용자 모두 동일한 날짜 상수를 사용하도록 리팩터링 제안
user1,user2,user3에서 각각LocalDate.now().minusMonths(7)를 호출하고 있습니다. 테스트 실행 시점마다 값을 계산하므로 미세하지만 서로 다른 날짜 인스턴스가 생성될 수 있고, 동일 로직이 세 번 반복됩니다.- .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) + .nicknameUpdatedAt(NICKNAME_UPDATED_AT)위와 같이 클래스 상단에
private static final LocalDate NICKNAME_UPDATED_AT = LocalDate.now().minusMonths(7);를 선언하거나
TestEntityFactory.createUserWithOldNickname()등으로 통합하면 중복-코드가 줄고 테스트 의도가 선명해집니다.src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java (1)
80-83: 테스트 고정값 추출 권장
saveUserAndCategory()에서도 매번LocalDate.now().minusMonths(7)를 호출합니다. 앞선 테스트들과 동일한 상수 추출/팩토리화 패턴을 적용하면 재사용성과 가독성이 향상됩니다.src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java (1)
136-141: 루프 내부의 현재 시각 계산 최소화
IntStream루프 안에서 매 번LocalDate.now().minusMonths(7)를 호출하면 호출 시점이 달라질 가능성이 (아주 작지만) 존재합니다. 루프 밖 상수로 뽑아두면 다음과 같이 깔끔해집니다.LocalDate nickUpdatedAt = LocalDate.now().minusMonths(7); ... .nicknameUpdatedAt(nickUpdatedAt)동일한 날짜 보장을 통해 잠재적 flakiness 를 예방할 수 있습니다.
src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java (1)
60-80: 중복된 날짜 계산 상수화
host,member,outsider모두 동일한nicknameUpdatedAt값을 설정합니다. 한 곳에서 상수를 정의하거나TestEntityFactory메서드를 활용해 중복을 제거하면 테스트 코드가 간결해집니다.src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java (1)
94-110: 테스트 데이터 일관성 확보 👍
nicknameUpdatedAt값을 7개월 전으로 지정하여 닉네임 변경 주기(6개월) 검증 로직을 우회하도록 세팅한 점이 적절합니다. 동일 패턴이 여러 테스트 클래스에서 반복되므로, 향후 공통 TestEntityFactory 메서드로 추출하면 유지보수가 더 수월할 것 같습니다.src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java (1)
68-75:nicknameUpdatedAt중복 설정 제거 권장Builder 체이닝 중 동일 필드가 두 번 호출되어 첫 번째(
minusMonths(7)) 값이 즉시 덮어써집니다. 혼란을 방지하기 위해 불필요한 한 줄을 삭제해 주세요.- .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) - .nicknameUpdatedAt(LocalDate.now().minusMonths(1)) + .nicknameUpdatedAt(LocalDate.now().minusMonths(7))src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java (1)
1-92: 포괄적이고 잘 구조화된 단위 테스트
UserUpdateService에 대한 단위 테스트가 매우 잘 작성되었습니다:장점:
- 성공적인 업데이트, 중복 닉네임 처리, 별칭만 업데이트하는 시나리오를 모두 커버
- Mockito를 사용한 적절한 의존성 모킹
- arrange-act-assert 패턴을 명확히 따름
- mock 상호작용에 대한 적절한 검증
- 명확하고 이해하기 쉬운 테스트 메서드명
테스트 데이터 일관성을 위해 기존 사용자의
nicknameUpdatedAt을 7개월 전으로 설정한 것이 다른 테스트 파일들과 일치하여 좋습니다. 도메인 검증 규칙(6개월 제한)을 올바르게 테스트할 수 있습니다.src/test/java/konkuk/thip/user/domain/UserTest.java (3)
35-35: 한국어 주석과 영어 메서드명 혼재 개선 필요Line 35의 주석에서 "영어로 네이밍"이라고 명시되어 있지만 실제로는 한국어 주석이 사용되고 있습니다. 일관성을 위해 전체 테스트 클래스에서 통일된 네이밍 컨벤션을 적용하는 것이 좋겠습니다.
86-86: 테스트 메서드명 일관성 개선다른 테스트 메서드들은 영어로 작성되어 있는데 이 메서드만 한국어로 작성되었습니다. 코드베이스 전체의 일관성을 위해 영어로 통일하는 것을 권장합니다.
- void 닉네임_업데이트_없이_별칭만_변경() { + void updateAliasOnly_success() {
62-69: 테스트 데이터 설정 최적화새로운 User 객체를 생성할 때 필요한 필드만 설정하는 것이 좋겠습니다. 현재는 nicknameUpdatedAt만 필요하지만 builder()를 사용해 불완전한 객체를 생성하고 있습니다.
- user = User.builder() - .nicknameUpdatedAt(LocalDate.now().minusMonths(3)) - .build(); + user = user.withNicknameUpdatedAt(LocalDate.now().minusMonths(3));또는 테스트용 팩토리 메서드를 활용할 수 있습니다.
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1)
45-45: 에러 메시지 개선 제안"다른 사용자가 이미 사용중인 닉네임입니다" 메시지에서 띄어쓰기를 개선할 수 있습니다.
- USER_NICKNAME_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, 70006, "다른 사용자가 이미 사용중인 닉네임입니다."), + USER_NICKNAME_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, 70006, "다른 사용자가 이미 사용 중인 닉네임입니다."),src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java (1)
55-66: 테스트 데이터 설정에서 개선점이 있습니다.테스트 데이터 생성 시 일관성을 위해 TestEntityFactory를 활용하는 것을 고려해보세요.
현재 UserJpaEntity를 직접 빌드하고 있는데, TestEntityFactory.createUser() 메서드를 활용하면 더 일관된 테스트 데이터를 생성할 수 있습니다:
- UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() - .nickname("oldthip") - .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) - .oauth2Id("oauth2_user100") - .role(UserRole.USER) - .aliasForUserJpaEntity(oldAlias) - .build()); + UserJpaEntity user = userJpaRepository.save(TestEntityFactory.createUser(oldAlias, "oldthip")); + // oauth2Id 변경이 필요한 경우에만 별도 설정src/main/java/konkuk/thip/user/domain/User.java (1)
69-71: 6개월 제한 검증 로직에서 개선점이 있습니다.null 체크와 날짜 비교 로직이 올바르지만, 더 명확한 조건식을 사용할 수 있습니다.
현재 로직은 정확하지만 가독성을 위해 다음과 같이 개선할 수 있습니다:
- if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { + if(nicknameUpdatedAt != null && LocalDate.now().isBefore(nicknameUpdatedAt.plusMonths(6))) {또는 더 명확한 변수명을 사용:
// 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가 + LocalDate sixMonthsLater = nicknameUpdatedAt != null ? nicknameUpdatedAt.plusMonths(6) : null; - if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { + if(sixMonthsLater != null && LocalDate.now().isBefore(sixMonthsLater)) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (38)
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java(1 hunks)src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java(1 hunks)src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java(3 hunks)src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java(1 hunks)src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java(1 hunks)src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java(3 hunks)src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java(2 hunks)src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java(1 hunks)src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java(1 hunks)src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java(1 hunks)src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java(1 hunks)src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java(1 hunks)src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java(1 hunks)src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java(1 hunks)src/main/java/konkuk/thip/user/application/service/UserSignupService.java(2 hunks)src/main/java/konkuk/thip/user/application/service/UserUpdateService.java(1 hunks)src/main/java/konkuk/thip/user/domain/User.java(4 hunks)src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java(3 hunks)src/test/java/konkuk/thip/book/adapter/in/web/BookDetailSearchControllerTest.java(1 hunks)src/test/java/konkuk/thip/book/adapter/in/web/BookMostSearchedBooksControllerTest.java(1 hunks)src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java(2 hunks)src/test/java/konkuk/thip/common/util/TestEntityFactory.java(3 hunks)src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java(2 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.java(1 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.java(1 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomGetMemberListApiTest.java(4 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.java(1 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java(6 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomRecruitingDetailViewApiTest.java(1 hunks)src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java(3 hunks)src/test/java/konkuk/thip/room/domain/RoomTest.java(1 hunks)src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java(2 hunks)src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java(1 hunks)src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java(2 hunks)src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java(1 hunks)src/test/java/konkuk/thip/user/application/service/UserUpdateServiceTest.java(1 hunks)src/test/java/konkuk/thip/user/domain/UserTest.java(1 hunks)src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java(3 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: room 도메인에서 startdate는 현재 날짜 이후여야 하는 도메인 규칙이 있어서, 테스트에서 만료된 상태를 시뮬레이션하려면 reflection을 사용해야 한다....
Learnt from: hd0rable
PR: THIP-TextHip/THIP-Server#57
File: src/test/java/konkuk/thip/room/domain/RoomTest.java:0-0
Timestamp: 2025-07-08T16:30:33.771Z
Learning: Room 도메인에서 startDate는 현재 날짜 이후여야 하는 도메인 규칙이 있어서, 테스트에서 만료된 상태를 시뮬레이션하려면 reflection을 사용해야 한다.
Applied to files:
src/test/java/konkuk/thip/room/adapter/in/web/RoomCloseJoinApiTest.javasrc/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.javasrc/test/java/konkuk/thip/room/adapter/in/web/RoomCreateAPITest.javasrc/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.javasrc/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.javasrc/test/java/konkuk/thip/room/adapter/in/web/RoomJoinApiTest.javasrc/test/java/konkuk/thip/room/domain/RoomTest.java
📚 Learning: thip 프로젝트에서는 cqrs port 분리 시 다음 컨벤션을 따름: commandport에는 findbyxxx를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, querypo...
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.
Applied to files:
src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.javasrc/main/java/konkuk/thip/user/application/port/out/UserCommandPort.javasrc/main/java/konkuk/thip/user/application/port/out/UserQueryPort.javasrc/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.javasrc/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java
📚 Learning: thip 프로젝트에서는 "사용자가 방에 속하는지 검증" 로직을 roomparticipantpolicy 도메인 서비스로 캡슐화하여 재사용성을 높이고 비즈니스 로직의 중복을 방지하는 ...
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서는 "사용자가 방에 속하는지 검증" 로직을 RoomParticipantPolicy 도메인 서비스로 캡슐화하여 재사용성을 높이고 비즈니스 로직의 중복을 방지하는 방식을 선호한다.
Applied to files:
src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java
📚 Learning: spring data jpa에서 findby{fieldname} 패턴의 메서드는 명시적 선언 없이 자동으로 생성되며, optional 반환 타입을 사용하는 것이 nu...
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#36
File: src/main/java/konkuk/thip/user/adapter/out/persistence/UserJpaRepository.java:7-7
Timestamp: 2025-06-29T09:47:31.299Z
Learning: Spring Data JPA에서 findBy{FieldName} 패턴의 메서드는 명시적 선언 없이 자동으로 생성되며, Optional<Entity> 반환 타입을 사용하는 것이 null 안전성을 위해 권장됩니다.
Applied to files:
src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java
🧬 Code Graph Analysis (2)
src/main/java/konkuk/thip/user/application/service/UserUpdateService.java (1)
src/main/java/konkuk/thip/user/application/service/UserSignupService.java (1)
Service(17-33)
src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java (1)
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (1)
TestEntityFactory(31-295)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (59)
src/test/java/konkuk/thip/user/adapter/in/web/UserVerifyNicknameControllerTest.java (1)
80-90: 닉네임 중복 검증 사용자에nicknameUpdatedAt필드 설정 👍실제 도메인 제약 조건을 반영하기 위해 7개월 전 날짜를 주입한 점 확인했습니다. 테스트 목적과 잘 부합합니다.
src/test/java/konkuk/thip/book/adapter/in/web/BookChangeSavedControllerTest.java (1)
70-80: 도메인 제약 반영 완료 👍
nicknameUpdatedAt필드 추가로 인해 테스트 실패 가능성을 사전에 차단한 변경으로 보입니다. 추가적인 문제점은 발견되지 않았습니다.src/test/java/konkuk/thip/user/adapter/in/web/UserFollowApiTest.java (1)
58-74: 닉네임 갱신일 필드 추가 확인 👍팔로우 관련 테스트에서도 도메인 변경 사항을 반영하여 일관성을 유지했습니다. 추가 의견 없습니다.
src/main/java/konkuk/thip/user/application/port/out/UserQueryPort.java (1)
12-12: 메서드 추가가 적절합니다.닉네임 업데이트 시 현재 사용자를 제외한 중복 체크를 위한 메서드가 올바르게 추가되었습니다. Spring Data JPA의 네이밍 컨벤션을 따르며, THIP 프로젝트의 CQRS 패턴에도 부합합니다.
src/main/java/konkuk/thip/user/adapter/out/persistence/repository/UserJpaRepository.java (1)
13-13: JPA Repository 메서드가 올바르게 추가되었습니다.Spring Data JPA의 Query Method 네이밍 컨벤션을 정확히 따르며, 특정 사용자를 제외한 닉네임 존재 여부 체크 기능이 적절히 구현되었습니다.
src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java (1)
13-13: 사용자 업데이트 메서드가 적절히 추가되었습니다.CQRS 패턴의 CommandPort 역할에 부합하며, 기존 메서드들과 일관성 있는 네이밍을 따릅니다. void 반환타입도 업데이트 작업에 적합합니다.
src/test/java/konkuk/thip/user/application/service/UserFollowServiceTest.java (1)
24-24: 테스트 클래스 설명이 적절히 추가되었습니다.클래스 레벨의 @DisplayName 어노테이션 추가로 테스트의 목적이 명확해지고, 다른 테스트 클래스들과의 일관성도 향상되었습니다.
src/test/java/konkuk/thip/room/domain/RoomTest.java (1)
24-24: 문자열 리터럴을 Enum 상수로 교체한 개선이 좋습니다.하드코딩된 문자열
"과학/IT"를Category.SCIENCE_ITenum 상수로 변경하여 컴파일 타임 안전성과 코드 유지보수성이 향상되었습니다.src/main/java/konkuk/thip/user/application/port/in/UserUpdateUseCase.java (1)
1-8: Clean Architecture 패턴을 잘 준수한 유즈케이스 인터페이스입니다.입력 포트로서의 역할이 명확하고, 메서드 시그니처가 간단명료합니다.
src/main/java/konkuk/thip/user/application/port/in/dto/UserUpdateCommand.java (1)
3-8: record 클래스를 활용한 깔끔한 DTO 구현입니다.불변성이 보장되고 필요한 필드들이 적절히 포함되어 있습니다.
src/test/java/konkuk/thip/record/adapter/in/web/RecordSearchApiTest.java (2)
411-411: 닉네임 업데이트 제약조건을 고려한 적절한 테스트 데이터 설정입니다.7개월 전 날짜로 설정하여 6개월 제한 검증 로직이 정상 작동할 수 있도록 구성했습니다.
529-529: 테스트 데이터 일관성이 잘 유지되고 있습니다.다른 테스트 메서드와 동일한 방식으로 nicknameUpdatedAt 필드를 설정했습니다.
src/test/java/konkuk/thip/vote/adapter/in/web/VoteCreateControllerTest.java (2)
99-99: 테스트 데이터 일관성 확보를 위한 적절한 필드 추가입니다.다른 테스트 파일들과 동일하게 nicknameUpdatedAt 필드를 7개월 전으로 설정했습니다.
117-118: 하드코딩된 문자열을 Enum으로 교체한 좋은 개선입니다.Category enum을 사용하여 코드의 유지보수성과 타입 안전성이 향상되었습니다.
src/main/java/konkuk/thip/user/adapter/out/persistence/UserQueryPersistenceAdapter.java (1)
26-29: 닉네임 중복 검사 기능이 적절히 구현되었습니다.현재 사용자를 제외한 닉네임 중복 검사가 가능하도록 메서드가 추가되어, 사용자 정보 수정 시 필요한 검증 로직을 지원합니다.
src/test/java/konkuk/thip/book/adapter/in/web/BookQueryControllerTest.java (2)
13-13: 임포트 최적화가 잘 되었습니다.테스트에 필요한 임포트들이 명시적으로 추가되고 정리되었습니다. 특히
LocalDate임포트는 새로운nicknameUpdatedAt필드 사용을 위해 필요한 변경입니다.Also applies to: 19-19, 25-25, 28-28, 30-31
63-63: 닉네임 업데이트 제한 규칙을 고려한 올바른 테스트 데이터 설정입니다.
nicknameUpdatedAt을 7개월 전으로 설정하여 6개월 제한 규칙을 통과할 수 있도록 한 것이 적절합니다. 이는 새로운 닉네임 업데이트 기능의 비즈니스 규칙과 잘 맞습니다.src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java (1)
29-37: 사용자 업데이트 API의 포괄적인 에러 코드 정의가 우수합니다.닉네임 업데이트 기능의 모든 검증 규칙(빈 값, 길이 제한, 중복 검사, 동일 값 검사, 빈도 제한)에 대응하는 에러 코드들이 체계적으로 정의되었습니다. 이는 API 문서화와 클라이언트 개발에 매우 유용할 것입니다.
src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java (1)
16-16: 매퍼에서nicknameUpdatedAt필드 매핑이 올바르게 추가되었습니다.도메인 엔티티와 JPA 엔티티 간의 양방향 매핑이 일관성 있게 구현되어, 닉네임 업데이트 기능이 정상적으로 동작할 수 있습니다.
Also applies to: 28-28
src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java (1)
13-15: 인스턴스 메서드로의 리팩토링이 적절합니다.정적 메서드에서 인스턴스 메서드로 변경하여 DTO가 자신의 상태를 사용해 커맨드 객체를 생성하도록 한 것이 객체지향 설계 원칙에 더 부합합니다.
src/test/java/konkuk/thip/room/adapter/in/web/RoomPlayingDetailViewApiTest.java (2)
14-14: 하드코딩된 문자열을 Enum 상수로 대체한 개선이 우수합니다.
Category.SCIENCE_IT.getImageUrl()을 사용하여 매직 스트링을 제거하고 유지보수성을 향상시켰습니다. 이는 PR 목표에서 언급한 상수를 Enum으로 교체하는 개선 작업의 일환으로 보입니다.Also applies to: 198-198, 246-246, 320-320, 372-372
125-125: 테스트 데이터에nicknameUpdatedAt필드 초기화가 적절합니다.7개월 전으로 설정하여 닉네임 업데이트 6개월 제한 규칙을 만족하도록 한 것이 올바른 테스트 데이터 설정입니다.
src/test/java/konkuk/thip/room/adapter/in/web/RoomSearchApiTest.java (3)
12-12: 도메인 Enum 사용으로 코드 일관성 향상Category 도메인 enum을 import하여 하드코딩된 문자열 대신 타입 안전한 enum을 사용하는 개선사항입니다.
139-139: 새로운 닉네임 업데이트 검증 로직을 지원하는 테스트 데이터 설정nicknameUpdatedAt 필드를 7개월 전으로 설정하여 닉네임 변경 주기 검증 로직(6개월 제한)을 올바르게 테스트할 수 있도록 구성되었습니다.
367-367: 하드코딩된 카테고리 문자열을 도메인 Enum으로 개선
"과학/IT"문자열을Category.SCIENCE_IT.getValue()로 교체하여 타입 안전성과 유지보수성을 크게 향상시켰습니다.src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java (1)
56-70: 검증 완료:updateIncludeAliasFrom메서드 존재 확인
src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java파일 44행에서
public void updateIncludeAliasFrom(User user, AliasJpaEntity aliasJpaEntity)메서드가 정의되어 있는 것을 확인했습니다.위치 확인을 완료했으므로, 해당 변경 사항을 승인합니다.
src/main/java/konkuk/thip/user/application/service/UserSignupService.java (1)
12-12: 사용자 가입 시 닉네임 업데이트 날짜 초기화새로운 사용자 생성 시
nicknameUpdatedAt필드를 현재 날짜로 초기화하는 올바른 구현입니다. 도메인 모델 변경사항과 일관성 있게 반영되었습니다.Also applies to: 28-28
src/test/java/konkuk/thip/common/util/TestEntityFactory.java (3)
17-17: 도메인 Enum import로 타입 안전성 향상Category와 Alias 도메인 enum을 import하여 테스트 팩토리에서 타입 안전한 상수를 사용할 수 있게 되었습니다.
Also applies to: 23-23
39-41: 하드코딩된 문자열을 도메인 Enum으로 교체별칭과 카테고리 생성에서 하드코딩된 문자열을 도메인 enum 상수로 교체하여 유지보수성과 타입 안전성을 크게 향상시켰습니다. 이는 PR 목표와 정확히 일치하는 개선사항입니다.
Also applies to: 47-48, 55-57, 63-64
72-72: 닉네임 업데이트 검증을 위한 일관된 테스트 데이터 설정
nicknameUpdatedAt필드를 7개월 전으로 설정하여 새로운 닉네임 업데이트 검증 로직(6개월 제한)을 테스트할 수 있는 일관된 테스트 데이터를 제공합니다.Also applies to: 82-82
src/test/java/konkuk/thip/user/domain/UserTest.java (1)
77-82: 도메인 로직 검증 완료닉네임과 별칭 업데이트 로직이 올바르게 구현되어 있고, nicknameUpdatedAt 필드가 현재 날짜로 정확히 설정되는지 검증하고 있습니다. 비즈니스 요구사항에 부합합니다.
src/main/java/konkuk/thip/user/application/service/UserUpdateService.java (1)
26-26: 비즈니스 로직 명확성 우수닉네임 업데이트 요청 여부를 null 체크로 판단하는 로직이 명확하고 주석도 적절합니다. 코드 가독성이 좋습니다.
src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java (2)
69-81: REST API 설계 우수PATCH 메서드를 사용한 부분 업데이트 API 설계가 적절하고, Swagger 문서화도 잘 되어 있습니다. 인증된 사용자 ID를 파라미터로 주입받는 방식도 보안상 안전합니다.
63-67: UserFollowRequest.toCommand 검증 완료
UserFollowRequest.toCommand(Long userId, Long targetUserId) 메서드 정의 및 호출 지점을 모두 확인했으며, 현재UserCommandController의userFollowRequest.toCommand(userId, followingUserId)사용은 시그니처와 일치합니다. 추가적인 영향은 없습니다.src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java (1)
8-16: Record 클래스 설계 적절요청 DTO를 Record로 구현한 것이 적절하고, Swagger 스키마 문서화도 잘 되어 있습니다. toCommand 메서드를 통한 계층 분리도 깔끔합니다.
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1)
41-45: 에러 코드 설계 우수새로 추가된 사용자 닉네임 관련 에러 코드들이 기존 패턴과 일관성 있게 구현되었습니다. HTTP 상태 코드(BAD_REQUEST)도 적절하고, 메시지도 명확합니다. 모든 비즈니스 규칙을 잘 커버하고 있습니다.
src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java (6)
1-27: 테스트 클래스 구조가 잘 구성되어 있습니다.필요한 의존성들이 적절히 주입되고, MockMvc 설정과 프로파일 구성이 올바르게 되어 있습니다.
46-50: 테스트 격리를 위한 cleanup 로직이 적절합니다.각 테스트 후 데이터베이스를 정리하여 테스트 간 격리를 보장하고 있습니다.
28-32: 테스트 설정이 적절합니다.SpringBootTest 기반 통합 테스트로 MockMvc를 사용하여 실제 HTTP 요청을 시뮬레이션하고 있습니다. 테스트 프로필 사용과 필터 비활성화 설정이 적절합니다.
46-50: 테스트 격리를 위한 정리 로직이 올바릅니다.각 테스트 후 사용자와 별칭 데이터를 정리하여 테스트 간 격리를 보장하고 있습니다.
72-78: API 요청과 응답 검증이 적절합니다.PATCH 요청과 기본적인 HTTP 상태 코드 검증이 올바르게 구현되어 있습니다.
80-86: 데이터베이스 검증 로직이 완전합니다.업데이트된 사용자의 닉네임과 별칭이 올바르게 변경되었는지 검증하고 있습니다.
src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java (8)
9-9: LocalDate import가 적절히 추가되었습니다.새로 추가된 nicknameUpdatedAt 필드를 위한 필수 import입니다.
27-28: 닉네임 업데이트 날짜 필드가 올바르게 정의되었습니다.데이터베이스 컬럼명과 nullable 제약조건이 적절히 설정되어 있습니다.
44-50: 새로운 업데이트 메서드가 잘 구현되었습니다.alias를 포함한 업데이트를 위한 별도 메서드가 명확한 네이밍과 함께 추가되었습니다.
52-57: 기존 업데이트 메서드가 적절히 수정되었습니다.nicknameUpdatedAt 필드 업데이트가 추가되어 일관성이 유지되고 있습니다.
9-9: LocalDate 임포트가 적절합니다.새로운 nicknameUpdatedAt 필드를 위해 필요한 임포트가 추가되었습니다.
27-29: 닉네임 업데이트 날짜 필드 정의가 올바릅니다.LocalDate 타입 사용과 nullable = false 설정이 적절하며, 컬럼명도 명확합니다. 주석으로 저장 형식을 명시한 것도 좋습니다.
44-51: 새로운 업데이트 메서드가 잘 구현되었습니다.별칭을 포함한 사용자 정보 업데이트를 위한 전용 메서드로, 모든 필요한 필드를 적절히 업데이트하고 있습니다.
52-58: 기존 업데이트 메서드가 올바르게 수정되었습니다.nicknameUpdatedAt 필드 업데이트가 추가되어 도메인 객체와의 일관성을 유지하고 있습니다.
src/main/java/konkuk/thip/user/domain/User.java (9)
9-9: LocalDate import가 적절히 추가되었습니다.새로 추가된 nicknameUpdatedAt 필드를 위한 필수 import입니다.
19-19: 닉네임 업데이트 날짜 필드가 올바르게 추가되었습니다.도메인 엔티티에 닉네임 변경 추적을 위한 필드가 적절히 추가되었습니다.
29-39: 팩토리 메서드가 적절히 수정되었습니다.새로운 필드를 포함하도록 withoutId 메서드가 올바르게 업데이트되었습니다.
52-59: 사용자 정보 업데이트 로직이 잘 구현되었습니다.닉네임 업데이트 요청 여부에 따른 조건부 처리와 별칭은 항상 업데이트하는 로직이 명확합니다.
9-10: LocalDate 임포트가 적절합니다.닉네임 업데이트 날짜 추적을 위해 필요한 임포트가 추가되었습니다.
19-20: 닉네임 업데이트 날짜 필드가 적절히 추가되었습니다.LocalDate 타입으로 날짜만 저장하는 것이 닉네임 업데이트 제한 로직에 적합합니다.
29-39: 팩토리 메서드 업데이트가 올바릅니다.새로운 필드를 받도록 시그니처가 확장되어 객체 생성 시 일관성을 유지하고 있습니다.
52-60: 사용자 정보 업데이트 로직이 잘 설계되었습니다.닉네임 업데이트 요청 여부에 따른 조건부 처리와 별칭은 항상 업데이트하는 로직이 명확합니다.
61-76: 닉네임 검증 로직이 포괄적이고 올바릅니다.모든 비즈니스 규칙이 적절한 순서로 검증되고 있으며, 각각에 대해 명확한 에러 코드를 사용하고 있습니다.
| @Schema(description = "사용자 수정 닉네임", example = "thip") | ||
| String nickname |
There was a problem hiding this comment.
🛠️ Refactor suggestion
닉네임 필드 검증 누락
aliasName에는 @notblank 검증이 있지만, nickname 필드에는 검증 어노테이션이 없습니다. 도메인 로직에서 닉네임 길이와 공백을 검증하고 있지만, API 레벨에서도 기본적인 검증을 추가하는 것이 좋겠습니다.
@Schema(description = "사용자 수정 닉네임", example = "thip")
+ @Size(max = 10, message = "닉네임은 10자 이하여야 합니다.")
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.
| @Schema(description = "사용자 수정 닉네임", example = "thip") | |
| String nickname | |
| @Schema(description = "사용자 수정 닉네임", example = "thip") | |
| @Size(max = 10, message = "닉네임은 10자 이하여야 합니다.") | |
| String nickname |
🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/user/adapter/in/web/request/UserUpdateRequest.java
at lines 14-15, the nickname field lacks validation annotations unlike
aliasName. Add a @NotBlank annotation to the nickname field to ensure it is not
empty or null at the API level, providing basic validation before domain logic
checks.
| if(isNicknameUpdateRequest && userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) { | ||
| throw new BusinessException(ErrorCode.USER_NICKNAME_ALREADY_EXISTS); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
닉네임 중복 검사 순서 개선 필요
닉네임 중복 검사가 도메인 객체 검증 이후에 수행되고 있습니다. 하지만 도메인 검증에서 예외가 발생하면 중복 검사가 실행되지 않습니다. 논리적으로는 중복 검사를 먼저 수행하는 것이 더 효율적입니다.
User user = userCommandPort.findById(command.userId());
+
+ if(isNicknameUpdateRequest && userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) {
+ throw new BusinessException(ErrorCode.USER_NICKNAME_ALREADY_EXISTS);
+ }
+
user.updateUserInfo(command.nickname(), alias, isNicknameUpdateRequest);
- if(isNicknameUpdateRequest && userQueryPort.existsByNicknameAndUserIdNot(command.nickname(), command.userId())) {
- throw new BusinessException(ErrorCode.USER_NICKNAME_ALREADY_EXISTS);
- }🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/user/application/service/UserUpdateService.java
around lines 31 to 33, the nickname duplication check is currently performed
after domain object validation, which can skip the duplication check if domain
validation fails. To fix this, reorder the logic to perform the nickname
duplication check before any domain validation to ensure it always runs first
and improves efficiency.
| private void validateCanUpdateNickname(String nickname) { | ||
| if(nickname.isBlank()) { // 빈칸 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_BLANK); | ||
| } | ||
| if(nickname.length() > 10) { // 10자 이상 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_TOO_LONG); | ||
| } | ||
| // 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가 | ||
| if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_UPDATE_TOO_FREQUENT); | ||
| } | ||
| if(nickname.equals(this.nickname)) { // 현재 닉네임과 같으면 업데이트 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME); | ||
| } | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
닉네임 검증 로직에서 null 체크를 강화해주세요.
현재 nicknameUpdatedAt가 null인 경우에 대한 처리가 있지만, 새로 생성되는 사용자의 경우를 더 명확하게 처리하는 것이 좋겠습니다.
다음과 같이 수정을 고려해보세요:
private void validateCanUpdateNickname(String nickname) {
if(nickname.isBlank()) {
throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_BLANK);
}
if(nickname.length() > 10) {
throw new InvalidStateException(ErrorCode.USER_NICKNAME_TOO_LONG);
}
if(nickname.equals(this.nickname)) {
throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME);
}
// 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가
// null인 경우는 최초 생성 시점이므로 업데이트 허용
if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) {
throw new InvalidStateException(ERROR.USER_NICKNAME_UPDATE_TOO_FREQUENT);
}
}또한 검증 순서를 재고려해보세요. 같은 닉네임 체크를 더 빠른 시점에 하는 것이 효율적일 수 있습니다.
🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/user/domain/User.java around lines 61 to 75,
improve the nickname validation by moving the check for the nickname being the
same as the current one before the nicknameUpdatedAt check, and ensure the null
check for nicknameUpdatedAt remains after that. This change clarifies that if
nicknameUpdatedAt is null (new user), the update is allowed, and avoids
unnecessary date checks when the nickname hasn't changed. Adjust the order of
validations accordingly to enhance efficiency and clarity.
| @Test | ||
| @DisplayName("사용자 닉네임과 별칭이 정상적으로 업데이트된다.") | ||
| void updateUser_success() throws Exception { | ||
| // given: 기존 alias 및 user 생성 | ||
| AliasJpaEntity oldAlias = aliasJpaRepository.save(TestEntityFactory.createScienceAlias()); | ||
| AliasJpaEntity newAlias = aliasJpaRepository.save(TestEntityFactory.createLiteratureAlias()); | ||
|
|
||
| UserJpaEntity user = userJpaRepository.save(UserJpaEntity.builder() | ||
| .nickname("oldthip") | ||
| .nicknameUpdatedAt(LocalDate.now().minusMonths(7)) | ||
| .oauth2Id("oauth2_user100") | ||
| .role(UserRole.USER) | ||
| .aliasForUserJpaEntity(oldAlias) | ||
| .build()); | ||
|
|
||
| Long userId = user.getUserId(); | ||
|
|
||
| UserUpdateRequest userUpdateRequest = new UserUpdateRequest(newAlias.getValue(),"newthip"); | ||
|
|
||
| // when: API 요청 | ||
| mockMvc.perform(patch("/users") | ||
| .requestAttr("userId", userId) | ||
| .contentType(MediaType.APPLICATION_JSON) | ||
| .content(objectMapper.writeValueAsString(userUpdateRequest))) | ||
| // then: HTTP 응답 상태 및 기본 응답 검증 | ||
| .andExpect(status().isOk()) | ||
| .andExpect(jsonPath("$.data").doesNotExist()); | ||
|
|
||
| // DB 검증: 닉네임과 alias가 업데이트되었는지 확인 | ||
| UserJpaEntity updatedUser = userJpaRepository.findById(userId).orElseThrow(); | ||
| assertThat(updatedUser.getNickname()).isEqualTo("newthip"); | ||
|
|
||
| AliasJpaEntity updatedAlias = aliasJpaRepository.findById(updatedUser.getAliasForUserJpaEntity().getAliasId()).orElseThrow(); | ||
| assertThat(updatedAlias.getValue()).isEqualTo(newAlias.getValue()); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
통합 테스트 시나리오 확장을 고려해보세요.
현재 성공 케이스만 테스트하고 있습니다. 닉네임 검증 실패 케이스들도 추가로 테스트하는 것이 좋겠습니다.
다음과 같은 추가 테스트 케이스들을 고려해보세요:
@Test
@DisplayName("닉네임이 10자를 초과하면 업데이트에 실패한다.")
void updateUser_fail_nicknameTooLong() throws Exception {
// 테스트 구현
}
@Test
@DisplayName("닉네임 변경 후 6개월이 지나지 않으면 업데이트에 실패한다.")
void updateUser_fail_nicknameUpdateTooFrequent() throws Exception {
// 테스트 구현
}
@Test
@DisplayName("중복된 닉네임으로 업데이트하면 실패한다.")
void updateUser_fail_duplicateNickname() throws Exception {
// 테스트 구현
}🤖 Prompt for AI Agents
In src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java around
lines 52 to 86, the current test only covers the successful user update
scenario. To improve test coverage, add new test methods to cover failure cases
such as when the nickname exceeds 10 characters, when a nickname update is
attempted before 6 months have passed since the last update, and when trying to
update to a duplicate nickname. Implement these tests by setting up appropriate
user data, making the patch request with invalid inputs, and asserting that the
update fails with the expected error responses.
🛠️ Refactor suggestion
에러 케이스 테스트가 누락되었습니다.
성공 케이스만 테스트하고 있어 중요한 검증 시나리오들이 빠져있습니다.
다음과 같은 에러 케이스들에 대한 테스트를 추가해야 합니다:
- 닉네임이 공백인 경우
- 닉네임이 10자를 초과하는 경우
- 6개월 이내에 닉네임을 변경하려는 경우
- 중복 닉네임을 사용하려는 경우
- 존재하지 않는 별칭을 사용하려는 경우
예시:
@Test
@DisplayName("닉네임이 공백인 경우 400 에러를 반환한다.")
void updateUser_blankNickname_badRequest() throws Exception {
// given
AliasJpaEntity alias = aliasJpaRepository.save(TestEntityFactory.createScienceAlias());
UserJpaEntity user = userJpaRepository.save(TestEntityFactory.createUser(alias));
UserUpdateRequest request = new UserUpdateRequest(alias.getValue(), "");
// when & then
mockMvc.perform(patch("/users")
.requestAttr("userId", user.getUserId())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errorCode").value("USER_NICKNAME_CANNOT_BE_BLANK"));
}🤖 Prompt for AI Agents
In src/test/java/konkuk/thip/user/adapter/in/web/UserUpdateApiTest.java between
lines 52 and 86, the test class only covers the successful user update scenario
and lacks tests for important error cases. Add separate test methods for each
error case: nickname being blank, nickname exceeding 10 characters, attempting
to change nickname within 6 months, using a duplicate nickname, and using a
non-existent alias. Each test should prepare the necessary data, perform the
PATCH request with invalid input, and assert that the response status is 400 Bad
Request with the appropriate error code in the JSON response.
seongjunnoh
left a comment
There was a problem hiding this comment.
고생하셨습니다! 궁금한 점 리뷰로 남겨두었는데 확인 부탁드립니다!
| private void validateCanUpdateNickname(String nickname) { | ||
| if(nickname.isBlank()) { // 빈칸 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_BLANK); | ||
| } | ||
| if(nickname.length() > 10) { // 10자 이상 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_TOO_LONG); | ||
| } | ||
| // 닉네임을 변경한지 6개월이 지나지 않았으면 닉네임 업데이트 불가 | ||
| if(nicknameUpdatedAt != null && nicknameUpdatedAt.isAfter(LocalDate.now().minusMonths(6))) { | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_UPDATE_TOO_FREQUENT); | ||
| } | ||
| if(nickname.equals(this.nickname)) { // 현재 닉네임과 같으면 업데이트 불가 | ||
| throw new InvalidStateException(ErrorCode.USER_NICKNAME_CANNOT_BE_SAME); | ||
| } | ||
| } |
| @Schema(description = "사용자 정보 수정 요청 DTO") | ||
| public record UserUpdateRequest( | ||
|
|
||
| @Schema(description = "사용자 수정 칭호", example = "문학가") | ||
| @NotBlank(message = "칭호는 필수입니다.") | ||
| String aliasName, | ||
|
|
||
| @Schema(description = "사용자 수정 닉네임", example = "thip") |
There was a problem hiding this comment.
p3 : 이렇게 @Schema 어노테이션을 추가하면 스웨거 상에서도 request dto의 description을 확인할 수 있는건가요?
There was a problem hiding this comment.
p3 : 추가로 nickname 이 10자 이하여야 한다는 것을 request dto 단에서 수행하는 것이 아니라, User 도메인 내부에서 수행하신 이유가 있을까요?? 닉네임이 10자 이하여야 한다 라는 도메인 규칙을 맞추기 위함인가요?
There was a problem hiding this comment.
p3 : 이렇게 @Schema 어노테이션을 추가하면 스웨거 상에서도 request dto의 description을 확인할 수 있는건가요?
넵 확인 가능합니다!
There was a problem hiding this comment.
p3 : 추가로 nickname 이 10자 이하여야 한다는 것을 request dto 단에서 수행하는 것이 아니라, User 도메인 내부에서 수행하신 이유가 있을까요?? 닉네임이 10자 이하여야 한다 라는 도메인 규칙을 맞추기 위함인가요?
현재 nickname은 pr 설명에서도 적어놓으셨듯이, null로 오는 경우가 존재해서 그 경우를 핸들링하기 위해 도메인에서 처리해주었습니다!
There was a problem hiding this comment.
p3 : 이렇게 @Schema 어노테이션을 추가하면 스웨거 상에서도 request dto의 description을 확인할 수 있는건가요?
넵 확인 가능합니다!
오 좋습니다! 저도 적용해보겠습니다!
There was a problem hiding this comment.
p3 : 추가로 nickname 이 10자 이하여야 한다는 것을 request dto 단에서 수행하는 것이 아니라, User 도메인 내부에서 수행하신 이유가 있을까요?? 닉네임이 10자 이하여야 한다 라는 도메인 규칙을 맞추기 위함인가요?
현재 nickname은 pr 설명에서도 적어놓으셨듯이, null로 오는 경우가 존재해서 그 경우를 핸들링하기 위해 도메인에서 처리해주었습니다!
넵넵 아무래도 도메인 규칙이 맞으니, 도메인 레벨에 검증하는 로직이 있는게 맞는거 같네요.
현재 request 에서 수행하는 bean validation 중 도메인 규칙에 해당하는 친구들은 도메인 레이어로 옮기는 것 또한 리펙토링 포인트로 생각해봐도 좋을 것 같네요! (수정해야하는게 도대체 몇개죠 허허)
There was a problem hiding this comment.
ㅋㅋㅋㅋ좋습니다! 그 부분은 급한건 아니니 일단 미뤄보죠 🥲
| @Column(name = "nickname_updated_at", nullable = false) | ||
| private LocalDate nicknameUpdatedAt; // 날짜 형식으로 저장 (예: "2023-10-01") | ||
|
|
There was a problem hiding this comment.
요구사항을 구현하려면 이게 있어야 하겠네요. 확인했습니다
| @DisplayName("[단위] User 단위 테스트") | ||
| class UserTest { | ||
|
|
#️⃣ 연관된 이슈
📝 작업 내용
프로필 편집 시 다음과 같은 경우가 존재합니다.
칭호는 무조건 전달되기 때문에 무조건 주어진 alias로 업데이트되고 nickname의 경우 다음과 같은 유효성 검증을 거칩니다.
📸 스크린샷
💬 리뷰 요구사항
기존 로컬 DB에 존재하는 데이터 유지시킨채로 nicknameUpdatedAt 컬럼을 추가하려면 sql console에 아래 쿼리 날리시면 됩니다~
추가적으로, 현재 테스트 코드에 카테고리, 칭호와 같은 상수를 문자열로 그대로 사용되고 있어, 유지보수에 좋지 않을 것 같아 최대한 Enum으로 대체하긴 했습니다. 추후에 더 발견되면 그때그때 바꿔줘야 할 것 같습니다 😭
📌 PR 진행 시 이러한 점들을 참고해 주세요
Summary by CodeRabbit
신규 기능
버그 수정
테스트
문서화