Skip to content

Feat/api schema#19

Open
sj0724 wants to merge 5 commits into
mainfrom
feat/apiSchema
Open

Feat/api schema#19
sj0724 wants to merge 5 commits into
mainfrom
feat/apiSchema

Conversation

@sj0724
Copy link
Copy Markdown
Collaborator

@sj0724 sj0724 commented Jun 2, 2026

  • 백엔드에서 전달받은 명세서 기준으로 전체 데이터 타입이랑 api 생성했습니다.
  • 리액트 쿼리 설정해뒀습니다.

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 블로그 분석 및 추천 기능 추가
    • 캠페인 상호작용 강화 (좋아요, 상세 조회, 분석)
    • AI 기반 맞춤형 피드 및 추천 공고 제공
    • 사용자 프로필 및 블로그 연동 관리
    • 구독 상태 조회 및 업그레이드 기능
    • 포인트 및 출금 관리 시스템
    • 사용자 온보딩 플로우
  • Chores

    • React Query 설정 및 개발자 도구 통합

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

Warning

Review limit reached

@sj0724, we couldn't start this review because you've reached your PR review rate limit.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84babf8b-5efa-418a-8af0-221955756be0

📥 Commits

Reviewing files that changed from the base of the PR and between 087709d and 19fa158.

📒 Files selected for processing (2)
  • src/app/_components/Providers.tsx
  • src/entities/campaign/index.ts

Walkthrough

이 PR은 앱 전체의 도메인 모델 및 API 계층을 정의합니다. React Query를 초기화한 후 8개 도메인(인증, 사용자, 구독, 캠페인, 피드, 분석, 마이페이지, 온보딩)의 Zod 스키마와 런타임 타입을 추가하고, 각 도메인별 REST API 서비스 객체를 구현합니다.

Changes

엔티티 스키마 및 API 서비스 통합

Layer / File(s) Summary
React Query 및 레이아웃 초기화
src/app/_components/Providers.tsx, src/app/layout.tsx
Providers 컴포넌트에서 QueryClient의 기본 query 옵션(staleTime: 60s, retry: 1)과 ReactQueryDevtools(기본 닫힘)를 설정하고, RootLayout에서 Header, children, Footer를 감싸는 컨텍스트로 추가합니다.
사용자 인증 및 구독 엔티티 스키마
src/entities/auth/*, src/entities/subscription/*, src/entities/user/*
로그인 요청(code, redirectUri) 및 토큰 응답 스키마를 정의하고, 구독 상태/업그레이드/취소 스키마를 추가합니다. 사용자 프로필(userProfileSchema), 프로필 업데이트(updateUserProfileSchema), 블로그 링크 요청(blogLinkSchema) 스키마를 정의하며, 사용자 관련 열거형(Provider, UserGrade, SubscriptionType, InterestCategory, UserChannel)을 확장합니다. 구독 열거형(PlanType, SubscriptionStatus)과 사용자 블로그 스키마(userId 선택화, lastCrawledAt/updatedAt 필드 추가)도 함께 업데이트됩니다.
캠페인 및 피드 도메인 스키마
src/entities/campaign/*, src/entities/feed/*
캠페인 목록/상세/쿼리 파라미터/뷰어/좋아요 분석/좋아요 응답 스키마 및 페이지네이션 제너릭(paginatedSchema)을 정의하고, 캠페인 열거형(CampaignCategory, CampaignType, CampaignChannel, CampaignStatus, CampaignSort, CampaignPlatform)을 추가합니다. 피드의 히어로(feedHeroSchema), 섹션(feedSectionSchema), 바디(feedBodySchema), AI 추천(aiRecommendedCampaignSchema), 블로거 스토리(bloggerStorySchema) 스키마와 대응 타입(FeedHero, FeedSection, FeedBody 등)을 정의합니다.
분석, 마이페이지, 온보딩 엔티티 스키마
src/entities/blog-analysis/*, src/entities/my/*, src/entities/onboarding/*
블로그 분석 요청/202 응답/결과/이력/추천/채팅 스키마 및 분석 상태/이유 유형 열거형을 추가합니다. 마이페이지의 내 캠페인/상세, 포인트 거래/응답, 출금 요청/응답 스키마 및 캠페인 상태/거래 유형/출금 상태 열거형을 정의합니다. 온보딩 응답 요청/결과/추천 스키마를 추가합니다.
도메인별 API 서비스 구현
src/service/index.ts
authService, userService, subscriptionService, campaignService, feedService, myService, onboardingService, blogAnalysisService 8개 서비스 객체를 정의하고, 각각 http 클라이언트를 사용해 로그인/로그아웃, 사용자 정보 조회/수정/블로그 연동, 구독 조회/업그레이드/해지, 공고 목록/상세/뷰어/검색/좋아요, 피드 조회, 내 체험단/포인트/출금, 온보딩 응답/추천, 블로그 분석 요청/결과/이력/추천 엔드포인트를 래핑하며 res.data를 반환합니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 스키마의 우아한 춤이 시작되고,
타입 안전의 문이 활짝 열려,
서비스는 API와 손을 맞잡고,
React Query는 상태를 지키며,
앱의 기초가 견고해진다네! 🎉

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목 'Feat/api schema'는 전체 API 스키마 및 데이터 타입 생성, React Query 설정 추가라는 주요 변경 사항을 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/apiSchema

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.

Copy link
Copy Markdown

@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: 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.tsloginRequestSchema.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

PlanTypeuser 도메인의 SubscriptionType과 값이 완전히 중복됩니다.

PlanType(['FREE', 'BASIC', 'PRO'])은 src/entities/user/model/user.enums.tsSubscriptionType과 멤버가 동일합니다. 동일 개념을 두 곳에서 별도로 정의하면 한쪽에 값이 추가/변경될 때 동기화가 누락되어 런타임 검증이 어긋날 수 있습니다. 단일 출처로 통합하는 것을 권장합니다(둘 중 하나를 정본으로 두고 재-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()) 적용 권장

blogLinkSchemaPOST /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 타입 활용 및 페이지네이션 타입 공통화 (권장)

getCampaignsstatus?: 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

📥 Commits

Reviewing files that changed from the base of the PR and between b4410bd and 087709d.

📒 Files selected for processing (26)
  • .husky/pre-commit
  • src/app/_components/Providers.tsx
  • src/app/layout.tsx
  • src/entities/auth/index.ts
  • src/entities/auth/model/auth.schema.ts
  • src/entities/blog-analysis/index.ts
  • src/entities/blog-analysis/model/blog-analysis.enums.ts
  • src/entities/blog-analysis/model/blog-analysis.schema.ts
  • src/entities/campaign/index.ts
  • src/entities/campaign/model/campaign.enums.ts
  • src/entities/campaign/model/campaign.schema.ts
  • src/entities/feed/index.ts
  • src/entities/feed/model/feed.schema.ts
  • src/entities/my/index.ts
  • src/entities/my/model/my.enums.ts
  • src/entities/my/model/my.schema.ts
  • src/entities/onboarding/index.ts
  • src/entities/onboarding/model/onboarding.schema.ts
  • src/entities/subscription/index.ts
  • src/entities/subscription/model/subscription.enums.ts
  • src/entities/subscription/model/subscription.schema.ts
  • src/entities/user/index.ts
  • src/entities/user/model/blog.schema.ts
  • src/entities/user/model/user.enums.ts
  • src/entities/user/model/user.schema.ts
  • src/service/index.ts

Comment thread src/app/_components/Providers.tsx Outdated
Comment thread src/entities/campaign/index.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant