Skip to content

Conversation

@daeun-han
Copy link
Member

@daeun-han daeun-han commented Feb 1, 2026

📌 PR 제목

[feat] 반려견 DBTI 상세 분석 구현 및 프로필 조회 API 수정


✨ 요약 설명

반려견의 DBTI 검사 결과를 상세하게 분석하여 제공하는 기능을 구현하고, 기획 변경 사항에 맞춰 반려견 프로필 조회 API의 응답 명세와 엔드포인트를 수정했습니다.


🧾 변경 사항

  • DBTI 상세 분석: 성향 축별(EI, PS, RT) 점수와 강점 방향(dominantSide)을 포함한 상세 분석 로직 구현
  • 나이 포맷팅 적용: 반려견 생년월일을 기반으로 0~23개월은 '개월', 24개월 이상은 '살'로 변환하여 응답하도록 수정
  • 프로필 응답 확장: PetProfileResponseDto에 dbtiType과 dbtiName 필드를 추가하여 UI 대응력 강화
  • 엔드포인트 수정: 반려견 프로필 조회 API를 /me/pets에서 /{petId}로 변경하고 유저 소유권 검증 로직 추가
  • DB 스키마 변경: dbti_type 테이블에 시각화 라벨링을 위한 left_label, right_label 컬럼 추가

📂 PR 타입

  • 기능 추가
  • 버그 수정
  • 리팩토링
  • 문서 수정
  • 기타 (DB 스키마 변경)

🧪 테스트

  • Postman으로 API 호출 확인
  • 로컬 실행 결과 화면 캡처 포함

✅ 체크리스트

  • 깃 & 코드 컨벤션을 지켰는가?
  • Swagger/문서화는 최신 상태인가?
  • 기능 변경 시 영향 받는 모듈을 확인했는가?

💬 리뷰어에게 전달할 말

  • 기존 integer 값으로 제공하던 나이 필드를 '24개월을 기준으로 분기 처리'해야하는 요구사항에 따라 백엔드에서 직접 개월 수와 나이를 판별하여 "6개월", "3살" 형태의 문자열로 내려주도록 구현했으니 확인해 주시고 피드백 부탁드립니다!
  • DBTI 상세 분석 데이터 DbtiResultResponseDto 내부에서 각 성향 축의 점수에 따라 left/right를 결정하는 로직을 추가했습니다. DbtiResultEntity에 추가된 getAnalysisOf 메서드를 통해 데이터를 매핑합니다.
  • 엔티티 간 데이터 조합 PetQueryService에서 PetEntity와 DbtiEntity를 조합하여 상세한 DBTI 명칭(예: "온순한 방구석멍")을 가져오도록 처리했습니다. DbtiEntity 임포트 및 Optional 처리 부분을 중점적으로 봐주시면 감사하겠습니다.
  • DB 스키마 업데이트 dbti_type 테이블에 라벨 컬럼이 추가되었습니다. 로컬 DB에서 테스트하실 때 기존 데이터를 삭제 후 최신 INSERT 쿼리를 실행해야 정상 작동합니다.

🔗 관련 이슈

아래 이슈번호 에 번호를 적으면 풀리퀘스트 머지 완료 시 자동으로 해당 이슈가 닫힙니다.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • DBTI 성격 유형 분석 결과에 축(EI/PS/RT), 좌우 라벨, 우세성 정보 추가
  • 개선 사항

    • 반려견 나이 표시 형식 개선 (개월/살 단위로 더 명확하게 표시)
    • 반려견 프로필에 DBTI 성격 정보 및 설명 추가 표시

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Feb 1, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

이 PR은 반려견 DBTI 결과의 상세 분석 기능을 구현하기 위해 데이터 구조를 재구성합니다. DBTI 결과를 축별 분석(분석값, 라벨, 우세 방향) 리스트로 반환하도록 변경하고, 반려견 프로필 조회 API를 사용자 기반에서 펫 ID 기반으로 전환하며, 관련 서비스/파사드/저장소 레이어를 업데이트합니다.

Changes

Cohort / File(s) Summary
DBTI 응답 DTO 및 엔티티
src/main/java/org/sopt/pawkey/backendapi/domain/dbti/api/dto/response/DbtiResultResponseDto.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/entity/DbtiResultEntity.java
DbtiResultResponseDto에 분석 리스트(DbtiResultInfo 내부 레코드) 추가, DbtiResultEntity에 getAnalysisOf 메서드 및 DbtiAnalysisResult 레코드 추가로 축별 점수와 우세 방향 계산 로직 구현
DBTI 타입 엔티티 및 저장소
src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/entity/DbtiTypeEntity.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/domain/repository/DbtiRepository.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/repository/DbtiRepositoryImpl.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/repository/SpringDataDbtiTypeRepository.java
DbtiTypeEntity에 leftLabel, rightLabel 필드 추가, 모든 DBTI 타입 조회 메서드(findAllTypes) 추가, SpringDataDbtiTypeRepository 신규 생성
DBTI 응용 계층 DTO 및 서비스
src/main/java/org/sopt/pawkey/backendapi/domain/dbti/application/dto/DbtiResultInfo.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/application/service/DbtiCommandService.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/application/service/DbtiQueryService.java
DbtiResultInfo 레코드 신규 도입하여 엔티티, DbtiInfo, 타입 리스트 래핑, DbtiCommandService와 DbtiQueryService의 반환 타입을 DbtiResultInfo로 변경, 검증 로직 추가
DBTI 파사드
src/main/java/org/sopt/pawkey/backendapi/domain/dbti/application/facade/DbtiCommandFacade.java, src/main/java/org/sopt/pawkey/backendapi/domain/dbti/application/facade/query/DbtiQueryFacade.java
DbtiResultInfo를 통해 파사드 제어 흐름 단순화, DbtiQueryService 호출 제거, 세 개 인자 팩토리 메서드로 응답 생성
반려견 프로필 API 및 응답 DTO
src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.java, src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetProfileResponseDto.java
PetController.getMyPet 엔드포인트 경로를 "/me/pets"에서 "/{petId}"로 변경, 팩토리 메서드 및 age 필드 타입 변경(long → String), dbtiDescription 필드 추가
반려견 조회 파사드 및 서비스
src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/facade/PetQueryFacade.java, src/main/java/org/sopt/pawkey/backendapi/domain/pet/application/service/PetQueryService.java
PetQueryFacade의 getUserPet을 getPetProfile로 리네임 및 petId 파라미터 추가, PetQueryService에서 getPetProfileDetail 메서드 신규 추가로 DBTI 설명 및 나이 포맷팅 처리
사용자 반려견 조회 서비스 제거
src/main/java/org/sopt/pawkey/backendapi/domain/user/application/service/UserPetQueryService.java
UserPetQueryService 클래스 전체 삭제로 중복된 반려견 프로필 조회 로직 제거

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • bingle625
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 주요 변경사항인 DBTI 상세 분석 구현과 프로필 조회 API 수정을 명확히 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿 구조를 따르며 요약, 변경사항, PR 타입, 테스트, 체크리스트, 리뷰어 전달말, 관련 이슈를 포함하고 있습니다.
Linked Issues check ✅ Passed 코드 변경이 #222의 모든 주요 목표를 충족합니다: DbtiTypeEntity 라벨 필드 추가, DbtiResultResponseDto 분석 구조 구현, dominantSide/score 계산 로직 추가.
Out of Scope Changes check ✅ Passed 모든 변경사항이 DBTI 상세 분석 및 프로필 조회 API와 직접 관련되어 있으며 #222 범위 내에 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#222

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@daeun-han
Copy link
Member Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Feb 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/dto/response/PetProfileResponseDto.java`:
- Around line 36-45: formatAge currently uses ChronoUnit.MONTHS.between(birth,
LocalDate.now()) which can be negative for future birth dates; update formatAge
to detect months < 0 and handle it (e.g., return "정보 없음" or normalize to "0개월")
before the existing month/years logic so that negative values never produce
strings like "-1개월"; ensure you reference the formatAge method and the
ChronoUnit.MONTHS.between(birth, LocalDate.now()) result when adding the guard.
🧹 Nitpick comments (4)
src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/entity/DbtiResultEntity.java (1)

69-75: 축 코드에 상수 사용을 고려해 주세요.

"EI", "PS", "RT" 문자열 리터럴이 하드코딩되어 있습니다. 타입 안전성과 유지보수성을 위해 상수나 enum을 사용하는 것이 좋습니다. 또한 "RT" 코드가 rfScore 필드에 매핑되는데, 명명 불일치가 혼란을 줄 수 있습니다.

추가로, DBTI_NOT_FOUND 에러 코드가 "유효하지 않은 축 코드" 상황에 의미상 정확하지 않을 수 있습니다. INVALID_AXIS_CODE와 같은 전용 에러 코드 추가를 검토해 주세요.

♻️ 상수 추출 제안
+	private static final String AXIS_EI = "EI";
+	private static final String AXIS_PS = "PS";
+	private static final String AXIS_RT = "RT";
+
 	public DbtiAnalysisResult getAnalysisOf(String axisCode) {
 		int rawScore = switch (axisCode) {
-			case "EI" -> this.eiScore;
-			case "PS" -> this.psScore;
-			case "RT" -> this.rfScore;
+			case AXIS_EI -> this.eiScore;
+			case AXIS_PS -> this.psScore;
+			case AXIS_RT -> this.rfScore;
 			default -> throw new DbtiBusinessException(DbtiErrorCode.DBTI_NOT_FOUND);
 		};
src/main/java/org/sopt/pawkey/backendapi/domain/pet/api/controller/PetController.java (1)

36-49: 메서드 명칭을 새 엔드포인트 의미에 맞게 정리하면 더 명확합니다.

getMyPet/me/pets 시절 네이밍이라, /{petId}로 변경된 만큼 getPetProfile 같은 명칭이 혼동을 줄일 수 있습니다.

src/main/java/org/sopt/pawkey/backendapi/domain/dbti/infra/persistence/repository/DbtiRepositoryImpl.java (1)

41-44: 타입 목록의 반환 순서가 의미가 있다면 정렬을 명시해 주세요.

findAllTypes()가 기본 순서를 그대로 반환하므로, 응답 순서가 UI/분석 축 매핑에 영향을 준다면 ORDER BY 또는 후처리 정렬을 추가하는 편이 안전합니다.

src/main/java/org/sopt/pawkey/backendapi/domain/dbti/api/dto/response/DbtiResultResponseDto.java (1)

28-51: analysis 리스트 순서를 명시적으로 고정하는 방어 로직을 권장합니다.

types 입력 순서(=DB 조회 순서)에 의존하면 응답 순서가 환경/쿼리 변경에 따라 흔들릴 수 있습니다. 클라이언트가 순서에 의존한다면 이슈가 될 수 있어 정렬을 보장하는 편이 안전합니다.

♻️ 정렬 추가 예시
 			types.stream()
+				.sorted(Comparator.comparing(DbtiTypeEntity::getCode))
 				.map(type -> {
 					var analysisResult = result.getAnalysisOf(type.getCode());

(참고: Comparator import가 필요합니다.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 반려견 DBTI 결과 상세 분석 기능 구현

2 participants