Feat/api schema#19
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 34 minutes and 55 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
Walkthrough이 PR은 앱 전체의 도메인 모델 및 API 계층을 정의합니다. React Query를 초기화한 후 8개 도메인(인증, 사용자, 구독, 캠페인, 피드, 분석, 마이페이지, 온보딩)의 Zod 스키마와 런타임 타입을 추가하고, 각 도메인별 REST API 서비스 객체를 구현합니다. Changes엔티티 스키마 및 API 서비스 통합
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
src/entities/auth/model/auth.schema.ts (2)
13-20: 💤 Low value
subscriptionType명명 일관성 확인 필요.여기서는 user 도메인의
SubscriptionType(FREE/BASIC/PRO)을subscriptionType필드로 사용하지만, subscription 도메인은 동일 값 집합을PlanType/planType으로 정의합니다. 같은 개념이 도메인마다 다른 이름과 별도 enum으로 표현되어 향후 값이 어긋날(drift) 위험이 있습니다. 열거형 통합 관련 의견은subscription.enums.ts에 남겼습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/auth/model/auth.schema.ts` around lines 13 - 20, tokenUserSchema currently uses the locally named SubscriptionType and field subscriptionType which diverges from the subscription domain's PlanType/planType and risks enum drift; import and use the single canonical enum defined in subscription.enums.ts (PlanType) and rename the schema field to planType (and update any consumers/tests) so tokenUserSchema uses PlanType for its type and a consistent planType property across domains.
6-9: 💤 Low value
redirectUri에 URL 형식 검증(z.url()) 적용 고려
src/entities/auth/model/auth.schema.ts의loginRequestSchema.redirectUri가 OAuth 콜백 URL이라면,z.string()대신z.url()로 검증해 잘못된 입력을 조기에 차단할 수 있습니다. 이 저장소는zod가^4.3.6이라z.url사용이 가능합니다.♻️ 제안 변경
export const loginRequestSchema = z.object({ code: z.string(), - redirectUri: z.string(), + redirectUri: z.url(), })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/auth/model/auth.schema.ts` around lines 6 - 9, Update the loginRequestSchema so redirectUri is validated as a URL: replace the z.string() validator for redirectUri with z.url() in the loginRequestSchema declaration (symbol: loginRequestSchema, property: redirectUri) to ensure OAuth callback URLs are properly validated by zod v4.src/entities/subscription/model/subscription.enums.ts (1)
3-4: ⚡ Quick win
PlanType이user도메인의SubscriptionType과 값이 완전히 중복됩니다.
PlanType(['FREE', 'BASIC', 'PRO'])은src/entities/user/model/user.enums.ts의SubscriptionType과 멤버가 동일합니다. 동일 개념을 두 곳에서 별도로 정의하면 한쪽에 값이 추가/변경될 때 동기화가 누락되어 런타임 검증이 어긋날 수 있습니다. 단일 출처로 통합하는 것을 권장합니다(둘 중 하나를 정본으로 두고 재-export하거나, 공유 enum으로 추출).♻️ 통합 예시 (SubscriptionType을 정본으로 재사용)
-import { z } from 'zod' +import { z } from 'zod' +import { SubscriptionType } from '`@/entities/user`' -export const PlanType = z.enum(['FREE', 'BASIC', 'PRO']) -export type PlanType = z.infer<typeof PlanType> +export const PlanType = SubscriptionType +export type PlanType = z.infer<typeof PlanType>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/subscription/model/subscription.enums.ts` around lines 3 - 4, The file defines a duplicate enum PlanType that fully overlaps with the user-domain SubscriptionType; remove the local PlanType and instead import and re-export the canonical SubscriptionType (and its inferred TypeScript type) so there is a single source of truth. Specifically, delete the z.enum declaration named PlanType, add an import of SubscriptionType from the user model, export const PlanType = SubscriptionType (or export SubscriptionType directly) and set export type PlanType = z.infer<typeof SubscriptionType> (or re-export the SubscriptionType type) and update any consumers to use the unified SubscriptionType/PlanType export.src/entities/user/model/user.schema.ts (1)
56-59: ⚡ Quick win
blogUrl입력값에 URL 형식 검증(z.url()) 적용 권장
blogLinkSchema는POST /users/me/blog요청 바디이고blogUrl은 사용자 입력 URL이므로, 단순z.string()대신z.url()로 WHATWG 호환 URL 형식을 검증하면 잘못된 값이 서버로 전달되는 것을 사전에 막을 수 있습니다.♻️ 제안 변경
export const blogLinkSchema = z.object({ - blogUrl: z.string(), + blogUrl: z.url(), platform: BlogPlatform, })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/user/model/user.schema.ts` around lines 56 - 59, The blogLinkSchema currently uses blogUrl: z.string(); change this to blogUrl: z.url() so the POST /users/me/blog request body validates WHATWG-compatible URLs; update the blogLinkSchema definition (and any tests or consumers of blogLinkSchema if they rely on plain strings) to use z.url() while keeping platform: BlogPlatform unchanged.src/service/index.ts (1)
178-201: ⚡ Quick win
status파라미터에UserCampaignStatus타입 활용 및 페이지네이션 타입 공통화 (권장)
getCampaigns의status?: string은 이미 정의된UserCampaignStatus열거형의 타입 안전성을 잃습니다. 또한{ page?: number; size?: number }형태가 여러 메서드에 중복됩니다. 공통 타입으로 추출하고status를 enum 타입으로 좁히는 것을 권장합니다.♻️ 제안 변경
+import type { UserCampaignStatus } from '`@/entities/my`' + +type PageParams = { page?: number; size?: number } + export const myService = { /** GET /my/campaigns — 내 체험단 목록 */ - getCampaigns: (params?: { status?: string; page?: number; size?: number }) => + getCampaigns: (params?: PageParams & { status?: UserCampaignStatus }) => http.get<Paginated<MyCampaign>>('/my/campaigns', { params }).then(res => res.data),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/service/index.ts` around lines 178 - 201, The getCampaigns signature uses a plain string for status and duplicates pagination shapes across methods; change getCampaigns to use status?: UserCampaignStatus and extract a shared PaginationParams type (e.g., type PaginationParams = { page?: number; size?: number }) then use that type for getCampaigns, getPoints and getLikes (update signatures for myService.getCampaigns, myService.getPoints, myService.getLikes) and ensure you import or reference the existing UserCampaignStatus and keep Paginated/response generics unchanged so type compatibility is preserved.src/entities/blog-analysis/model/blog-analysis.schema.ts (1)
39-39: 💤 Low value날짜/URL 필드에 Zod v4 포맷 검증 추가(선택)
src/entities/blog-analysis/model/blog-analysis.schema.ts(라인 39의analyzedAt: z.string().nullable()및 라인 48의 URL 필드)은 현재z.string()만이라 ISO datetime/URL 형식 검증이 없습니다. Zod v4에서는 standalone 포맷 API로z.iso.datetime()/z.url()을 제공하므로(예:z.iso.datetime().nullable(),z.url().nullable()), 응답 파싱 단계에서 형식 오류를 더 빨리 잡을 수 있습니다. 백엔드 응답이 완전히 확정적이면 현행 유지도 무방합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/entities/blog-analysis/model/blog-analysis.schema.ts` at line 39, The schema currently uses generic z.string() for the analyzedAt field and the URL field; update those to use Zod v4 format validators so parsing fails fast: replace the analyzedAt definition (symbol: analyzedAt in blog-analysis.schema) with z.iso.datetime().nullable() and replace the URL field (the URL property in the same schema) with z.url().nullable(); ensure imports/types remain compatible with Zod v4 format API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/_components/Providers.tsx`:
- Line 24: Wrap the unconditional ReactQueryDevtools render in Providers.tsx
with a development-only guard or lazy-load it so it only appears in dev builds;
specifically, conditionally render ReactQueryDevtools (reference:
ReactQueryDevtools) only when process.env.NODE_ENV === 'development' or import
it dynamically for dev only, ensuring the devtools are not included in
production bundles.
In `@src/entities/campaign/index.ts`:
- Around line 1-15: The barrel is exporting the type Paginated but not the
runtime paginatedSchema, causing consumers to deep-import the schema; update the
exports in this module to also re-export the runtime symbol paginatedSchema
alongside type Paginated (i.e., add paginatedSchema to the existing export list
that currently includes campaignSchema, campaignDetailSchema, ... and type
Paginated) so callers can import the runtime validator without reaching into the
model file.
---
Nitpick comments:
In `@src/entities/auth/model/auth.schema.ts`:
- Around line 13-20: tokenUserSchema currently uses the locally named
SubscriptionType and field subscriptionType which diverges from the subscription
domain's PlanType/planType and risks enum drift; import and use the single
canonical enum defined in subscription.enums.ts (PlanType) and rename the schema
field to planType (and update any consumers/tests) so tokenUserSchema uses
PlanType for its type and a consistent planType property across domains.
- Around line 6-9: Update the loginRequestSchema so redirectUri is validated as
a URL: replace the z.string() validator for redirectUri with z.url() in the
loginRequestSchema declaration (symbol: loginRequestSchema, property:
redirectUri) to ensure OAuth callback URLs are properly validated by zod v4.
In `@src/entities/blog-analysis/model/blog-analysis.schema.ts`:
- Line 39: The schema currently uses generic z.string() for the analyzedAt field
and the URL field; update those to use Zod v4 format validators so parsing fails
fast: replace the analyzedAt definition (symbol: analyzedAt in
blog-analysis.schema) with z.iso.datetime().nullable() and replace the URL field
(the URL property in the same schema) with z.url().nullable(); ensure
imports/types remain compatible with Zod v4 format API.
In `@src/entities/subscription/model/subscription.enums.ts`:
- Around line 3-4: The file defines a duplicate enum PlanType that fully
overlaps with the user-domain SubscriptionType; remove the local PlanType and
instead import and re-export the canonical SubscriptionType (and its inferred
TypeScript type) so there is a single source of truth. Specifically, delete the
z.enum declaration named PlanType, add an import of SubscriptionType from the
user model, export const PlanType = SubscriptionType (or export SubscriptionType
directly) and set export type PlanType = z.infer<typeof SubscriptionType> (or
re-export the SubscriptionType type) and update any consumers to use the unified
SubscriptionType/PlanType export.
In `@src/entities/user/model/user.schema.ts`:
- Around line 56-59: The blogLinkSchema currently uses blogUrl: z.string();
change this to blogUrl: z.url() so the POST /users/me/blog request body
validates WHATWG-compatible URLs; update the blogLinkSchema definition (and any
tests or consumers of blogLinkSchema if they rely on plain strings) to use
z.url() while keeping platform: BlogPlatform unchanged.
In `@src/service/index.ts`:
- Around line 178-201: The getCampaigns signature uses a plain string for status
and duplicates pagination shapes across methods; change getCampaigns to use
status?: UserCampaignStatus and extract a shared PaginationParams type (e.g.,
type PaginationParams = { page?: number; size?: number }) then use that type for
getCampaigns, getPoints and getLikes (update signatures for
myService.getCampaigns, myService.getPoints, myService.getLikes) and ensure you
import or reference the existing UserCampaignStatus and keep Paginated/response
generics unchanged so type compatibility is preserved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0965eef5-adbc-4509-97f6-1159c4bc7ac0
📒 Files selected for processing (26)
.husky/pre-commitsrc/app/_components/Providers.tsxsrc/app/layout.tsxsrc/entities/auth/index.tssrc/entities/auth/model/auth.schema.tssrc/entities/blog-analysis/index.tssrc/entities/blog-analysis/model/blog-analysis.enums.tssrc/entities/blog-analysis/model/blog-analysis.schema.tssrc/entities/campaign/index.tssrc/entities/campaign/model/campaign.enums.tssrc/entities/campaign/model/campaign.schema.tssrc/entities/feed/index.tssrc/entities/feed/model/feed.schema.tssrc/entities/my/index.tssrc/entities/my/model/my.enums.tssrc/entities/my/model/my.schema.tssrc/entities/onboarding/index.tssrc/entities/onboarding/model/onboarding.schema.tssrc/entities/subscription/index.tssrc/entities/subscription/model/subscription.enums.tssrc/entities/subscription/model/subscription.schema.tssrc/entities/user/index.tssrc/entities/user/model/blog.schema.tssrc/entities/user/model/user.enums.tssrc/entities/user/model/user.schema.tssrc/service/index.ts
Summary by CodeRabbit
릴리스 노트
New Features
Chores