Conversation
Walkthrough도구 플랜의 가격 필드를 월간/연간으로 분리하고(planPrice → priceMonthly, priceAnnual), 플랜 응답에 플랜 링크(planLink)를 추가하며 DTO, 엔티티, 서비스 계층의 매핑과 팩토리 시그니처를 일괄 업데이트합니다. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 분
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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 |
Test Results110 tests 110 ✅ 4s ⏱️ Results for commit 611b92e. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java(1 hunks)src/main/java/com/daruda/darudaserver/domain/admin/service/AdminService.java(1 hunks)src/main/java/com/daruda/darudaserver/domain/tool/dto/res/PlanListRes.java(1 hunks)src/main/java/com/daruda/darudaserver/domain/tool/dto/res/PlanRes.java(1 hunks)src/main/java/com/daruda/darudaserver/domain/tool/entity/Plan.java(2 hunks)src/main/java/com/daruda/darudaserver/domain/tool/service/ToolService.java(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: yechan-kim
Repo: Tool-daruda/35-APPJAM-SERVER-DARUDA PR: 340
File: src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java:55-87
Timestamp: 2025-11-27T08:53:05.793Z
Learning: In `src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java`, the `planType` field accepts Korean string values ("무료", "월간", "구매", "월간 & 연간") from the API request and internally converts them to enum values (FREE, MONTHLY, PURCHASE, MONTHLY_ANNUAL). The API documentation should show the Korean strings that clients need to send, not the internal enum names.
📚 Learning: 2025-11-27T08:53:05.793Z
Learnt from: yechan-kim
Repo: Tool-daruda/35-APPJAM-SERVER-DARUDA PR: 340
File: src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java:55-87
Timestamp: 2025-11-27T08:53:05.793Z
Learning: In `src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java`, the `planType` field accepts Korean string values ("무료", "월간", "구매", "월간 & 연간") from the API request and internally converts them to enum values (FREE, MONTHLY, PURCHASE, MONTHLY_ANNUAL). The API documentation should show the Korean strings that clients need to send, not the internal enum names.
Applied to files:
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java
🔇 Additional comments (6)
src/main/java/com/daruda/darudaserver/domain/admin/service/AdminService.java (1)
267-276:priceAnnual필터링 누락 가능성 검토
priceMonthly만null체크를 하고 있습니다.CreateToolPlanRequest에서priceAnnual에@NotNull이 적용되어 있다면 이 필터 조건은 충분합니다. 하지만priceAnnual이 선택 사항으로 변경될 경우, 필터 조건도 함께 업데이트해야 합니다.
CreateToolPlanRequest의 검증 어노테이션과 일관성을 확인해주세요.src/main/java/com/daruda/darudaserver/domain/tool/dto/res/PlanListRes.java (1)
8-17: LGTM!
planLink필드 추가 및 팩토리 메서드 업데이트가 깔끔하게 구현되었습니다.src/main/java/com/daruda/darudaserver/domain/tool/dto/res/PlanRes.java (1)
8-23: LGTM!단일 가격 필드를
priceAnnual과priceMonthly로 분리하는 변경이 일관성 있게 적용되었습니다.src/main/java/com/daruda/darudaserver/domain/tool/service/ToolService.java (1)
94-100: LGTM!변수명 변경(
plan→toolPlans)으로 가독성이 향상되었고,PlanListRes.of호출이 새로운 시그니처에 맞게 업데이트되었습니다.src/main/java/com/daruda/darudaserver/domain/tool/entity/Plan.java (2)
35-39: 월/연간 가격 컬럼 null 정책이 비즈니스 요구와 일치하는지 확인 필요
price_monthly는nullable = false,price_annual은 nullable 로 두셨는데, 지금 구조상 모든 플랜에 월간 가격이 반드시 있어야 하는 전제로 보입니다.
- Admin 쪽에서
priceMonthly를 필터 조건으로 사용하고 있다면(요약에 따르면p.priceMonthly() != null), "구매" 타입이나 향후 "연간 전용"과 같은 플랜이 생겼을 때 월간 가격을 어떻게 처리할지(0으로 둘지, 반드시 존재해야 할지) 명확히 해야 합니다.- 기존 데이터 마이그레이션 시에도
price_monthly가 NOT NULL 제약을 만족하는지 한번 더 체크해 두는 게 안전해 보입니다.요구사항 상 "월간 & 연간" 조합 타입까지 고려했을 때 이 설계가 의도와 정확히 맞는지 한 번만 더 검토 부탁드립니다.
Based on learnings.
48-55: CreateToolPlanRequest → Plan 매핑은 자연스럽지만 null 처리 의도 재확인 권장
Plan.create에서:.planName(toolPlanRequest.planName()) .priceMonthly(toolPlanRequest.priceMonthly()) .priceAnnual(toolPlanRequest.priceAnnual())로 매핑하신 부분은 직관적이고 DTO 변경사항과도 잘 맞습니다. 다만:
priceMonthly()가 null인 요청이 들어올 경우 JPA 레벨에서 NOT NULL 제약 위반이 날 수 있으므로,
- DTO에서
@NotNull+ 검증으로 막을지,- 아니면 여기서 기본값(예: 0L)을 강제할지 정책을 한 번만 더 명시해 두시는 게 좋습니다.
priceAnnual()은 null 허용이므로, "월간 전용" 플랜에 대해 실제로 null을 저장하는 것이 의도인지, 아니면 0 등의 기본값을 두고 싶은지 API 설계와 맞춰 주세요.현재 구현 자체는 문제 없어 보이며, 상위 계층 DTO/서비스의 검증과 일관성만 확인되면 그대로 가도 될 것 같습니다.
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java (2)
23-23: 검증 메시지 구체화 권장두 필드 모두 동일한 메시지 "플랜 가격은 0 이상이어야 합니다."를 사용하고 있습니다. 더 명확한 메시지로 개선할 수 있습니다:
- @PositiveOrZero(message = "플랜 가격은 0 이상이어야 합니다.") + @PositiveOrZero(message = "월간 플랜 가격은 0 이상이어야 합니다.") Long priceMonthly, @Schema( description = "연간 플랜 가격(원화)", example = "10000", requiredMode = Schema.RequiredMode.NOT_REQUIRED ) - @PositiveOrZero(message = "플랜 가격은 0 이상이어야 합니다.") + @PositiveOrZero(message = "연간 플랜 가격은 0 이상이어야 합니다.") Long priceAnnual,Also applies to: 30-30
19-19: 예시 값 차별화 권장월간 가격과 연간 가격 모두 "10000"을 예시로 사용하고 있습니다. 일반적으로 연간 플랜은 할인된 가격을 제공하므로, 예시 값을 다르게 설정하면 API 사용자에게 더 명확한 가이드를 제공할 수 있습니다.
@Schema( description = "월간 플랜 가격(원화)", example = "10000", requiredMode = Schema.RequiredMode.REQUIRED ) @NotNull(message = "월간 플랜 가격은 필수입니다.") @PositiveOrZero(message = "플랜 가격은 0 이상이어야 합니다.") Long priceMonthly, @Schema( description = "연간 플랜 가격(원화)", - example = "10000", + example = "100000", requiredMode = Schema.RequiredMode.NOT_REQUIRED )Also applies to: 27-27
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-27T08:53:05.793Z
Learnt from: yechan-kim
Repo: Tool-daruda/35-APPJAM-SERVER-DARUDA PR: 340
File: src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java:55-87
Timestamp: 2025-11-27T08:53:05.793Z
Learning: In `src/main/java/com/daruda/darudaserver/domain/admin/controller/AdminController.java`, the `planType` field accepts Korean string values ("무료", "월간", "구매", "월간 & 연간") from the API request and internally converts them to enum values (FREE, MONTHLY, PURCHASE, MONTHLY_ANNUAL). The API documentation should show the Korean strings that clients need to send, not the internal enum names.
Applied to files:
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java
🔇 Additional comments (2)
src/main/java/com/daruda/darudaserver/domain/admin/dto/request/CreateToolPlanRequest.java (2)
18-31: 검증 어노테이션 일관성 수정 확인이전 리뷰에서 지적된 검증 어노테이션 불일치 문제가 수정되었습니다:
priceMonthly:@NotNull추가 및REQUIRED스키마와 일치 ✓priceAnnual:@NotNull제거 및NOT_REQUIRED스키마와 일치 ✓API 문서와 실제 검증 동작이 일관되게 정렬되었습니다.
25-31: No issue found - priceAnnual null handling is correctThe
priceAnnualfield is properly designed as optional and handles null values correctly throughout the codebase:
- The DTO field has no
@NotNullconstraint and is markedNOT_REQUIRED, allowing null values- The
@PositiveOrZerovalidation only applies when the value is present (not null)- The Plan entity correctly defines
priceAnnualas nullable in the database schema- Both
Plan.create()andAdminService.updateTool()properly pass null values without issuesNo null handling verification or changes are needed.
Likely an incorrect or invalid review comment.
📣 Related Issue
📝 Summary
🙏 Question & PR point
📬 Postman
툴 생성 시
플랜 조회 시
Summary by CodeRabbit
릴리스 노트
새로운 기능
변경사항
✏️ Tip: You can customize this high-level summary in your review settings.