Skip to content

Conversation

@sgoldenbird
Copy link
Contributor

@sgoldenbird sgoldenbird commented Aug 6, 2025

👻 관련 이슈 번호

  • none

👻 요약

  • 카카오 로그인 과정에서 회원가입이 필요한 사용자를 위한 전환 페이지를 만들고, 이 페이지에서 닉네임을 입력받아 회원가입을 진행하도록 개선
  • 로그인 성공 후 TanStack Query와 Zustand를 활용해 사용자 정보를 즉시 불러와 전역 상태에 저장함으로써, 헤더와 같은 UI 컴포넌트가 실시간으로 로그인 상태를 반영하도록 구현
  • 리드미 gif 업데이트

👻 주요 변경 사항

  1. kakao/transition 페이지 추가
  • 카카오 OAuth 인증 후, 서버 응답에 따라 로그인 또는 회원가입을 명확히 구분하여 사용자 경험을 향상시킵니다.
  • 서버에서 회원가입이 필요한 경우(status=need-signup) 클라이언트를 kakao/transition 페이지로 리디렉션합니다.
  • transition 페이지는 status 쿼리 파라미터를 확인하여, 사용자에게 "회원 가입 먼저 진행해주세요."라는 메시지를 표시합니다.
  • 사용자는 이 페이지에서 닉네임을 입력하고, "계속하기" 버튼을 눌러 회원가입을 위한 재인증 과정을 시작합니다.
  1. 닉네임 입력 로직 추가
  • kakao/transition 페이지에 닉네임 입력 폼을 추가했습니다.
  • useForm과 Zod를 사용해 닉네임 유효성 검사를 수행합니다.
  • 사용자가 닉네임을 입력하고 버튼을 클릭하면, 닉네임 정보가 URL의 state 파라미터로 인코딩되어 카카오 인증 페이지로 전달됩니다.
  • 이후 서버는 이 state 값을 통해 닉네임을 받아 회원가입을 완료합니다.
  1. 인증 상태 관리 개선 (TanStack Query & Zustand)
  • 로그인 성공 후 유저 정보를 가져와 전역 상태에 동기화하는 로직을 강화했습니다.
  • 컴포넌트를 추가하여 앱이 로드될 때마다 useUser 훅을 호출하도록 했습니다.
  • useUser 훅은 TanStack Query를 사용해 서버로부터 유저 정보를 페칭하고, 그 결과를 Zustand 스토어에 동기화합니다.

이로써 로그인 직후 메인 페이지의 헤더 등 모든 컴포넌트가 최신 유저 정보를 즉시 반영하여 상태 불일치 문제를 해결합니다.

👻 체크리스트

  • Assignees에 본인을 등록했나요?
  • 라벨을 사이드 탭에서 등록했나요?
  • PR은 사이드 탭 Projects를 등록 하지마세요.
  • PR은 Milestone을 등록 하지마세요.
  • PR을 보내는 브랜치가 올바른지 확인했나요?
  • 팀원들이 리뷰하기 쉽도록 설명을 자세하게 작성했나요?
  • 변경사항을 충분히 테스트 했나요?
  • 컨벤션에 맞게 구현했나요?

📷 UI 변경 사항

image oauth2 oauth3 oauth4

👻 문제 사항

👻 논의 사항

👻 기타 참고 사항

  • accessToken 유효기간을 테스트를 위해 15초로 잠시 변경했습니다. 추후 다시 1시간으로 변경할 예정입니다.

Summary by CodeRabbit

  • 문서화

    • README에 주요 기능을 보여주는 GIF 미리보기 섹션이 추가되고, 불필요한 공백 및 이미지 크기 등이 정리되었습니다.
  • 신규 기능

    • 클라이언트 인증 상태를 서버와 동기화하는 AuthInitializer 컴포넌트가 추가되었습니다.
  • 리팩터

    • ClientProviders 컴포넌트가 ClientProvider로 이름이 변경되고, 관련 코드가 일관되게 수정되었습니다.
  • 버그 수정

    • useUser 훅이 글로벌 상태와 연동되어 사용자 정보 동기화 및 오류 시 상태 초기화가 반영되었습니다.
  • 기타

    • accessToken 쿠키의 유효기간이 15초로 단축되었습니다.
    • /api/etl 경로에 대한 미들웨어 예외 처리가 제거되어, 해당 요청도 일반 미들웨어 로직을 거치게 됩니다.
    • .gitignore에 local-assets/가 추가되었습니다.
    • 회원가입 및 로그인 후 전역 사용자 상태 업데이트 부분이 일시적으로 비활성화되었습니다.

@sgoldenbird sgoldenbird self-assigned this Aug 6, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 6, 2025

Walkthrough

이 변경 사항은 클라이언트 인증 동기화 기능 도입, 글로벌 사용자 상태 관리 연동, 인증 쿠키 만료 시간 단축, 미들웨어 내 주석 추가, .gitignore 및 README 문서 개선, 그리고 일부 컴포넌트 및 훅의 네이밍 및 구조 수정으로 구성되어 있습니다. 또한 카카오 OAuth 관련 닉네임 입력 및 검증 기능이 추가되었습니다.

Changes

Cohort / File(s) Change Summary
인증 상태 동기화 및 글로벌 상태 연동
src/app/_components/AuthInitializer.tsx, src/app/_components/ClientProvider.tsx, src/domain/Auth/hooks/useUser.ts
AuthInitializer 컴포넌트 추가 및 ClientProvider에 포함, useUser 훅이 글로벌 Zustand 스토어와 연동되어 사용자 정보 동기화 및 초기화 처리
컴포넌트 네이밍 및 레이아웃 적용
src/app/_components/ClientProvider.tsx, src/app/layout.tsx
ClientProvidersClientProvider로 네이밍 변경 및 레이아웃 내 컴포넌트 사용 방식 수정
인증 쿠키 만료 시간 변경
src/domain/Auth/utils/setAuthCookies.ts
accessToken 쿠키의 maxAge를 1시간에서 15초로 단축
미들웨어 주석 추가
src/middleware.ts
토큰 리프레시 로직 내 주석 추가, 개발 서버와 배포 환경 간 차이 언급
로그인/회원가입 훅에서 글로벌 상태 업데이트 주석 처리
src/domain/Auth/hooks/useSigninMutation.ts, src/domain/Auth/hooks/useSignupMutation.ts
useRoamReadyStoresetUser 호출 주석 처리로 로그인 및 회원가입 후 글로벌 사용자 상태 업데이트 비활성화
카카오 OAuth 닉네임 입력 및 검증 기능 추가
src/domain/Auth/components/KakaoTransition.tsx, src/domain/Auth/schemas/request.ts, src/app/api/auth/kakao/signup/route.ts
KakaoTransition 컴포넌트에 닉네임 입력 폼과 유효성 검사 추가, 닉네임을 OAuth state 파라미터로 전달, OAuth 회원가입 라우트에서 닉네임 파라미터 사용하도록 변경
README 및 .gitignore 개선
README.md, .gitignore
README에 GIF 미리보기 섹션 추가, 기여자 이미지 크기 조정, .next/ 중복 제거 및 local-assets/ 추가
Next.js 이미지 최적화 설정 변경
next.config.ts
images.unoptimized 설정 활성화 (true)

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant ClientProvider
    participant AuthInitializer
    participant useUser
    participant Store

    App->>ClientProvider: children 렌더링
    ClientProvider->>AuthInitializer: AuthInitializer 렌더링
    AuthInitializer->>useUser: useUser() 호출
    useUser->>Store: 사용자 정보 setUser/clearUser 동기화
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Possibly related PRs

Suggested labels

feat

Suggested reviewers

  • Seon-K
  • Yongmin0423

Poem

🐰
인증 싱크가 척척 맞춰지고,
쿠키는 짧게 15초 숨 고르네.
닉네임 입력해 카카오로 가고,
미들웨어엔 작은 메모 남기고,
GIF 춤추는 README 반짝이네!
로암레디, 오늘도 빛나네!
✨🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/248/readme

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

github-actions bot commented Aug 6, 2025

✅ Preview Deployment Ready!

🔗 Preview URL: https://roam-ready-oy7jrc6i7-yongmins-projects-bf5f7733.vercel.app
📝 Branch: feat/248/readme
💾 Commit: Feat: readme gif
🕐 Deployed at:


This preview will be automatically updated on new commits.

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: 0

🧹 Nitpick comments (1)
.gitignore (1)

18-18: 중복된 .next/ 항목을 제거해주세요.

17번째 줄에 이미 /.next/가 있어서 18번째 줄의 .next/는 중복입니다.

-/.next/
-.next/
+/.next/
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f7e7ce and 8f021ee.

⛔ Files ignored due to path filters (12)
  • gifs/auth1.gif is excluded by !**/*.gif
  • gifs/auth2.gif is excluded by !**/*.gif
  • gifs/auth3.gif is excluded by !**/*.gif
  • gifs/detail.gif is excluded by !**/*.gif
  • gifs/kakao.gif is excluded by !**/*.gif
  • gifs/main-carousel.gif is excluded by !**/*.gif
  • gifs/main-list-filter.gif is excluded by !**/*.gif
  • gifs/main-list-pagination.gif is excluded by !**/*.gif
  • gifs/main-search.gif is excluded by !**/*.gif
  • gifs/my-activity-edit-delete.gif is excluded by !**/*.gif
  • gifs/my-info.gif is excluded by !**/*.gif
  • gifs/my-reservation.gif is excluded by !**/*.gif
📒 Files selected for processing (8)
  • .gitignore (2 hunks)
  • README.md (3 hunks)
  • src/app/_components/AuthInitializer.tsx (1 hunks)
  • src/app/_components/ClientProvider.tsx (2 hunks)
  • src/app/layout.tsx (2 hunks)
  • src/domain/Auth/hooks/useUser.ts (2 hunks)
  • src/domain/Auth/utils/setAuthCookies.ts (1 hunks)
  • src/middleware.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • src/middleware.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: in the roamready project, page titles for create and edit pages are intentionally kept consistent (u...
Learnt from: Yongmin0423
PR: codeit-FE-15-Part4-Team1/RoamReady#359
File: src/app/(app)/mypage/experiences/edit/[id]/page.tsx:64-64
Timestamp: 2025-07-29T06:02:45.614Z
Learning: In the RoamReady project, page titles for create and edit pages are intentionally kept consistent (using "등록" for both) for design uniformity, rather than changing to reflect the specific operation like "수정".

Applied to files:

  • README.md
🧬 Code Graph Analysis (5)
src/app/layout.tsx (1)
src/app/_components/ClientProvider.tsx (1)
  • ClientProvider (25-33)
src/app/_components/ClientProvider.tsx (3)
src/shared/libs/queryClient.ts (1)
  • queryClient (14-24)
src/app/_components/AuthInitializer.tsx (1)
  • AuthInitializer (12-17)
src/shared/components/ui/toast/ToastContainer.tsx (1)
  • ToastContainer (20-43)
src/domain/Auth/utils/setAuthCookies.ts (1)
src/middleware.ts (1)
  • middleware (38-124)
src/app/_components/AuthInitializer.tsx (1)
src/domain/Auth/hooks/useUser.ts (1)
  • useUser (42-70)
src/domain/Auth/hooks/useUser.ts (2)
src/shared/store/index.ts (1)
  • useRoamReadyStore (32-47)
src/domain/Auth/services/index.ts (1)
  • getMe (85-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: vercel-preview
🔇 Additional comments (14)
.gitignore (1)

47-47: local-assets/ 디렉토리 추가가 적절합니다.

로컬 개발 환경에서 사용하는 에셋 파일들을 무시하는 것이 좋은 접근입니다.

src/domain/Auth/hooks/useUser.ts (3)

43-44: 글로벌 상태 통합이 잘 구현되었습니다.

useRoamReadyStore에서 setUserclearUser 함수를 추출하여 상태 관리를 중앙화한 것이 좋은 접근입니다.


50-50: staleTime 설정이 적절합니다.

5분의 staleTime은 사용자 정보의 특성상 적절한 캐시 시간입니다.


54-66: useEffect 로직이 올바르게 구현되었습니다.

쿼리 성공 시 글로벌 상태 업데이트, 실패 시 상태 클리어 로직이 적절합니다. 의존성 배열도 정확하게 설정되어 있습니다.

src/app/layout.tsx (1)

7-7: 컴포넌트 이름 변경이 일관되게 적용되었습니다.

ClientProviders에서 ClientProvider로의 이름 변경이 import와 사용 부분에서 일관되게 적용되었습니다.

Also applies to: 33-33

src/domain/Auth/utils/setAuthCookies.ts (1)

37-38: accessToken 만료 시간 15초 설정 – 의도 확인 필요

src/domain/Auth/utils/setAuthCookies.ts에서 accessToken의 maxAge가
기존 주석 처리된 60 * 60(1시간) 대신 15(초)로 변경되었습니다. 이로 인해:

  • 토큰 갱신 빈도 급증 → 사용자 경험 저하 우려
  • refreshToken 만료 전에도 세션이 자주 만료될 수 있음
  • docstring(“accessToken (1시간)”)과 실제 코드(15초) 불일치

middleware.ts에는 별도 maxAge 설정이 없어, 이 파일의 설정이 곧 토큰 수명 주기를 결정합니다.
이 변경이 디버깅 목적인지, 아니면 프로덕션용 의도인지 확인해주시기 바랍니다.
의도된 변경이라면 문서 및 주석 처리된 기존 코드도 함께 정리해주세요.

src/app/_components/AuthInitializer.tsx (1)

1-17: 인증 초기화 컴포넌트가 잘 구현되었습니다.

  • 'use client' 지시어가 적절히 사용됨
  • 단일 책임 원칙을 잘 따름 (인증 상태 초기화만 담당)
  • 명확한 문서화와 주석
  • null 반환으로 UI에 영향을 주지 않음

인증 상태 동기화를 위한 깔끔한 구현입니다.

src/app/_components/ClientProvider.tsx (4)

6-6: 인증 초기화 컴포넌트 import 추가 승인

AuthInitializer 컴포넌트를 올바르게 import했습니다. 이 컴포넌트는 앱 로드 시 인증 상태 동기화를 담당하는 중요한 역할을 합니다.


11-11: JSDoc 업데이트 승인

컴포넌트 이름 변경에 따른 JSDoc 주석 업데이트가 올바르게 적용되었습니다. 단수형 ClientProvider가 더 적절한 네이밍입니다.

Also applies to: 20-20


25-25: 컴포넌트 이름 변경 승인

ClientProviders에서 ClientProvider로의 이름 변경이 적절합니다. 단일 프로바이더 컴포넌트에 더 맞는 네이밍입니다.


28-28: 인증 초기화 컴포넌트 추가 승인

<AuthInitializer />QueryClientProvider 내부의 첫 번째 자식으로 배치한 것이 적절합니다. 앱 로드 시 인증 상태를 조기에 동기화하여 사용자 경험을 개선합니다.

README.md (3)

16-68: GIF 미리보기 섹션 추가 승인

잘 구성된 GIF 미리보기 섹션을 추가했습니다. 주요 기능들을 시각적으로 문서화하여 README의 품질을 크게 향상시켰습니다. 접기/펼치기 기능으로 문서 가독성도 유지했습니다.

카테고리별 구성이 논리적이고, GIF 파일 경로도 일관성 있게 작성되었습니다.


84-84: 기여자 이미지 크기 조정 승인

기여자 프로필 이미지의 너비를 조정하여 테이블 레이아웃의 일관성을 개선했습니다.

Also applies to: 87-87


102-102: 텍스트 포맷팅 수정 승인

"메인 페이지"에서 "메인페이지"로 공백을 제거하여 문서 내 텍스트의 일관성을 개선했습니다.

@github-actions
Copy link

github-actions bot commented Aug 6, 2025

✅ Preview Deployment Ready!

🔗 Preview URL: https://roam-ready-9ncofr55h-yongmins-projects-bf5f7733.vercel.app
📝 Branch: feat/248/readme
💾 Commit: Feat: readme gif
🕐 Deployed at:


This preview will be automatically updated on new commits.

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

🔭 Outside diff range comments (1)
src/domain/Auth/hooks/useSigninMutation.ts (1)

17-22: JSDoc 문서를 업데이트하세요.

현재 JSDoc 주석은 여전히 setUser 호출과 data 매개변수 사용에 대해 언급하고 있지만, 실제 코드에서는 이러한 동작이 제거되었습니다. 문서를 현재 구현과 일치하도록 업데이트해야 합니다.

특히 다음 부분들을 수정해야 합니다:

  • data 매개변수에 대한 설명 제거
  • setUser 호출에 대한 설명 제거
  • 사용자 상태 동기화가 useUser 훅에서 처리된다는 점 명시
🧹 Nitpick comments (4)
src/domain/Auth/hooks/useSigninMutation.ts (3)

8-8: 주석 처리된 import 문을 제거하세요.

주석 처리된 import 문은 코드 가독성을 저해합니다. 리팩토링이 완료되었다면 완전히 제거하는 것이 좋습니다.

-// import { useRoamReadyStore } from '@/shared/store';

35-35: 주석 처리된 코드를 제거하세요.

사용하지 않는 변수 선언도 제거해주세요.

-  // const setUser = useRoamReadyStore((state) => state.setUser);

41-44: 주석 처리된 코드를 정리하세요.

주석 처리된 코드들을 완전히 제거하여 코드 가독성을 향상시키세요.

-    onSuccess: () => {
-      // onSuccess: (data: SigninResponse) => {
+    onSuccess: () => {
       sessionStorage.removeItem('signup-form');
-      // setUser(data.user);
       queryClient.invalidateQueries({ queryKey: ['user', 'me'] });
src/domain/Auth/hooks/useUser.ts (1)

64-76: useEffect 의존성 배열과 최적화를 검토하세요.

두 개의 별도 useEffect를 사용하는 것은 명확하지만, 몇 가지 고려사항이 있습니다:

  1. setUserclearUser가 안정적인 참조를 가지는지 확인이 필요합니다.
  2. 성능 최적화를 위해 하나의 useEffect로 통합할 수 있습니다.

통합된 useEffect 예시:

-  useEffect(() => {
-    if (queryResult.isSuccess) {
-      setUser(queryResult.data);
-    }
-  }, [queryResult.isSuccess, queryResult.data, setUser]);
-
-  useEffect(() => {
-    if (queryResult.isError) {
-      clearUser();
-    }
-  }, [queryResult.isError, clearUser]);
+  useEffect(() => {
+    if (queryResult.isSuccess && queryResult.data) {
+      setUser(queryResult.data);
+    } else if (queryResult.isError) {
+      clearUser();
+    }
+  }, [queryResult.isSuccess, queryResult.isError, queryResult.data, setUser, clearUser]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f021ee and 5a44de4.

⛔ Files ignored due to path filters (3)
  • gifs/create-activity1.gif is excluded by !**/*.gif
  • gifs/create-activity2.gif is excluded by !**/*.gif
  • gifs/my-reservation-list.gif is excluded by !**/*.gif
📒 Files selected for processing (9)
  • README.md (3 hunks)
  • src/app/_components/AuthInitializer.tsx (1 hunks)
  • src/app/_components/ClientProvider.tsx (1 hunks)
  • src/app/layout.tsx (2 hunks)
  • src/domain/Auth/hooks/useSigninMutation.ts (2 hunks)
  • src/domain/Auth/hooks/useSignupMutation.ts (3 hunks)
  • src/domain/Auth/hooks/useUser.ts (2 hunks)
  • src/domain/Auth/utils/setAuthCookies.ts (1 hunks)
  • src/middleware.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/domain/Auth/hooks/useSignupMutation.ts
  • README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/middleware.ts
  • src/domain/Auth/utils/setAuthCookies.ts
  • src/app/layout.tsx
  • src/app/_components/AuthInitializer.tsx
  • src/app/_components/ClientProvider.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: vercel-preview
🔇 Additional comments (2)
src/domain/Auth/hooks/useUser.ts (2)

53-61: 사용자 상태 중앙화 접근법이 우수합니다.

useUser 훅에서 전역 상태 동기화를 중앙 집중식으로 처리하는 것은 좋은 아키텍처 결정입니다. staleTime 설정도 불필요한 재요청을 방지하여 성능을 개선합니다.


18-18: AuthInitializer 구현 및 타이밍 확인 완료

  • <AuthInitializer />ClientProvider 최상단에서 즉시 렌더링되어 앱 시작 시 바로 useUser()를 호출합니다.
  • 로그인/회원가입 후 queryClient.invalidateQueries('currentUser') 호출 시, 활성화된 쿼리가 자동으로 재요청되어 서버와 클라이언트의 사용자 상태가 즉시 동기화됩니다.
  • UI 컴포넌트에서 isLoading/isFetching 상태를 활용해 로딩 스피너나 플레이스홀더를 표시하면, 페칭 중에 잘못된 정보가 노출되지 않습니다.

현 구현은 의도한 대로 서버·클라이언트 간 상태 일관성을 유지하므로 추가 수정 없이 그대로 유지하셔도 됩니다.

Comment on lines +64 to +69
useEffect(() => {
// isSuccess가 true가 되면 (데이터 로딩 성공 시)
if (queryResult.isSuccess) {
setUser(queryResult.data);
}
}, [queryResult.isSuccess, queryResult.data, setUser]);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

데이터 존재 여부 확인을 추가하세요.

queryResult.isSuccess가 true여도 data가 undefined일 가능성이 있습니다. 안전성을 위해 데이터 존재 여부를 확인하는 것이 좋습니다.

   useEffect(() => {
-    if (queryResult.isSuccess) {
+    if (queryResult.isSuccess && queryResult.data) {
       setUser(queryResult.data);
     }
   }, [queryResult.isSuccess, queryResult.data, setUser]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
// isSuccess가 true가 되면 (데이터 로딩 성공 시)
if (queryResult.isSuccess) {
setUser(queryResult.data);
}
}, [queryResult.isSuccess, queryResult.data, setUser]);
useEffect(() => {
// isSuccess가 true가 되면 (데이터 로딩 성공 시)
if (queryResult.isSuccess && queryResult.data) {
setUser(queryResult.data);
}
}, [queryResult.isSuccess, queryResult.data, setUser]);
🤖 Prompt for AI Agents
In src/domain/Auth/hooks/useUser.ts around lines 64 to 69, the useEffect hook
sets the user state when queryResult.isSuccess is true, but it does not check if
queryResult.data actually exists. To fix this, add a condition to verify that
queryResult.data is not undefined before calling setUser, ensuring the code only
sets the user when valid data is present.

Base automatically changed from develop to main August 6, 2025 11:51
@sgoldenbird sgoldenbird changed the title Feat: readme gif Feat: Oauth 통합구현 Aug 6, 2025
@sgoldenbird sgoldenbird changed the title Feat: Oauth 통합구현 Feat: Oauth 통합구현(transition page) Aug 6, 2025
@github-actions
Copy link

github-actions bot commented Aug 6, 2025

✅ Preview Deployment Ready!

🔗 Preview URL: https://roam-ready-q3hi0g208-yongmins-projects-bf5f7733.vercel.app
📝 Branch: feat/248/readme
💾 Commit: Feat: readme gif
🕐 Deployed at:


This preview will be automatically updated on new commits.

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: 2

🔭 Outside diff range comments (1)
src/app/api/auth/kakao/signup/route.ts (1)

111-129: 409/400 에러 처리 로직 복원 필요

src/app/api/auth/kakao/signup/route.ts에서 409/400(이미 가입된 사용자) 분기 처리가 주석 처리되어 실제로 실행되지 않고 있습니다. 다른 곳에서도 해당 리디렉션을 대체하는 구현이 발견되지 않았으므로, /kakao/transition?status=already-exists로의 리디렉션 로직을 복원해주세요.

  • 파일: src/app/api/auth/kakao/signup/route.ts
  • 위치: 주석 처리된 409/400 에러 처리 블록 (약 111–129행)
🧹 Nitpick comments (1)
src/app/api/auth/kakao/signup/route.ts (1)

95-95: 이전 랜덤 닉네임 생성 코드 정리 필요

주석 처리된 랜덤 닉네임 생성 코드가 남아있습니다. 더 이상 사용하지 않는다면 완전히 제거하는 것이 좋겠습니다.

-    // const arbitraryNickname = `K_${crypto.randomUUID().replace(/-/g, '').slice(0, 7)}`;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a44de4 and 71fc51b.

📒 Files selected for processing (7)
  • next.config.ts (1 hunks)
  • src/app/api/auth/kakao/signin/route.ts (2 hunks)
  • src/app/api/auth/kakao/signup/route.ts (2 hunks)
  • src/domain/Auth/components/KakaoTransition.tsx (2 hunks)
  • src/domain/Auth/schemas/request.ts (1 hunks)
  • src/domain/Auth/utils/setAuthCookies.ts (1 hunks)
  • src/middleware.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • next.config.ts
  • src/domain/Auth/schemas/request.ts
  • src/app/api/auth/kakao/signin/route.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/middleware.ts
  • src/domain/Auth/utils/setAuthCookies.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: vercel-preview
🔇 Additional comments (6)
src/app/api/auth/kakao/signup/route.ts (1)

78-78: state 파라미터 추출 로직 추가 확인됨

카카오 OAuth에서 state 파라미터를 통해 닉네임을 전달받는 방식으로 변경되었습니다. 이는 적절한 접근 방식입니다.

src/domain/Auth/components/KakaoTransition.tsx (5)

3-13: 새로운 의존성 임포트 확인됨

카카오 OAuth 닉네임 입력 기능을 위한 필요한 의존성들이 적절히 임포트되었습니다.


54-60: 폼 설정이 적절히 구성됨

react-hook-form 설정이 올바르게 되어 있으며, 실시간 유효성 검사(mode: 'onChange')가 활성화되어 사용자 경험이 향상되었습니다.


64-72: 닉네임 인코딩 처리 로직 확인됨

사용자 입력 닉네임을 URL 인코딩하여 state 파라미터로 전달하는 로직이 적절히 구현되었습니다.


96-104: 버튼 상태 관리가 적절히 구현됨

폼 유효성에 따른 버튼 비활성화 및 스타일 변경이 올바르게 구현되어 사용자 경험이 향상되었습니다. formState.isValid를 사용하여 동적으로 버튼 상태를 관리하는 것이 좋습니다.


81-117: FormProvider 래핑 및 전체 구조 개선 확인됨

전체 컴포넌트가 FormProvider로 적절히 래핑되어 폼 컨텍스트가 올바르게 제공되고 있습니다. 조건부 렌더링을 통해 회원가입이 필요한 경우에만 닉네임 입력 필드를 표시하는 로직도 적절합니다.

Comment on lines +86 to +93
const nickname = state ? decodeURIComponent(state) : null;

if (!nickname) {
throw Object.assign(
new Error('회원가입에 필요한 닉네임 정보가 없습니다.'),
{ status: 400 },
);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

닉네임 디코딩 및 검증 로직에 보안 강화 필요

현재 구현에서 몇 가지 보안 및 안정성 개선이 필요합니다:

  1. decodeURIComponent 사용 시 잘못된 URI 인코딩에 대한 예외 처리가 없습니다
  2. 서버 측에서 닉네임 길이나 형식에 대한 추가 검증이 필요합니다
  3. 클라이언트에서 전달받은 데이터이므로 보안 검증을 강화해야 합니다

다음과 같이 개선하는 것을 제안합니다:

-    const nickname = state ? decodeURIComponent(state) : null;
-
-    if (!nickname) {
-      throw Object.assign(
-        new Error('회원가입에 필요한 닉네임 정보가 없습니다.'),
-        { status: 400 },
-      );
-    }
+    let nickname: string | null = null;
+    
+    if (state) {
+      try {
+        nickname = decodeURIComponent(state);
+        // 서버 측 닉네임 검증 (길이 및 형식)
+        if (nickname.length < 1 || nickname.length > 10) {
+          throw new Error('닉네임은 1-10자 사이여야 합니다.');
+        }
+        // 특수문자 검증 등 추가 가능
+      } catch (error) {
+        throw Object.assign(
+          new Error('유효하지 않은 닉네임 형식입니다.'),
+          { status: 400 },
+        );
+      }
+    }
+
+    if (!nickname) {
+      throw Object.assign(
+        new Error('회원가입에 필요한 닉네임 정보가 없습니다.'),
+        { status: 400 },
+      );
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const nickname = state ? decodeURIComponent(state) : null;
if (!nickname) {
throw Object.assign(
new Error('회원가입에 필요한 닉네임 정보가 없습니다.'),
{ status: 400 },
);
}
let nickname: string | null = null;
if (state) {
try {
nickname = decodeURIComponent(state);
// 서버 측 닉네임 검증 (길이 및 형식)
if (nickname.length < 1 || nickname.length > 10) {
throw new Error('닉네임은 1-10자 사이여야 합니다.');
}
// 특수문자 검증 등 추가 가능
} catch (error) {
throw Object.assign(
new Error('유효하지 않은 닉네임 형식입니다.'),
{ status: 400 },
);
}
}
if (!nickname) {
throw Object.assign(
new Error('회원가입에 필요한 닉네임 정보가 없습니다.'),
{ status: 400 },
);
}
🤖 Prompt for AI Agents
In src/app/api/auth/kakao/signup/route.ts around lines 86 to 93, the nickname
decoding and validation lacks error handling and security checks. Wrap the
decodeURIComponent call in a try-catch block to handle malformed URI errors
gracefully. After decoding, add server-side validation to check the nickname's
length and format against allowed criteria. Ensure all validations reject
invalid or potentially harmful input before proceeding.

Comment on lines +90 to +94
<Input.Root name='nickname' type='text'>
<Input.Field placeholder='닉네임을 입력해주세요' maxLength={11} />
<Input.Helper />
</Input.Root>
)}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

입력 필드 설정에서 불일치 발견

maxLength={11}로 설정되어 있지만, 스키마에서는 닉네임을 1-10자로 제한하고 있습니다. 일관성을 위해 maxLength={10}으로 변경해야 합니다.

-            <Input.Field placeholder='닉네임을 입력해주세요' maxLength={11} />
+            <Input.Field placeholder='닉네임을 입력해주세요' maxLength={10} />

또한, 접근성 향상을 위해 적절한 레이블을 추가하는 것을 권장합니다:

          <Input.Root name='nickname' type='text'>
+            <Input.Label>닉네임</Input.Label>
            <Input.Field placeholder='닉네임을 입력해주세요' maxLength={10} />
            <Input.Helper />
          </Input.Root>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Input.Root name='nickname' type='text'>
<Input.Field placeholder='닉네임을 입력해주세요' maxLength={11} />
<Input.Helper />
</Input.Root>
)}
<Input.Root name='nickname' type='text'>
<Input.Label>닉네임</Input.Label>
<Input.Field placeholder='닉네임을 입력해주세요' maxLength={10} />
<Input.Helper />
</Input.Root>
)}
🤖 Prompt for AI Agents
In src/domain/Auth/components/KakaoTransition.tsx around lines 90 to 94, the
Input.Field has maxLength set to 11, which conflicts with the schema limiting
nicknames to 10 characters. Change maxLength to 10 to match the schema.
Additionally, add an accessible label for the input field to improve
accessibility, such as using a label element or aria-label attribute.

@sgoldenbird sgoldenbird merged commit 773968d into main Aug 6, 2025
2 checks passed
@sgoldenbird sgoldenbird deleted the feat/248/readme branch August 6, 2025 13:43
@sgoldenbird sgoldenbird changed the title Feat: Oauth 통합구현(transition page) Feat: Oauth 통합구현(transition page) 및 사용자 정보 동기화 기능 변경 Aug 6, 2025
@sgoldenbird sgoldenbird changed the title Feat: Oauth 통합구현(transition page) 및 사용자 정보 동기화 기능 변경 Feat: Oauth 통합구현(transition page) 및 사용자 정보 동기화 기능 추가 변경 Aug 6, 2025
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.

Refactor: Oauth 통합구현 및 사용자 정보 동기화 기능 추가 변경 (+리드미 gif)

4 participants