refactor: 로그인 진입 시 세션 조회 왕복 제거 및 스플래시 전환 개선 - #348
Conversation
|
Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다. |
* refactor: /archive 탭 쿼리 파라미터를 /archive/wish, /archive/tournament 경로로 분리 * refactor: 구버전 /archive(?tab=) 경로를 신규 경로로 리다이렉트 * refactor: 옛 /wish 페이지 잔재 정리 및 archive 콜로케이션 재배치 * fix: 위시 페이지 체류 중 후속 공유 인텐트가 무시되던 문제 수정 * fix: 보관 탭 활성 판정 경로 경계 추가 및 위시 추가 후 중복 라우팅 제거 * fix: 공유 인텐트 실패 URL 잠금 해제 및 링크 담기 실패 시 다이얼로그 유지
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough로그인 페이지의 회원 판정이 Changes로그인 인증 흐름
위시 공유 처리
스플래시 및 렌더링 설정
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant LoginPage
participant getRoleFromToken
participant LoginButtons
participant refreshClientToken
participant postGuestLoginMutation
LoginPage->>getRoleFromToken: access_token 역할 확인
getRoleFromToken-->>LoginPage: MEMBER 또는 null
LoginPage->>LoginButtons: redirect와 action 전달
LoginButtons->>refreshClientToken: 클라이언트 토큰 갱신
refreshClientToken-->>LoginButtons: 성공 또는 실패
LoginButtons->>postGuestLoginMutation: 실패 시 게스트 발급
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
apps/web/src/app/archive/tournament/_components/TournamentStatusTab.tsx (1)
19-34: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win탭 상태를 보조기기에 노출해 주세요.
현재 선택 상태가 색상과 indicator로만 표현되어 스크린 리더에는 일반 버튼 그룹으로 노출됩니다. wrapper에
role="tablist", 각 버튼에role="tab"과aria-selected를 추가해 선택 상태를 전달해 주세요. 이 지적은 현재 컴포넌트가 콘텐츠 전환용 탭 UI로 사용되는 구현에 근거합니다.🤖 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 `@apps/web/src/app/archive/tournament/_components/TournamentStatusTab.tsx` around lines 19 - 34, Update the tab wrapper around TABS in TournamentStatusTab to use role="tablist", and add role="tab" plus aria-selected based on activeTab === tab.value to each tab button so assistive technologies receive the selection state.apps/web/src/app/archive/_common/_components/ArchivePageLayout.tsx (1)
3-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win컴포넌트 props 타입 이름을 컴포넌트별로 명시해 주세요.
세 파일 모두 일반적인
Props를 사용해 저장소의 명명 규칙을 위반합니다. As per coding guidelines, 컴포넌트 props 타입은{ComponentName}Props형식을 사용해야 합니다.
apps/web/src/app/archive/_common/_components/ArchivePageLayout.tsx#L3-L8:Props를ArchivePageLayoutProps로 변경하고 시그니처 참조를 갱신해 주세요.apps/web/src/app/archive/tournament/_components/TournamentHistoryList.tsx#L8-L13:Props를TournamentHistoryListProps로 변경하고 시그니처 참조를 갱신해 주세요.apps/web/src/app/archive/tournament/_components/TournamentStatusTab.tsx#L7-L10:Props를TournamentStatusTabProps로 변경하고 시그니처 참조를 갱신해 주세요.🤖 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 `@apps/web/src/app/archive/_common/_components/ArchivePageLayout.tsx` around lines 3 - 8, Rename the generic Props type to the component-specific name and update its usage in ArchivePageLayout.tsx (lines 3-8) to ArchivePageLayoutProps, TournamentHistoryList.tsx (lines 8-13) to TournamentHistoryListProps, and TournamentStatusTab.tsx (lines 7-10) to TournamentStatusTabProps. Ensure each component signature references its renamed type.Source: Coding guidelines
🤖 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 `@apps/web/src/app/archive/tournament/_components/TournamentHistoryList.tsx`:
- Around line 12-13: Update TournamentHistoryList to distinguish the empty-state
message when statuses includes COMPLETED, using the existing tab context or an
emptyMessage prop. Ensure completed tournaments show completion-appropriate
wording, while other statuses retain the current “not started” message; align
the condition with the COMPLETED mapping in ArchiveTournamentClient.tsx.
In `@apps/web/src/app/archive/wish/_components/WishContentClient.tsx`:
- Around line 5-6: Update the useDeleteWishes and useShareIntentWish imports in
WishContentClient.tsx to use the project’s `@/`* absolute path alias instead of
relative sibling-directory paths; keep relative imports only for files in the
same directory.
In `@apps/web/src/app/archive/wish/_hooks/useShareIntentWish.ts`:
- Around line 32-51: Update handleShareIntent so the processedUrlsRef entry is
removed in the mutation’s onSettled callback rather than only onError, allowing
both successful and failed URLs to be shared again while preserving duplicate
protection during processing.
In `@apps/web/src/app/login/page.tsx`:
- Around line 37-39: In the login page JSX paragraph element, reformat the
className attribute so each line complies with the 100-character print width
while preserving the existing class names and whitespace-pre-line behavior.
In `@apps/web/src/utils/auth.ts`:
- Around line 34-41: Update getRoleFromToken to validate payload.role at runtime
instead of relying on the UserIdentityTypeT type assertion. Return the role only
when it is exactly an allowed GUEST or MEMBER value; return null for missing,
arbitrary, or non-string values.
---
Nitpick comments:
In `@apps/web/src/app/archive/_common/_components/ArchivePageLayout.tsx`:
- Around line 3-8: Rename the generic Props type to the component-specific name
and update its usage in ArchivePageLayout.tsx (lines 3-8) to
ArchivePageLayoutProps, TournamentHistoryList.tsx (lines 8-13) to
TournamentHistoryListProps, and TournamentStatusTab.tsx (lines 7-10) to
TournamentStatusTabProps. Ensure each component signature references its renamed
type.
In `@apps/web/src/app/archive/tournament/_components/TournamentStatusTab.tsx`:
- Around line 19-34: Update the tab wrapper around TABS in TournamentStatusTab
to use role="tablist", and add role="tab" plus aria-selected based on activeTab
=== tab.value to each tab button so assistive technologies receive the selection
state.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 48396b3f-c93e-4dfa-80f7-ac53771f3c24
📒 Files selected for processing (54)
apps/app/app/+native-intent.tsapps/app/components/ShareBottomSheet.tsxapps/app/hooks/useShareIntent.tsapps/web/next.config.mjsapps/web/src/apis/getWishlist.tsapps/web/src/app/_components/SplashClient.tsxapps/web/src/app/_components/splash.cssapps/web/src/app/archive/_common/_components/ArchivePageLayout.tsxapps/web/src/app/archive/_components/WishTab.tsxapps/web/src/app/archive/_components/tournament-history-content/client.tsxapps/web/src/app/archive/_types/wish.tsapps/web/src/app/archive/page.tsxapps/web/src/app/archive/tournament/_components/ArchiveTournamentClient.tsxapps/web/src/app/archive/tournament/_components/TournamentHistoryContent.tsxapps/web/src/app/archive/tournament/_components/TournamentHistoryList.tsxapps/web/src/app/archive/tournament/_components/TournamentStatusTab.tsxapps/web/src/app/archive/tournament/page.tsxapps/web/src/app/archive/wish/[id]/_hooks/useDeleteWish.tsapps/web/src/app/archive/wish/[id]/_hooks/usePatchWish.tsapps/web/src/app/archive/wish/[id]/layout.tsxapps/web/src/app/archive/wish/_apis/deleteWishes.tsapps/web/src/app/archive/wish/_components/FabMenu.tsxapps/web/src/app/archive/wish/_components/WishAddDialog.tsxapps/web/src/app/archive/wish/_components/WishCardSkeleton.tsxapps/web/src/app/archive/wish/_components/WishContent.tsxapps/web/src/app/archive/wish/_components/WishContentClient.tsxapps/web/src/app/archive/wish/_components/WishFab.tsxapps/web/src/app/archive/wish/_components/WishGridContent.tsxapps/web/src/app/archive/wish/_components/WishlistBottomBar.tsxapps/web/src/app/archive/wish/_components/WishlistFabArea.tsxapps/web/src/app/archive/wish/_components/WishlistList.tsxapps/web/src/app/archive/wish/_components/wish-grid/WishFailedCard.tsxapps/web/src/app/archive/wish/_components/wish-grid/WishProcessingCard.tsxapps/web/src/app/archive/wish/_components/wish-grid/index.tsxapps/web/src/app/archive/wish/_hooks/useDeleteWishes.tsapps/web/src/app/archive/wish/_hooks/useShareIntentWish.tsapps/web/src/app/archive/wish/page.tsxapps/web/src/app/login/_components/LoginButtons.tsxapps/web/src/app/login/layout.tsxapps/web/src/app/login/page.tsxapps/web/src/app/notification/_utils/getNotificationRoute.tsapps/web/src/app/tournament/[id]/create/by-wish/_components/WishSelectCard.tsxapps/web/src/components/bottom-tab-bar/index.tsxapps/web/src/components/common/wish-card/index.tsxapps/web/src/components/get-item-dialog/ByLinkDialog.tsxapps/web/src/components/tournament-error-dialog/index.tsxapps/web/src/consts/route.tsapps/web/src/hooks/useNotificationSSE.tsapps/web/src/hooks/usePostWishLink.tsapps/web/src/hooks/usePostWishOCR.tsapps/web/src/types/wish.tsapps/web/src/utils/auth.tsapps/web/src/utils/getRouteType.tsapps/web/src/utils/pushNotificationRoute.ts
💤 Files with no reviewable changes (6)
- apps/web/src/app/archive/_components/tournament-history-content/client.tsx
- apps/web/src/app/archive/_types/wish.ts
- apps/web/src/app/login/layout.tsx
- apps/web/src/app/archive/_components/WishTab.tsx
- apps/web/src/app/archive/page.tsx
- apps/web/src/app/_components/splash.css
# Conflicts: # apps/web/src/app/archive/wish/_hooks/useShareIntentWish.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/web/src/app/layout.tsx (1)
5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win타입 전용 React import를
import type으로 변경해 주세요.
React는 타입 참조에만 사용되므로 런타임 기본 import 대신 타입 import를 사용하고React.ReactNode도ReactNode로 바꾸는 편이 규칙에 맞습니다.수정 예시
-import React from 'react'; +import type { ReactNode } from 'react'; - children: React.ReactNode; + children: ReactNode;As per coding guidelines,
apps/web/**/*.{ts,tsx}에서는 타입 전용 import에import type을 사용해야 합니다.🤖 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 `@apps/web/src/app/layout.tsx` at line 5, Update the React import in the layout module to use a type-only import, and replace the `React.ReactNode` references with the imported `ReactNode` type. Preserve the component behavior while removing the runtime React import.Source: Coding guidelines
🤖 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.
Nitpick comments:
In `@apps/web/src/app/layout.tsx`:
- Line 5: Update the React import in the layout module to use a type-only
import, and replace the `React.ReactNode` references with the imported
`ReactNode` type. Preserve the component behavior while removing the runtime
React import.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: b85790cd-54c2-4b33-bf17-c11908958197
⛔ Files ignored due to path filters (1)
apps/web/src/assets/fonts/PretendardVariable.woff2is excluded by!**/*.woff2
📒 Files selected for processing (2)
apps/web/src/app/layout.tsxapps/web/src/styles/globals.css
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@apps/web/src/components/Providers.tsx`:
- Around line 15-22: Update the ReactQueryDevtools dynamic import to disable
server-side rendering by passing the next/dynamic option ssr: false, while
preserving the existing development-only loading behavior.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: be0a2eb9-846e-46b7-bfbd-3d203cc73488
📒 Files selected for processing (1)
apps/web/src/components/Providers.tsx
* refactor: access token JWT에서 role 추출하는 유틸 추가 * refactor: 로그인 세션 검사(getMe) 제거하고 JWT role 기반으로 전환 * refactor: 게스트 세션 재활용 판정을 클릭 시점 refresh로 일원화 * fix: 루트 스플래시 배경 FOUC 제거 * feat: 로그인 진입 시 문구·버튼 fade-in 애니메이션 추가 * refactor: /archive 탭을 위시리스트·내 토너먼트 페이지로 분리 (#347) * refactor: /archive 탭 쿼리 파라미터를 /archive/wish, /archive/tournament 경로로 분리 * refactor: 구버전 /archive(?tab=) 경로를 신규 경로로 리다이렉트 * refactor: 옛 /wish 페이지 잔재 정리 및 archive 콜로케이션 재배치 * fix: 위시 페이지 체류 중 후속 공유 인텐트가 무시되던 문제 수정 * fix: 보관 탭 활성 판정 경로 경계 추가 및 위시 추가 후 중복 라우팅 제거 * fix: 공유 인텐트 실패 URL 잠금 해제 및 링크 담기 실패 시 다이얼로그 유지 * refactor: JWT role을 명시적 검증으로 좁혀 타입 단언 제거 * fix: share intent 처리 후 URL 잠금 해제하여 재공유 허용 * refactor: font preload 삭제 * refactor: Pretendard 폰트 CDN Dynamic Subset Variable로 교체 * chore: TanstackQuery devtool Dynamic Import로 변경 * chore: Tanstack Query Devtools ssr false 설정
* fix: svgo removeViewBox 비활성화로 아이콘 축소 렌더링 시 잘림 방지 * feat: 바텀탭 디자인 변경 및 탭 4개로 분리 * refactor: 바텀탭 button > link 태그로 교체 * feat: 마이페이지에 바텀탭 추가 * refactor: 바텀탭 z-index를 Z_INDEX 상수로 관리 * refactor: 마이 탭 신설에 따라 헤더 프로필 아이콘 제거 * feat: 바텀탭 포인터 다운 시 스케일업 인터랙션 추가 * feat: 바텀탭 인디케이터 드래그로 탭 전환하는 인터랙션 추가 * feat: 바텀탭 liquid glass 효과 추가 * feat: 바텀탭 포커스되지 않은 탭 클릭해도 드래그 가능하도록 변경 * feat: 바텀탭 렌즈 변신 조건 정리 및 배경 틴트 상태 분리 * refactor: 바텀탭 wrapper 컴포넌트 내부로 이동 * style: 바텀탭 blur 완화 * fix: 탭바 새 제스처 시작 시 예약된 라우팅 취소 * fix: 탭바 착지 애니메이션 완료 후 라우팅되도록 지연 정렬 * fix: 탭바 새 제스처 시작 시 예약된 라우팅 취소 * refactor: 로그인 진입 시 세션 조회 왕복 제거 및 스플래시 전환 개선 (#348) * refactor: access token JWT에서 role 추출하는 유틸 추가 * refactor: 로그인 세션 검사(getMe) 제거하고 JWT role 기반으로 전환 * refactor: 게스트 세션 재활용 판정을 클릭 시점 refresh로 일원화 * fix: 루트 스플래시 배경 FOUC 제거 * feat: 로그인 진입 시 문구·버튼 fade-in 애니메이션 추가 * refactor: /archive 탭을 위시리스트·내 토너먼트 페이지로 분리 (#347) * refactor: /archive 탭 쿼리 파라미터를 /archive/wish, /archive/tournament 경로로 분리 * refactor: 구버전 /archive(?tab=) 경로를 신규 경로로 리다이렉트 * refactor: 옛 /wish 페이지 잔재 정리 및 archive 콜로케이션 재배치 * fix: 위시 페이지 체류 중 후속 공유 인텐트가 무시되던 문제 수정 * fix: 보관 탭 활성 판정 경로 경계 추가 및 위시 추가 후 중복 라우팅 제거 * fix: 공유 인텐트 실패 URL 잠금 해제 및 링크 담기 실패 시 다이얼로그 유지 * refactor: JWT role을 명시적 검증으로 좁혀 타입 단언 제거 * fix: share intent 처리 후 URL 잠금 해제하여 재공유 허용 * refactor: font preload 삭제 * refactor: Pretendard 폰트 CDN Dynamic Subset Variable로 교체 * chore: TanstackQuery devtool Dynamic Import로 변경 * chore: Tanstack Query Devtools ssr false 설정 * fix: Android 12+ 스플래시 로고 저해상도 문제 해결 (RN 오버레이로 전환) * fix: Android 시스템 스플래시 저품질 로고 미노출 처리 (배경색만 표시) * Revert "fix: Android 시스템 스플래시 저품질 로고 미노출 처리 (배경색만 표시)" This reverts commit adede7e. * Revert "fix: Android 12+ 스플래시 로고 저해상도 문제 해결 (RN 오버레이로 전환)" This reverts commit 74d09aa. * fix: 안드로이드 카카오 로그인 무한 로딩 수정 (리다이렉트 수신 액티비티 등록) (#350) * fix: 카카오 로그인 안드로이드 리다이렉트 수신 액티비티 등록 * chore: 서명 자격증명 및 빌드 산출물 gitignore 추가 * fix: 안드로이드 스플래시 로고 저해상도 노출 수정 (RN 오버레이 전환) (#352) * fix: Android 12+ 스플래시 로고 저해상도 문제 해결 (RN 오버레이로 전환) * fix: Android 시스템 스플래시 저품질 로고 미노출 처리 (배경색만 표시) * fix: SplashScreen.hideAsync rejection 처리 추가 * refactor: BottomCta 공통 컴포넌트 개선 및 페이지별 개별 구현 통합 (#345) * feat: 바텀 CTA 상단 그라데이션 옵션 추가 및 패딩 스펙 반영 * refactor: 페이지별 바텀 CTA를 BottomCta 공통 컴포넌트로 교체 * chore: iOS ShareBottomSheet 에셋 파일명 교체 (#353) * chore: iOS 앱 공유 바텀 시트 에셋 추가 * feat: iOS 앱 공유 바텀시트 성공/에러 UI 추가 * chore: app sentry cli 추가 * chore: patch app version * chore: Playwright E2E 테스트 환경 구축 (#319) * chore: playwright 설치 * chore: Playwright 설정 및 테스트 스크립트 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat: 게스트 storageState 생성 setup 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat: page.route 기반 API 목킹 fixture 및 목 데이터 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: 홈 및 토너먼트 준비 페이지 E2E 테스트 추가 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: SSR 접근 권한 조회용 목 스텁 서버 추가 및 준비 페이지 테스트를 진입 플로우로 변경 * chore: playwright/.auth gitignore 패턴 수정 * chore: E2E 테스트 CI 잡 추가 * fix: UI 모드와 CLI 동시 실행 시 목 스텁 포트 충돌 해결 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix: dev 전용 react-grab 스크립트 차단으로 trace 스냅샷 빈 화면 해결 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: CI Node 버전 22 LTS로 변경 * refactor: E2E 테스트를 도메인 폴더 구조로 변경 * refactor: @e2e alias 도입 * feat: E2E 이미지 목킹 추가 (가짜 CDN URL + /_next/image 인터셉트) * feat: api 목킹 fixture에 patch, delete 메서드 추가 * docs: E2E 테스트 사용 가이드 추가 --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Jung Sun A <amber0809@naver.com> --------- Co-authored-by: joyeongchan <tigerbone@naver.com> Co-authored-by: kanghaeun <145974230+kanghaeun@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* refactor: access token JWT에서 role 추출하는 유틸 추가 * refactor: 로그인 세션 검사(getMe) 제거하고 JWT role 기반으로 전환 * refactor: 게스트 세션 재활용 판정을 클릭 시점 refresh로 일원화 * fix: 루트 스플래시 배경 FOUC 제거 * feat: 로그인 진입 시 문구·버튼 fade-in 애니메이션 추가 * refactor: /archive 탭을 위시리스트·내 토너먼트 페이지로 분리 (#347) * refactor: /archive 탭 쿼리 파라미터를 /archive/wish, /archive/tournament 경로로 분리 * refactor: 구버전 /archive(?tab=) 경로를 신규 경로로 리다이렉트 * refactor: 옛 /wish 페이지 잔재 정리 및 archive 콜로케이션 재배치 * fix: 위시 페이지 체류 중 후속 공유 인텐트가 무시되던 문제 수정 * fix: 보관 탭 활성 판정 경로 경계 추가 및 위시 추가 후 중복 라우팅 제거 * fix: 공유 인텐트 실패 URL 잠금 해제 및 링크 담기 실패 시 다이얼로그 유지 * refactor: JWT role을 명시적 검증으로 좁혀 타입 단언 제거 * fix: share intent 처리 후 URL 잠금 해제하여 재공유 허용 * refactor: font preload 삭제 * refactor: Pretendard 폰트 CDN Dynamic Subset Variable로 교체 * chore: TanstackQuery devtool Dynamic Import로 변경 * chore: Tanstack Query Devtools ssr false 설정


작업 요약
작업 내용
1. 렌더 경로에서 세션 조회(
getMe) 백엔드 왕복 제거기존에는 로그인 페이지 SSR 시
layout과page두 곳에서getMe()(GET /api/v1/users/me)를await해서, 세션 조회 백엔드 왕복이 끝나야 로그인 UI가 렌더됐습니다.role(GUEST/MEMBER)이 담겨 있어, 네트워크 없이 동기 decode로 세션을 판정하도록 전환getRoleFromToken()유틸 추가 (기존decodeJwt재사용)login/layout.tsx삭제 (getMe·HydrationBoundary·리다이렉트가 모두 불필요해짐)→ 렌더 경로의 세션 조회 백엔드 왕복 1회 → 0회,
getMe호출 지점 2곳 → 0곳2. 멤버 리다이렉트 & 스테일 토큰 루프 가드
/login에 직접 진입하면 홈으로 리다이렉트 (JWT role 기반, 서버 왕복 없음)/login ↔ /home리다이렉트 루프가 도는 것을 방지 (action=session-expired일 때 멤버 리다이렉트 스킵)3. 게스트 세션 재활용 판정을 클릭 시점으로 일원화
canReuseGuestSession(JWT role 스냅샷)을 넘기지 않음handleGuestLogin이 클릭 시 항상refreshClientToken()시도 → 실패 시 새 게스트 발급4. 스플래시 배경 FOUC 제거
5. 로그인 진입 시 fade-in 애니메이션
animate-in fade-in-0, RSC 유지 · 클라이언트 전환 없음)스크린샷
변경 전
2026-07-16.10.47.53.mov
변경 후
2026-07-16.10.46.43.mov
연관 이슈
closes #346
Summary by CodeRabbit