-
Notifications
You must be signed in to change notification settings - Fork 1
[feat] 유저 및 반려견 정보 수정 API 구현 #201
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
base: develop
Are you sure you want to change the base?
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough사용자와 반려견의 정보 수정 기능을 추가하면서 나이 기반 데이터를 생년월일 기반으로 변경합니다. 반려견 특성(trait) 관련 기능을 제거하고, Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant UC as UserController
participant UUF as UpdateUserInfoFacade
participant US as UserService
participant UQS as UserQueryService
participant UR as UserRepository
participant DB as Database
Client->>UC: PATCH /api/v1/users/me/userInfo<br/>userId, UpdateUserInfoRequestDto
UC->>UUF: execute(userId, command)
rect rgb(200, 220, 240)
Note over UUF,DB: User Info Update Flow
UUF->>US: updateUserInfo(userId, command)
US->>UR: findById(userId)
UR->>DB: SELECT User WHERE userId
DB-->>UR: UserEntity
UR-->>US: UserEntity
rect rgb(240, 220, 200)
Note over US: Authorization Check<br/>(if needed)
end
US->>US: updateProfile(name, birth, gender)
US->>UR: save(userEntity)
UR->>DB: UPDATE User SET name, birth, gender
DB-->>UR: success
UR-->>US: updated UserEntity
end
rect rgb(220, 240, 200)
Note over UUF,DB: Fetch Updated Info
UUF->>UQS: getUserInfo(userId)
UQS->>UR: findById(userId)
UR->>DB: SELECT User WHERE userId
DB-->>UR: UserEntity
UR-->>UQS: UserEntity
UQS->>UQS: Build UserInfoResponseDto
UQS-->>UUF: UserInfoResponseDto
end
UUF-->>UC: UserInfoResponseDto
UC-->>Client: ApiResponse<UserInfoResponseDto>
sequenceDiagram
actor Client
participant UC as UserController
participant UPCF as UserPetCommandFacade
participant PS as PetService
participant PR as PetRepository
participant UPQS as UserPetQueryService
participant DB as Database
Client->>UC: PATCH /api/v1/users/me/pets/{petId}<br/>userId, petId, UpdatePetRequestDto
UC->>UPCF: updatePetInfo(userId, petId, command)
rect rgb(200, 220, 240)
Note over UPCF,DB: Pet Update with Auth Check
UPCF->>PS: updatePetInfo(userId, petId, command)
PS->>PR: findById(petId)
PR->>DB: SELECT Pet WHERE petId
DB-->>PR: PetEntity
PR-->>PS: PetEntity
rect rgb(240, 200, 200)
Note over PS: Authorization Validation<br/>user.userId == pet.user.userId?<br/>if false → UNAUTHORIZED_ACCESS
end
PS->>PS: updateProfile(name, birth, gender,<br/>isNeutered, breed)
PS->>PR: save(petEntity)
PR->>DB: UPDATE Pet SET name, birth, gender...
DB-->>PR: success
UR-->>PS: updated PetEntity
end
rect rgb(220, 240, 200)
Note over UPCF,DB: Fetch Updated Pet Profile
UPCF->>UPQS: getPetProfile(petId)
UPQS->>PR: findById(petId)
PR->>DB: SELECT Pet WHERE petId
DB-->>PR: PetEntity
PR-->>UPQS: PetEntity
UPQS->>UPQS: Build PetProfileResponseDto<br/>from(petEntity)
UPQS-->>UPCF: PetProfileResponseDto
end
UPCF-->>UC: PetProfileResponseDto
UC-->>Client: ApiResponse<PetProfileResponseDto>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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 |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
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.
Actionable comments posted: 8
Fix all issues with AI Agents 🤖
In
@src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.java:
- Line 28: In AppleTokenVerifier.java update the deprecated import: replace the
old io.jsonwebtoken.SignatureException import with
io.jsonwebtoken.security.SignatureException to match the jjwt 0.12+ API used by
verifyWith(); ensure the import at the top of the AppleTokenVerifier class is
changed so caught/handled exceptions reference the new SignatureException type
consistent with verifyWith().
In
@src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/UpdatePetRequestDto.java:
- Line 6: Remove the unused import of UpdateUserInfoCommand from
UpdatePetRequestDto.java; locate the import statement "import
org.sopt.pawkey.backendapi.domain.user.application.dto.request.UpdateUserInfoCommand;"
in the UpdatePetRequestDto class and delete it (or run your IDE's
optimize/organize imports) so there are no unused imports left.
In
@src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/request/UpdatePetCommand.java:
- Around line 5-11: The UpdatePetCommand record is missing validation
annotations for the gender and birth fields; add @Pattern(regexp = "^(M|F)$",
message = "성별은 M 또는 F이어야 합니다.") to the gender field and @PastOrPresent(message =
"생년월일은 현재 또는 과거 날짜여야 합니다") to the birth field (keeping the same constraints used
by PetRequestDto/entity), and import the corresponding
javax.validation.constraints annotations so validation runs on UpdatePetCommand
(or UpdatePetRequestDto) during request binding.
In
@src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java:
- Around line 93-99: UpdatePetRequestDto currently only validates birth with
@NotNull so future dates can slip through; add the javax.validation.constraint
@PastOrPresent to the birth field in UpdatePetRequestDto so the API layer
rejects future dates before reaching PetEntity.updateProfile, ensuring the birth
property is validated during request binding/validation.
In
@src/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/UpdateUserInfoRequestDto.java:
- Around line 18-20: The gender field in UpdateUserInfoRequestDto currently only
uses @NotBlank and allows invalid values; change it to a strongly-typed enum by
creating a Gender enum with values M and F, update the DTO's gender type to
Gender and replace @NotBlank with @NotNull (and keep the @Schema
description/example), and then adjust any code that maps/deserializes the
request (controllers/services) to handle Gender instead of String;
alternatively, if you prefer not to add an enum, validate the String with
@Pattern(regexp = "^[MF]$") and a @NotBlank/@NotNull to enforce only "M" or "F".
In
@src/main/java/org/sopt/pawkey/backendapi/domain/user/domain/repository/SocialAccountRepository.java:
- Line 15: findByUser_UserId currently returns an Optional<SocialAccountEntity>
without platform or primary-account constraints, which is unsafe because a user
can have multiple SocialAccountEntity rows; update the repository and/or domain
to make the intent explicit: either remove findByUser_UserId and replace calls
in UserQueryService with a repository method that includes platform (e.g.,
findByUser_UserIdAndPlatform) or add a primary flag to SocialAccountEntity and a
query like findByUser_UserIdAndIsPrimaryTrue, or alternatively add a
@OneToMany(mappedBy="user") collection to UserEntity and change UserQueryService
to select the correct account deterministically (by platform or primary) before
assuming a single result; ensure all usages of findByUser_UserId are updated to
the chosen deterministic query.
In
@src/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/entity/UserEntity.java:
- Around line 57-59: Region became non-nullable on UserEntity (the region field
annotated with @JoinColumn(name = "region_id")), but
UserService.findOrCreateUserBySocialId still constructs users with region(null),
causing runtime constraint errors; either revert to @JoinColumn(name =
"region_id", nullable = true) on the RegionEntity reference or update
findOrCreateUserBySocialId to supply a valid RegionEntity (e.g., fetch or create
a default Region via RegionRepository and set it on the new UserEntity) so new
users never get region = null, ensuring consistency with the DB constraint.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostFilterController.java (2)
56-56: 불필요한 타입 변환을 제거하세요.Line 54에서
userId가 이미Long타입으로 선언되어 있으므로, Line 56의Long.valueOf(userId)호출은 불필요합니다.🔎 수정 제안
- PostListResponseDto response = postQueryFacade.getFilterPostList(requestDto, Long.valueOf(userId)); + PostListResponseDto response = postQueryFacade.getFilterPostList(requestDto, userId);
40-45: GET 엔드포인트를 @userid 어노테이션으로 마이그레이션하고 미사용 파라미터를 정리해주세요.현재 PostFilterController의 두 엔드포인트가 서로 다른 인증 방식을 사용하고 있으며, 이는 의도된 설계가 아닌 불완전한 마이그레이션으로 보입니다.
변경 필요 사항:
- GET 엔드포인트(Line 41):
@RequestHeader(USER_ID_HEADER) @NotNull Integer userId→@UserId Long userId로 통일- POST 엔드포인트(Line 54)와 코드베이스 전체에서 사용 중인 표준 패턴 적용
- 추가로, GET 엔드포인트에서 userId 파라미터를 받지만 메서드 본문(Line 43)에서 사용하지 않음. 파라미터가 필요없다면 제거하거나, 필요하다면 코드에 반영해주세요.
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetRepositoryImpl.java (1)
17-19: 중복된 리포지토리 필드를 통합하세요.동일한 타입(
SpringDataPetRepository)의 필드가 두 개 선언되어 있습니다:
- Line 17:
springDataPetRepository- Line 19:
petRepository이는 혼란을 야기하고 유지보수를 어렵게 만듭니다. 하나의 필드로 통합하고 모든 메서드에서 일관되게 사용해야 합니다.
🔎 제안하는 수정
private final SpringDataPetRepository springDataPetRepository; - - private final SpringDataPetRepository petRepository; @Override public PetEntity save(PetEntity pet) { return springDataPetRepository.save(pet); } public List<PetEntity> findAllPetsByUserId(Long userId) { - return petRepository.findAllByUser_UserId(userId); + return springDataPetRepository.findAllByUser_UserId(userId); } @Override public Optional<PetEntity> findById(Long petId) { return springDataPetRepository.findById(petId); }
🧹 Nitpick comments (12)
src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/withdraw/GoogleWithdrawService.java (1)
34-39: 예외 처리 개선을 권장합니다.현재 구현은 모든 예외를
Exception으로 포괄적으로 처리하고 있으며, 원본 예외 정보가 손실됩니다. 다음 개선 사항을 고려해보세요:
- 원본 예외를 cause로 전달하여 디버깅 시 스택 트레이스 보존
- 예외 발생 시 로깅 추가로 모니터링 개선
- 가능하다면 더 구체적인 예외 타입 처리
🔎 개선된 예외 처리 제안
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers); try{ restTemplate.postForEntity(revokeUri,request, Void.class); } catch(Exception e){ - throw new AuthBusinessException(AuthErrorCode.SOCIAL_WITHDRAW_FAIL); + // 원본 예외를 cause로 전달하여 스택 트레이스 보존 + throw new AuthBusinessException(AuthErrorCode.SOCIAL_WITHDRAW_FAIL, e); }참고:
AuthBusinessException생성자가 cause를 지원하지 않는 경우, 생성자 추가를 고려하거나 최소한 로깅을 추가하는 것을 권장합니다.src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.java (1)
109-112: ExpiredJwtException에 대해 더 적절한 에러 코드 사용을 고려해 주세요.토큰 만료(
ExpiredJwtException)와 서명 오류(SignatureException)는 다른 실패 유형입니다. 현재 둘 다TOKEN_SIGNATURE_INVALID로 매핑되어 있는데, 클라이언트가 만료와 서명 오류를 구분하여 적절한 대응(예: 토큰 갱신 vs 재로그인)을 할 수 있도록 별도의 에러 코드(예:TOKEN_EXPIRED) 사용을 검토해 보세요.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserQueryFacade.java (1)
4-6: 미사용 import 제거를 권장합니다.
UpdateUserInfoCommand와UserEntity를 import하고 있지만 파일 내에서 사용되지 않습니다. 코드 정리를 위해 제거하는 것이 좋습니다.🔎 제안하는 수정
import org.sopt.pawkey.backendapi.domain.user.api.dto.response.UserInfoResponseDto; -import org.sopt.pawkey.backendapi.domain.user.application.dto.request.UpdateUserInfoCommand; import org.sopt.pawkey.backendapi.domain.user.application.service.UserQueryService; -import org.sopt.pawkey.backendapi.domain.user.infra.persistence.entity.UserEntity; import org.springframework.stereotype.Service;src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UpdateUserInfoFacade.java (1)
1-1: 패키지 구조 일관성 검토 필요
UpdateUserInfoFacade가facade루트 패키지에 위치해 있지만,UserPetCommandFacade는facade.command에,UserQueryFacade는facade.query에 위치합니다. PR 설명에서도 Facade 네이밍 통일이 제안되었으므로, Command/Query 분리 원칙에 따라facade.command패키지로 이동하는 것이 좋겠습니다.-package org.sopt.pawkey.backendapi.domain.user.application.facade; +package org.sopt.pawkey.backendapi.domain.user.application.facade.command;src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/UpdatePetRequestDto.java (1)
17-18: gender 필드에 대한 유효성 검증 강화 권장현재
@NotBlank만 적용되어 있어 "M", "F" 외의 값도 허용됩니다.@Pattern어노테이션을 추가하거나 enum 타입을 사용하여 유효한 값만 허용하도록 개선할 수 있습니다.🔎 제안: Pattern 어노테이션 추가
@Schema(description = "반려견 성별 (M/F)", example = "M") +@Pattern(regexp = "^[MF]$", message = "성별은 M 또는 F만 허용됩니다.") @NotBlank String gender,src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserPetQueryService.java (1)
29-34: getPetProfile 메서드의 소유권 검증 부재 - 설계 개선 권장
getPetProfile(Long petId)메서드는petId만을 기반으로 반려견 정보를 조회하며 소유권 검증을 수행하지 않습니다.현재 코드에서는
UserPetCommandFacade.updatePetInfo내에서petService.updatePetInfo(userId, petId, command)가 먼저 호출되어 소유권을 검증한 후getPetProfile(petId)을 호출하므로 실제 보안 문제는 없습니다. 그러나 이 메서드가 다른 곳에서 재사용되거나 향후에 독립적으로 호출될 수 있으므로, 방어 심층(defense in depth) 원칙 관점에서userId파라미터를 추가하여 메서드 레벨에서 소유권을 검증하는 것을 권장합니다.비교 참고:
UserPetQueryFacade.getUserPets는userService.findById(userId)→getPetProfiles(user)패턴으로 검증 후 조회를 수행합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserQueryService.java (1)
29-31: 이메일이 없는 경우 빈 문자열 대신 null 반환을 고려하세요.현재 소셜 계정이 없는 경우 빈 문자열(
"")을 반환합니다. 이는 데이터가 실제로 없는 상황을 숨길 수 있습니다.null을 반환하거나UserInfoResponseDto에서Optional<String>또는 nullable 필드를 사용하는 것이 더 명시적일 수 있습니다.String email = socialAccountRepository.findByUser_UserId(userId) .map(SocialAccountEntity::getPrimaryEmail) .orElse(null); // 또는 Optional<String>을 고려src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.java (1)
14-18: 사용되지 않는 컨트롤러와 필드를 제거하세요.
PetController는 class-level@RequestMapping애노테이션만 있고 실제 핸들러 메서드가 없으며,petQueryService필드도 사용되지 않습니다. Pet 관련 엔드포인트는UserController에 이미 구현되어 있습니다(/me/pets,/me/pets/{petId}). 이 컨트롤러는 불필요한 dead code이므로 제거를 권장합니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetProfileResponseDto.java (2)
41-48:convertGender에서 예외 발생 시 API 응답 실패 가능성 검토 필요DB에 저장된 성별 값이 "M" 또는 "F"가 아닌 경우
IllegalArgumentException이 발생하여 API 응답이 실패합니다. 입력 시 validation이 있더라도, 기존 데이터나 마이그레이션 이슈로 인한 데이터 정합성 문제가 있을 수 있습니다.
UserInfoResponseDto.parseGender처럼 기본값 반환 방식을 고려해보세요.🔎 제안: 방어적 처리 적용
private static String convertGender(String gender) { - if ("M".equals(gender)) { - return "남아"; - } else if ("F".equals(gender)) { - return "여아"; - } - throw new IllegalArgumentException("올바르지 않은 성별 값입니다: " + gender); + return switch (gender) { + case "M" -> "남아"; + case "F" -> "여아"; + default -> gender; + }; }
35-39:calculateAgeInMonths의 null 체크와 엔티티 정의 간 불일치
PetEntity.birth컬럼은nullable = false로 정의되어 있지만, 여기서는 null 체크를 수행합니다. 방어적 코딩으로는 좋으나, 실제로 null이 들어올 수 없다면 이 체크는 불필요할 수 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.java (1)
42-44: PetService에서 UserBusinessException 사용 검토
PetService에서UserBusinessException을 사용하는 것은 도메인 경계를 넘는 의존성입니다.PetErrorCode에UNAUTHORIZED_ACCESS를 추가하고PetBusinessException을 사용하는 것이 도메인 응집도 측면에서 더 적절할 수 있습니다.관련 코드 스니펫에서
PetBusinessException은PetErrorCode만 받도록 설계되어 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserService.java (1)
34-44: 시그니처 변경은 모두 반영되었으나, 메서드 이름의 명확성 개선 권장
saveUser메서드 호출 검증 결과,UserRegisterFacade.java의 유일한 호출 위치에서 새로운 시그니처(userId 매개변수 포함)가 올바르게 반영되어 있습니다. 시그니처 변경으로 인한 호출 위치 누락 문제는 없습니다.다만, 메서드 이름 개선은 여전히 검토할 가치가 있습니다. 현재
saveUser는 기존 사용자의 프로필을 업데이트하는 메서드이며, 사용자 등록 플로우(OAuth로 최소 정보 생성 → 프로필 완성)의 후반부에 위치합니다. 메서드 의도를 더 명확하게 드러내기 위해updateUserProfile,completeUserRegistration또는saveUserProfile과 같이 메서드명을 변경하는 것이 코드 가독성을 향상시킬 수 있습니다.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (63)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostFilterController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostLikeController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/domain/repository/PostLikeRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/entity/PostImageEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/PostLikeRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/SpringDataPostLikeRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/auth/api/controller/AuthController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.javasrc/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/withdraw/GoogleWithdrawService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/auth/infra/persistence/entity/AppleRefreshTokenEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/PetRequestDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/UpdatePetRequestDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetProfileResponseDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetTraitCategoryListResponseDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetTraitCategoryResponseDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/SelectedOptionForPetTraitCategory.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/request/CreatePetCommand.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/request/UpdatePetCommand.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/response/PetTraitCategoryResult.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetQueryService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetTraitOptionRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetTraitSelectedRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/exception/PetErrorCode.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitCategoryEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitOptionEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitSelectedEntity.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetTraitOptionRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetTraitSelectedRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitCategoryRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitOptionRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitSelectedRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/region/api/controller/RegionController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/review/api/controller/ReviewController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/routes/api/controller/RouteController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/api/controller/UserController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/CreateUserRequestDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/UpdateUserInfoRequestDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/response/UserInfoResponseDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/response/UserRegisterResponseDto.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/dto/request/CreateUserCommand.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/dto/request/UpdateUserInfoCommand.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UpdateUserInfoFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserLoginFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserRegisterFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserWithdrawFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/command/UserPetCommandFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserQueryFacade.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/SocialAccountService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserPetQueryService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserQueryService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/domain/repository/SocialAccountRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/exception/UserErrorCode.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/SocialAccountRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/SpringDataSocialAccountRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/entity/UserEntity.java
💤 Files with no reviewable changes (20)
- src/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/SpringDataPostLikeRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetTraitCategoryListResponseDto.java
- src/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/PostLikeRepositoryImpl.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetTraitOptionRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/entity/PostImageEntity.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitOptionRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/Post/domain/repository/PostLikeRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitCategoryEntity.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitSelectedEntity.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/SelectedOptionForPetTraitCategory.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetTraitOptionRepositoryImpl.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitSelectedRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetTraitSelectedRepositoryImpl.java
- src/main/java/org/sopt/pawkey/backendapi/domain/auth/infra/persistence/entity/AppleRefreshTokenEntity.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetTraitCategoryResponseDto.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetTraitSelectedRepository.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetTraitOptionEntity.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetQueryService.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/response/PetTraitCategoryResult.java
- src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetTraitCategoryRepository.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-13T12:32:16.414Z
Learnt from: daeun-han
Repo: PAW-KEY/PAWKEY-Backend PR: 55
File: src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserLikedPostQueryFacade.java:26-71
Timestamp: 2025-07-13T12:32:16.414Z
Learning: PostEntity에서 postImageEntityList를 List에서 Set으로 변경한 것은 JPA/Hibernate의 MultipleBagFetchException을 피하기 위한 설계입니다. 여러 List 컬렉션을 동시에 fetch join할 수 없으므로 Set을 사용하거나 별도 쿼리로 분리해야 합니다.
Applied to files:
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java
📚 Learning: 2025-07-13T11:54:29.024Z
Learnt from: daeun-han
Repo: PAW-KEY/PAWKEY-Backend PR: 55
File: src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserLikedPostQueryFacade.java:55-55
Timestamp: 2025-07-13T11:54:29.024Z
Learning: 좋아요한 게시물 목록을 조회하는 API에서 isLiked 필드를 true로 하드코딩하는 것은 성능상 합리적입니다. PostLikeEntity 리스트가 이미 좋아요를 누른 게시물들만 포함하므로 별도 쿼리로 좋아요 상태를 확인하는 것은 중복이고 비효율적입니다.
Applied to files:
src/main/java/org/sopt/pawkey/backendapi/domain/user/api/controller/UserController.java
🧬 Code graph analysis (7)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UpdateUserInfoFacade.java (3)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserService.java (1)
Service(21-103)src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserQueryFacade.java (1)
Service(12-22)src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserQueryService.java (1)
Service(16-36)
src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.java (2)
src/main/java/org/sopt/pawkey/backendapi/domain/auth/exception/AuthBusinessException.java (1)
AuthBusinessException(6-12)src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleAuthKeyService.java (1)
Slf4j(39-196)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/command/UserPetCommandFacade.java (2)
src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.java (1)
Service(17-54)src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserPetQueryService.java (1)
Service(15-35)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserPetQueryService.java (1)
src/main/java/org/sopt/pawkey/backendapi/domain/pet/exception/PetBusinessException.java (1)
PetBusinessException(5-9)
src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.java (3)
src/main/java/org/sopt/pawkey/backendapi/domain/pet/exception/PetBusinessException.java (1)
PetBusinessException(5-9)src/main/java/org/sopt/pawkey/backendapi/domain/user/exception/UserBusinessException.java (1)
UserBusinessException(6-10)src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/command/UserPetCommandFacade.java (1)
Service(12-24)
src/main/java/org/sopt/pawkey/backendapi/domain/user/api/controller/UserController.java (2)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostController.java (1)
RestController(36-90)src/main/java/org/sopt/pawkey/backendapi/domain/routes/api/controller/RouteController.java (1)
RestController(33-97)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserQueryService.java (2)
src/main/java/org/sopt/pawkey/backendapi/domain/user/exception/UserBusinessException.java (1)
UserBusinessException(6-10)src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UpdateUserInfoFacade.java (1)
Service(12-24)
🔇 Additional comments (47)
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserWithdrawFacade.java (2)
24-39: 탈퇴 로직 구현 — 문제 없음
withdraw메서드의 로직은 적절하게 구현되었습니다:
- 토큰 조회 → 소셜 연동 해제 → 세션 revoke → 사용자 삭제 순서가 명확합니다
- 소셜 연동 해제 실패 시 예외 처리로 내부 탈퇴를 계속 진행하는 것이 올바릅니다
3-4: import 경로 변경 — 유효성 확인 완료
TokenService와SocialWithdrawServiceFactory의 import 경로가domain.auth패키지로 올바르게 변경되었습니다. 검증 결과, 클래스 정의 위치가 다음과 같이 import 경로와 일치합니다:
TokenService:src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/token/TokenService.javaSocialWithdrawServiceFactory:src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/withdraw/SocialWithdrawServiceFactory.java이 패키지 이동은 codebase 전체에서 일관성 있게 반영되었으며, 기존
domain.user경로의 import는 더 이상 사용되지 않습니다.src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/withdraw/GoogleWithdrawService.java (1)
5-5: LGTM! 중복 import 제거 완료.중복된 import 문을 제거하고 코드 정리를 수행한 변경사항입니다. 런타임 동작에 영향을 주지 않으며 코드 가독성을 개선합니다.
Also applies to: 13-13
src/main/java/org/sopt/pawkey/backendapi/domain/routes/api/controller/RouteController.java (1)
5-5: import 정리가 적절합니다.
UserIdimport를 상단으로 통합하고 중복을 제거하여 코드 일관성이 개선되었습니다.src/main/java/org/sopt/pawkey/backendapi/domain/region/api/controller/RegionController.java (1)
5-5: import 정리가 적절합니다.
UserIdimport 중복 제거 및 배치 통일로 코드 일관성이 향상되었습니다.src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostLikeController.java (1)
6-6: import 순서 정리가 적절합니다.import 순서를 조정하여 일관성을 확보했으며 동작에는 영향이 없습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/review/api/controller/ReviewController.java (1)
5-5: import 정리가 적절합니다.
UserIdimport를 단일 위치로 통합하여 중복을 제거했습니다.src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostController.java (1)
7-7: import 정리가 적절합니다.
UserIdimport를 상단으로 이동하고 중복을 제거하여 여러 컨트롤러 간 일관성이 확보되었습니다.src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostFilterController.java (1)
5-5: LGTM!
@UserId어노테이션 사용을 위한 import 추가가 적절합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserLoginFacade.java (1)
5-11: LGTM!Import 정리가 깔끔하게 되었으며, 추가된 모든 import가 클래스 내에서 실제로 사용되고 있습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/auth/api/controller/AuthController.java (1)
6-15: LGTM!Import 문 재정렬만 수행되었으며, 기존 기능에 영향이 없습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.java (1)
3-31: Import 정리 및 의존성 구성이 적절합니다.
AppleAuthKeyService를 통한 공개 키 조회와 예외 처리를 위한 import가 잘 구성되어 있습니다. 관련 코드 스니펫에서 확인되는AppleAuthKeyService.getPublicKey()메서드와의 연동이 올바르게 설정되어 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/exception/UserErrorCode.java (1)
14-15: 새로운 권한 오류 코드 추가 확인 완료UNAUTHORIZED_ACCESS 에러 코드가 적절하게 추가되었습니다. HTTP 403 상태와 명확한 메시지가 사용되었으며, 에러 코드 패턴도 일관성 있게 유지되고 있습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/SocialAccountService.java (1)
3-3: Import 정리 확인Import 구문이 적절하게 정리되었습니다. 기능적 변경 사항은 없습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/SpringDataPetRepository.java (1)
11-13: EntityGraph 단순화가 적절합니다.반려견 특성(trait) 관련 엔티티 제거에 맞춰
@EntityGraph의attributePaths를 "profileImage"만 포함하도록 올바르게 단순화했습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/dto/request/CreateUserCommand.java (1)
3-14: 나이 기반에서 생년월일 기반으로의 전환이 올바르게 구현되었습니다.
age필드를LocalDate birth로 변경하고 팩토리 메서드도 그에 맞춰 적절히 업데이트했습니다. PR의 목표와 일치하는 변경사항입니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/SocialAccountRepositoryImpl.java (1)
31-34: userId 기반 조회 메서드가 올바르게 구현되었습니다.
findByUser_UserId메서드가 표준 리포지토리 패턴에 따라 JPA 리포지토리에 적절히 위임하고 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/SpringDataSocialAccountRepository.java (1)
13-13: Spring Data JPA 쿼리 메서드가 올바르게 추가되었습니다.
findByUser_UserId메서드는 Spring Data JPA 네이밍 규칙을 따르며, 사용자 ID로 소셜 계정을 조회하는 기능을 적절히 제공합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/command/UserPetCommandFacade.java (1)
12-23: LGTM! Command-Query 분리 패턴이 잘 적용되었습니다.Facade가 수정(Command) 후 조회(Query)를 호출하여 최신 상태를 반환하는 설계가 적절합니다.
PetService.updatePetInfo에서 이미 소유권 검증을 수행하므로getPetProfile호출 시 별도 검증이 필요하지 않습니다.
@Transactional이 메서드 레벨에 적용되어 있고,PetService.updatePetInfo도@Transactional을 가지고 있지만 기본 전파 수준(REQUIRED)으로 동일 트랜잭션 내에서 실행되므로 문제없습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UpdateUserInfoFacade.java (1)
19-23: LGTM! 수정 후 조회 패턴이 올바르게 구현되었습니다.
userService.updateUserInfo호출 후userQueryService.getUserInfo를 통해 최신 정보를 반환하는 흐름이 적절합니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/exception/PetErrorCode.java (1)
6-8: LGTM! Pet trait 기능 제거에 따른 적절한 에러 코드 변경입니다.
CATEGORY_OPTION_NOT_FOUND가PET_NOT_FOUND로 변경되었으며, 코드베이스 전반에서 pet trait 관련 기능이 제거됨에 따라 적절한 수정입니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/domain/repository/PetRepository.java (1)
14-15: LGTM! Repository 인터페이스가 적절하게 확장되었습니다.
findById메서드가Optional<PetEntity>를 반환하도록 정의되어 있어 null-safe한 조회가 가능합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/UserRegisterFacade.java (1)
25-31: LGTM! 이미지 처리 로직 제거로 코드가 간결해졌습니다.
MultipartFile파라미터와 관련 이미지 처리 로직이 제거되어 Facade의 책임이 명확해졌습니다. 사용자 등록 흐름이 Region 조회 → User 저장 → Pet 저장 → 응답 반환으로 단순화되었습니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/repository/PetRepositoryImpl.java (1)
30-33: 새로운 findById 메서드가 올바르게 구현되었습니다.
Optional<PetEntity>를 반환하는findById메서드가 적절하게 추가되었으며, Spring Data JPA의 표준 패턴을 따르고 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/response/UserRegisterResponseDto.java (1)
6-16: 응답 DTO 단순화가 적절하게 구현되었습니다.응답 DTO가
userId와petId만 포함하도록 단순화되었으며, 팩토리 메서드도 올바르게 업데이트되었습니다. 이는 민감한 정보(loginId) 노출을 줄이고 응답 페이로드를 최소화하는 좋은 설계입니다.참고: 이 변경은 기존 API 소비자에게 영향을 미치는 breaking change이므로, API 버전 관리 및 문서화가 적절히 업데이트되었는지 확인하세요.
src/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/UpdateUserInfoRequestDto.java (1)
22-24: toCommand() 변환 메서드가 올바르게 구현되었습니다.Request DTO에서 Command로의 변환 로직이 명확하고 간결하게 구현되었습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserQueryService.java (2)
18-18: 클래스 레벨 @transactional 어노테이션이 적절합니다.Query 서비스에
@Transactional(readOnly = true)를 추가하여 읽기 전용 트랜잭션임을 명시했습니다. 이는 성능 최적화와 의도 명확화에 도움이 됩니다.
24-35: 이메일 조회 로직이 올바르게 통합되었습니다.
SocialAccountRepository를 통한 이메일 조회가 적절하게 구현되었으며, Optional 체이닝을 사용한 안전한 처리가 돋보입니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.java (1)
13-13: API 경로 변경은 breaking change입니다.RequestMapping이
/pets/traits에서/pets로 변경되었습니다. 이는 기존 API 소비자에게 영향을 미칠 수 있으므로, 다음을 확인하세요:
- API 문서(Swagger) 업데이트 완료
- 클라이언트 팀에 변경사항 전달
- API 버전 관리 전략 적용 여부
src/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/response/UserInfoResponseDto.java (2)
7-20: LGTM!
birth기반으로 변경된 구조가 적절합니다. 팩토리 메서드 패턴 사용도 깔끔합니다.
22-30: LGTM!
parseGender헬퍼 메서드가 null 처리와 대소문자 변환을 적절히 수행합니다.toUpperCase()사용으로 대소문자 혼용 입력에도 안전합니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/PetRequestDto.java (1)
13-24: LGTM!
age기반에서birth기반으로의 마이그레이션이 적절히 구현되었습니다.@JsonFormat과@NotNull조합으로 날짜 형식 검증이 잘 되어 있습니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetProfileResponseDto.java (1)
21-33: LGTM!
from(PetEntity)팩토리 메서드로 엔티티에서 DTO로의 변환이 깔끔하게 구현되었습니다.imageUrlnull 처리도 적절합니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/request/CreatePetCommand.java (1)
5-20: LGTM!
age기반에서birth기반으로의 전환이 깔끔하게 구현되었습니다. Command 객체로서 적절한 구조입니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.java (2)
37-53: LGTM!
@Transactional내에서 소유권 검증 후 업데이트하는 패턴이 적절합니다. dirty checking을 통해 자동으로 변경사항이 반영됩니다.
23-35:savePet메서드에@Transactional누락 확인 필요
savePet메서드에@Transactional어노테이션이 없습니다. 호출하는 상위 레이어(Facade 등)에서 트랜잭션이 관리되고 있는지 확인이 필요합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/CreateUserRequestDto.java (1)
15-34: LGTM!
birth기반 사용자 등록 DTO가 적절히 구현되었습니다.@Valid를 통한 중첩 객체 검증과@JsonFormat날짜 형식 지정이 올바릅니다.src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java (2)
42-44: LGTM!
@PastOrPresent검증 어노테이션으로 미래 날짜 입력을 방지합니다.nullable = false로 데이터 무결성도 보장됩니다.
63-64: LGTM!
dbti필드 추가가 적절합니다. nullable로 설정되어 DBTI 검사 미완료 상태를 허용합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserService.java (2)
28-32: 읽기 전용 트랜잭션 어노테이션 추가 승인조회 메서드에
@Transactional(readOnly = true)를 추가한 것은 적절합니다. 성능 최적화와 의도 명확화에 도움이 됩니다.
92-102: 새로운 updateUserInfo 메서드 구현 승인사용자 정보 업데이트를 위한 새로운 메서드가 적절하게 구현되었습니다. 트랜잭션 처리가 올바르게 적용되었고, 명확한 책임 분리가 이루어졌습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/entity/UserEntity.java (2)
41-41: @DynamicUpdate 어노테이션 추가 승인
@DynamicUpdate어노테이션을 추가한 것은 좋은 선택입니다. 이 어노테이션은 변경된 컬럼만 포함하는 UPDATE SQL을 생성하여, 부분 업데이트가 빈번한 사용자 프로필 엔티티에 적합합니다.
119-123: updateProfile 메서드 구현 승인프로필 업데이트 메서드가 명확하고 간결하게 구현되었습니다.
@DynamicUpdate와 함께 사용하여 효율적인 부분 업데이트가 가능합니다.src/main/java/org/sopt/pawkey/backendapi/domain/user/api/controller/UserController.java (4)
65-74: createUser 엔드포인트 업데이트 승인
@UserId어노테이션을 통한 인증된 사용자 ID 주입과@Parameter(hidden = true)를 통한 Swagger 문서 숨김 처리가 적절하게 구현되었습니다. 다른 컨트롤러(RouteController, PostController)와 일관된 패턴을 따릅니다.
76-88: 사용자 정보 조회 엔드포인트 구현 승인마이페이지를 위한 사용자 정보 조회 엔드포인트가 깔끔하게 구현되었습니다. RESTful 패턴을 잘 따르고 있으며, Swagger 문서화도 적절합니다.
90-103: 사용자 정보 수정 엔드포인트 구현 승인사용자 정보 수정 API가 적절하게 구현되었습니다. 입력 검증, Command 패턴 적용, 수정 후 최신 데이터 반환 등 모범 사례를 잘 따르고 있습니다.
164-178: 반려견 정보 수정 엔드포인트 구현 승인반려견 정보 수정 API가 잘 구현되었습니다.
참고: 이슈 #200에서 언급된 경로는
/petInfo/{petId}였으나, PR에서는/pets/{petId}를 사용하고 있습니다. 이는 GET/me/pets엔드포인트와의 일관성을 위한 의도적인 변경으로 보이며, 더 RESTful한 설계입니다.구현 장점:
@PathVariable을 통한 petId 추출@Valid를 통한 입력 검증- 권한 검증 (403 에러 응답 문서화)
- 수정 후 최신 데이터 반환으로 좋은 UX 제공
...wkey/backendapi/domain/auth/application/service/login/verifier/apple/AppleTokenVerifier.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/request/UpdatePetRequestDto.java
Outdated
Show resolved
Hide resolved
...ain/java/org/sopt/pawkey/backendapi/domain/pet/application/dto/request/UpdatePetCommand.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java
Show resolved
Hide resolved
...in/java/org/sopt/pawkey/backendapi/domain/user/api/dto/request/UpdateUserInfoRequestDto.java
Outdated
Show resolved
Hide resolved
...va/org/sopt/pawkey/backendapi/domain/user/application/dto/request/UpdateUserInfoCommand.java
Show resolved
Hide resolved
...n/java/org/sopt/pawkey/backendapi/domain/user/domain/repository/SocialAccountRepository.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/user/infra/persistence/entity/UserEntity.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java
Outdated
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetService.java
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java
Outdated
Show resolved
Hide resolved
src/main/java/org/sopt/pawkey/backendapi/domain/pet/infra/persistence/entity/PetEntity.java
Show resolved
Hide resolved
dltnals317
left a comment
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.
고생하셨습니다...! 👍🏻
|
현재 제안 주신 2가지 부분 적용하여 수정했습니다!
|
📌 PR 제목
[feat] 유저 및 반려견 정보 수정 API 구현
✨ 요약 설명
마이페이지에서 사용자의 프로필 정보와 반려견 정보를 수정할 수 있는 API를 구현했습니다. 특히, 설계 원칙에 따라 조회(Query)와 수정(Command)의 책임을 명확히 분리하여 Facade 계층을 구성했습니다.
🧾 변경 사항
📂 PR 타입
🧪 테스트
✅ 체크리스트
💬 리뷰어에게 전달할 말
수정 API 실행 후 별도의 조회 호출 없이도 최신 데이터를 확인할 수 있도록, Command 서비스 실행 후 Query 서비스를 호출하여 상세 정보를 반환하도록 설계했는데 이 방법이 적절했을지 알려주시면 감사하겠습니다!
또한, Facade 계층을 구성하면서 기존에 혼재되어 있던 Facade들의 네이밍을 통일하면 좋을 것 같아 의견드립니다.
🔗 관련 이슈
Summary by CodeRabbit
릴리스 노트
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.