Skip to content

토큰 로직 재설정#24

Merged
GWjun merged 4 commits intomainfrom
refactor/token-blocking/#23
Mar 29, 2025
Merged

토큰 로직 재설정#24
GWjun merged 4 commits intomainfrom
refactor/token-blocking/#23

Conversation

@GWjun
Copy link
Copy Markdown
Owner

@GWjun GWjun commented Mar 29, 2025

Summary by CodeRabbit

  • Documentation

    • 데이터베이스 설정 문서의 명령어가 업데이트되어, 최신 워크플로우를 반영합니다.
  • New Features

    • HTML 요청에 대해 새로운 인증 처리 흐름이 도입되어, 보호된 페이지 접근 시 로그인 처리가 개선되었습니다.
    • 사용자와 방문자 맞춤 레이아웃이 추가되어 인터페이스 경험이 향상되었습니다.
    • 새로운 경로 관리 모듈이 도입되어, 애플리케이션의 경로 정의가 중앙 집중화되었습니다.
  • Refactor

    • 토큰 갱신 및 로그아웃 프로세스가 개선되어 안정적인 인증 흐름을 제공합니다.
    • 불필요한 상태 관리 제거 및 경로 참조 업데이트로 코드 최적화를 이루었습니다.
  • Tests

    • 레이아웃 및 경로 변경 사항을 반영하여 테스트 코드가 업데이트되었습니다.

@GWjun GWjun added refactor refactoring code common common job labels Mar 29, 2025
@GWjun GWjun linked an issue Mar 29, 2025 that may be closed by this pull request
4 tasks
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 29, 2025

Walkthrough

이번 변경은 Prisma ORM 설정 명령어 수정, 서버 측 HTML 요청에 대한 인증 미들웨어 도입 및 개선, 리프레시 토큰 로직을 비동기로 전환하고 기존의 마운트 차단 로직을 제거하는 내용을 포함합니다. 또한, 레이아웃 컴포넌트와 라우팅 구조가 재구성되고, 관련 import 경로와 내보내기 방식, 테스트 파일 및 스토어 메서드가 업데이트되어 코드베이스의 구조와 일관성이 개선되었습니다.

Changes

File(s) Change Summary
README.md, server/entry.tsx, server/main.ts, server/middlewares/authMiddleware.ts, server/routes/auth/route.ts - README: Prisma 명령어 pnpx prisma generatenpx prisma db push
- 서버: routes import 경로를 절대 경로로 변경, HTML 요청용 인증 미들웨어 추가, 에러 및 404 핸들러 개선, 쿠키 경로 간소화
src/App.tsx, src/apis/apiClient.ts, src/hooks/useInitToken.ts, src/hooks/test/useInitToken.test.ts - 토큰 로직: App 내 마운트 차단 로직 제거, refreshToken 함수 및 promise 변수 도입
- 훅: 기본 → 명명된 import/내보내기 방식 전환
Components, Pages, Routes & Store (src/components/, src/contexts/QueryProvider/index.tsx, src/main.tsx, src/pages/, src/queries/auth/, src/routes/, src/stores/authStore.ts) - 레이아웃/라우팅: 기존 Layout 및 VisitorOutlet 삭제, UserLayout 및 VisitorLayout 신규 추가
- 경로/테스트: PATH 상수와 관련 import 경로 재구성, 페이지별 로그아웃 및 리디렉션 로직 개선
- 스토어: authStore의 logout 메서드 비동기화 및 QueryProvider 내보내기 방식 변경

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant S as Server
    participant AM as AuthMiddleware
    participant TS as TokenService
    C->>S: HTML 요청 전송
    S->>AM: preHandler Hook 호출
    alt 요청이 보호된 경로인 경우
        AM->>AM: refreshToken 쿠키 확인
        alt 쿠키 없음
            AM-->>C: 로그인 페이지로 리디렉션
        else 쿠키 있음
            AM->>AM: 쿠키 서명 검증
            alt 서명 오류
                AM-->>C: 로그인 페이지로 리디렉션
            else 서명 유효
                AM->>TS: refreshToken 검증 요청
                alt 토큰 검증 실패
                    AM-->>C: 쿠키 삭제 후 로그인 페이지로 리디렉션
                else 토큰 검증 성공
                    AM->>S: 사용자 정보 첨부 후 요청 전달
                end
            end
        end
    else
        AM-->>S: 요청 그대로 진행
    end
Loading
sequenceDiagram
    participant App as Application
    participant AF as API Client
    participant RT as refreshToken()
    participant LS as Logout Service
    App->>AF: API 요청 전송
    AF->>AF: 응답 실패 (401)
    AF->>RT: refreshTokenPromise 없음? → 호출
    RT-->>AF: 새 액세스 토큰 반환
    alt 토큰 갱신 성공
        AF->>App: 재요청 성공 응답 전달
    else
        AF->>LS: 로그아웃 처리 (await)
        AF->>App: 실패 응답 전달
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
페이지 보호 서버에서 수행 (#23)
refresh 비동기 처리 (#23)
마운트 블로킹 삭제 (#23)
로그인시 리디렉션 로직 (#23)

Poem

나는 토끼, 코드 숲을 헤치며 뛰네
미들웨어가 비추는 길, 별빛처럼 반짝여
토큰은 부드럽게 바람 따라 흐르고
레이아웃 새로움에 마음도 가볍게跳
한 줄 한 줄, 코딩의 꿈을 담아내네 🐰✨


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d0d9ddd and 64ca9f5.

📒 Files selected for processing (6)
  • README.md (1 hunks)
  • src/__test__/util/renderWithProvider.tsx (1 hunks)
  • src/components/layout/UserLayout.test.tsx (1 hunks)
  • src/components/layout/VisitorLayout.test.tsx (1 hunks)
  • src/hooks/__test__/useInitToken.test.ts (3 hunks)
  • src/pages/Home/Home.test.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/test/util/renderWithProvider.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • README.md
  • src/pages/Home/Home.test.tsx
  • src/components/layout/VisitorLayout.test.tsx
  • src/hooks/test/useInitToken.test.ts
🧰 Additional context used
🧬 Code Definitions (1)
src/components/layout/UserLayout.test.tsx (2)
src/stores/authStore.ts (1)
  • useAuthStore (12-28)
src/components/layout/UserLayout.tsx (1)
  • UserLayout (6-18)
🔇 Additional comments (4)
src/components/layout/UserLayout.test.tsx (4)

7-8: 컴포넌트 import 및 경로 업데이트가 적절하게 이루어졌습니다.

Layout에서 UserLayout으로의 변경과 PATH import 경로 업데이트가 잘 이루어졌습니다. 명시적인 import 방식은 코드의 가독성과 유지보수성을 향상시킵니다.


10-10: 테스트 설명이 컴포넌트 이름 변경과 일치하도록 업데이트되었습니다.

테스트 스위트 설명이 Layout 컴포넌트 테스트에서 UserLayout 컴포넌트 테스트로 적절하게 변경되었습니다.


16-16: 컴포넌트 참조가 업데이트되었습니다.

Route 엘리먼트가 UserLayout 컴포넌트를 사용하도록 업데이트되었습니다.


31-40: 인증 관련 테스트 케이스가 누락되었는지 확인하세요.

현재 테스트는 헤더, 푸터 및 Outlet의 렌더링만 검증하고 있습니다. AI 요약에 따르면 이전에는 사용자가 인증되지 않았을 때 로그인 페이지로 리디렉션하는 테스트 케이스가 있었습니다. 이 기능이 제거되었다면 괜찮지만, 만약 이 기능이 여전히 필요하다면 해당 테스트 케이스를 추가해야 합니다.

인증 로직이 다른 컴포넌트나 미들웨어로 이동되었는지 확인해보세요.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

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

🔭 Outside diff range comments (4)
src/hooks/__test__/useInitToken.test.ts (3)

17-25: ⚠️ Potential issue

테스트 케이스 업데이트 필요

useInitToken 훅이 더 이상 isPending 속성을 반환하지 않는 것으로 보입니다. 이 테스트 케이스를 업데이트하여 변경된 훅의 동작과 인터페이스에 맞게 조정해야 합니다.

 test('refresh 요청이 성공하면 accessToken을 초기화하고 isPending을 false로 설정한다', async () => {
   const { result } = renderHook(() => useInitToken())

-  expect(result.current.isPending).toBe(true)
-  await waitFor(() => expect(result.current.isPending).toBe(false))
+  // 변경된 useInitToken 훅 인터페이스에 맞게 테스트 케이스 수정 필요
+  // 예: useInitToken이 이제 객체가 아닌 경우
+  await waitFor(() => {/* 적절한 완료 조건 */})
   expect(useAuthStore.getState().setAccessToken).toHaveBeenCalledWith(
     'new-mock-access-token',
   )
 })
🧰 Tools
🪛 GitHub Check: test

[failure] 20-20: src/hooks/test/useInitToken.test.ts > useInitToken 훅 테스트 > refresh 요청이 성공하면 accessToken을 초기화하고 isPending을 false로 설정한다
TypeError: Cannot read properties of undefined (reading 'isPending')
❯ src/hooks/test/useInitToken.test.ts:20:27

🪛 GitHub Actions: Test

[error] 20-20: Cannot read properties of undefined (reading 'isPending')


27-42: ⚠️ Potential issue

두 번째 테스트 케이스도 업데이트 필요

마찬가지로 refresh 실패 테스트 케이스도 isPending 속성이 더 이상 존재하지 않는 것으로 보이기 때문에 수정이 필요합니다.

 test('refresh 요청이 실해하면 accessToken을 초기화하지 않고 isPending을 false로 설정한다', async () => {
   mswServer.use(
     http.post(`${BASE_URL}/${END_POINTS.AUTH}/refresh`, () => {
       return mswResponse({
         status: 400,
         error: getErrorResponse('INVALID_REQUEST'),
       })
     }),
   )

   const { result } = renderHook(() => useInitToken())

-  expect(result.current.isPending).toBe(true)
-  await waitFor(() => expect(result.current.isPending).toBe(false))
+  // 변경된 useInitToken 훅 인터페이스에 맞게 테스트 케이스 수정 필요
+  // 예: 비동기 요청 완료를 확인하는 다른 방법 사용
+  await waitFor(() => {/* 적절한 완료 조건 */})
   expect(useAuthStore.getState().setAccessToken).not.toHaveBeenCalled()
 })
🧰 Tools
🪛 GitHub Check: test

[failure] 39-39: src/hooks/test/useInitToken.test.ts > useInitToken 훅 테스트 > refresh 요청이 실해하면 accessToken을 초기화하지 않고 isPending을 false로 설정한다
TypeError: Cannot read properties of undefined (reading 'isPending')
❯ src/hooks/test/useInitToken.test.ts:39:27

🪛 GitHub Actions: Test

[error] 39-39: Cannot read properties of undefined (reading 'isPending')


10-43: 🛠️ Refactor suggestion

테스트 설명 및 이름 업데이트 필요

테스트 함수 이름과 설명에 isPending에 대한 언급이 있습니다. 하지만 useInitToken 훅의 인터페이스가 변경되어 더 이상 isPending을 반환하지 않는 것으로 보입니다. 테스트 이름과 설명을 현재 훅의 기능에 맞게 업데이트해야 합니다.

-test('refresh 요청이 성공하면 accessToken을 초기화하고 isPending을 false로 설정한다', async () => {
+test('refresh 요청이 성공하면 accessToken을 초기화한다', async () => {
   // 테스트 구현...
 })

-test('refresh 요청이 실해하면 accessToken을 초기화하지 않고 isPending을 false로 설정한다', async () => {
+test('refresh 요청이 실패하면 accessToken을 초기화하지 않는다', async () => {
   // 테스트 구현...
 })

또한 "실해하면"은 "실패하면"의 오타로 보입니다. 수정이 필요합니다.

🧰 Tools
🪛 GitHub Check: test

[failure] 20-20: src/hooks/test/useInitToken.test.ts > useInitToken 훅 테스트 > refresh 요청이 성공하면 accessToken을 초기화하고 isPending을 false로 설정한다
TypeError: Cannot read properties of undefined (reading 'isPending')
❯ src/hooks/test/useInitToken.test.ts:20:27


[failure] 39-39: src/hooks/test/useInitToken.test.ts > useInitToken 훅 테스트 > refresh 요청이 실해하면 accessToken을 초기화하지 않고 isPending을 false로 설정한다
TypeError: Cannot read properties of undefined (reading 'isPending')
❯ src/hooks/test/useInitToken.test.ts:39:27

🪛 GitHub Actions: Test

[error] 20-20: Cannot read properties of undefined (reading 'isPending')


[error] 39-39: Cannot read properties of undefined (reading 'isPending')

src/components/layout/UserLayout.test.tsx (1)

31-37: 💡 Verification agent

❓ Verification inconclusive

파이프라인 오류를 조사해 보세요.
screen.getByTestId('test-login-page')를 찾지 못하는 문제로 보아, 인증 정보 변경 이후에 라우팅이나 컴포넌트가 적절히 다시 렌더링되지 않았을 수 있습니다.

다음 스크립트를 통해 테스트가 실패하는 정확한 이유를 확인한 뒤, 라우팅 변경이나 상태 업데이트 시점 등을 점검해 보세요:


🏁 Script executed:

#!/bin/bash
# 테스트 실패에 대한 원인 파악을 위해 대상 테스트만 단독 실행
# Vitest 또는 Jest를 사용하신다면, 특정 테스트 파일만 실행할 수 있습니다.
# 예: npx vitest run src/components/layout/UserLayout.test.tsx
npx vitest run src/components/layout/UserLayout.test.tsx

Length of output: 933


파이프라인 및 환경 구성 문제 확인 필요

  • 실행한 스크립트 결과, 테스트 환경에서 vitest 패키지를 찾지 못하는 설정 오류가 발생했습니다. 이는 라우팅이나 컴포넌트 재렌더링 문제와 별개로, 테스트 실행 환경 자체가 올바르게 구성되지 않았음을 의미합니다.
  • 우선 vite.config.ts와 테스트 실행에 필요한 의존성(특히 vitest)이 제대로 설치되어 있는지 확인 및 수정해 주세요.
  • 환경 설정이 정상화된 이후, 인증 상태 변경 후 컴포넌트가 올바르게 렌더링되는지 재검증해 보시기 바랍니다.
🧰 Tools
🪛 GitHub Check: test

[failure] 36-36: src/components/layout/UserLayout.test.tsx > UserLayout 컴포넌트 테스트 > 인증되지 않은 상태에서 로그인 페이지로 리다이렉트 된다
TestingLibraryElementError: Unable to find an element by: [data-testid="test-login-page"]

Ignored nodes: comments, script, style

src/components/layout/VisitorLayout.test.tsx (1)

39-41: 테스트 설명 업데이트 필요

39줄의 테스트 설명에서 여전히 'Outlet'을 언급하고 있지만, 이제는 VisitorLayout 컴포넌트를 테스트하고 있습니다.

-it('인증되지 않은 상태에서는 Outlet이 올바르게 렌더링된다', () => {
+it('인증되지 않은 상태에서는 VisitorLayout 내부의 Outlet이 올바르게 렌더링된다', () => {
server/main.ts (1)

45-58: HTML 요청에 대한 인증 로직 추가가 적절합니다.
HTML 요청(text/html)이면서 /api/ 주소가 아닌 경우에만 authMiddleware를 적용하여 일반 페이지에 대한 접근 제어가 가능해졌습니다. 다만, 향후 SSR 라우팅에 미들웨어가 예상치 못한 영향을 주지 않도록 주기적인 테스트가 필요합니다.

src/App.tsx (1)

13-13: useInitToken 훅 호출 위치 확인
App 컴포넌트 내에서 바로 호출함으로써, 마운트 시 토큰 초기화가 처리됩니다. 렌더링 차질이 없는지 확인해 주세요.

server/middlewares/authMiddleware.ts (1)

5-10: isProtectedRoute 함수의 단순화 가능성
현재 some 메서드를 통해 특정 URL을 보호 대상으로 판단하고 있습니다. 추후 라우트 패턴이 복잡해지면 정규식이나 별도 매핑 로직을 고려해 보셔도 좋겠습니다.

src/routes/routes.tsx (1)

5-5: 전역 Error 객체 이름 충돌 주의

Error 컴포넌트 이름이 JavaScript 전역 Error 객체와 충돌할 가능성이 있습니다. 정적 분석 도구에서도 이 문제를 지적하고 있습니다. 컴포넌트 이름을 ErrorPage, ErrorView 또는 ErrorComponent와 같이 변경하는 것이 좋습니다.

🧰 Tools
🪛 Biome (1.9.4)

[error] 5-5: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fb7968d and d0d9ddd.

📒 Files selected for processing (33)
  • README.md (1 hunks)
  • server/entry.tsx (1 hunks)
  • server/main.ts (4 hunks)
  • server/middlewares/authMiddleware.ts (1 hunks)
  • server/routes/auth/route.ts (1 hunks)
  • src/App.tsx (1 hunks)
  • src/apis/apiClient.ts (2 hunks)
  • src/components/Layout/index.tsx (0 hunks)
  • src/components/VisitorOutlet/index.tsx (0 hunks)
  • src/components/layout/Footer.test.tsx (1 hunks)
  • src/components/layout/Footer.tsx (1 hunks)
  • src/components/layout/UserLayout.test.tsx (1 hunks)
  • src/components/layout/UserLayout.tsx (1 hunks)
  • src/components/layout/VisitorLayout.test.tsx (1 hunks)
  • src/components/layout/VisitorLayout.tsx (1 hunks)
  • src/contexts/QueryProvider/index.tsx (1 hunks)
  • src/hooks/__test__/useInitToken.test.ts (1 hunks)
  • src/hooks/useInitToken.ts (2 hunks)
  • src/main.tsx (1 hunks)
  • src/pages/Chat/index.tsx (1 hunks)
  • src/pages/Friend/index.tsx (1 hunks)
  • src/pages/FriendFind/index.tsx (1 hunks)
  • src/pages/Home/Home.test.tsx (1 hunks)
  • src/pages/Home/index.tsx (1 hunks)
  • src/pages/Login/Login.test.tsx (1 hunks)
  • src/pages/Login/index.tsx (1 hunks)
  • src/pages/Register/Register.test.tsx (1 hunks)
  • src/pages/Register/index.tsx (1 hunks)
  • src/queries/auth/useLoginMutation.ts (1 hunks)
  • src/queries/auth/useRegisterMutation.ts (1 hunks)
  • src/routes/path.ts (1 hunks)
  • src/routes/routes.tsx (4 hunks)
  • src/stores/authStore.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • src/components/Layout/index.tsx
  • src/components/VisitorOutlet/index.tsx
🧰 Additional context used
🧬 Code Definitions (5)
src/components/layout/VisitorLayout.tsx (2)
src/stores/authStore.ts (1)
  • useAuthStore (12-28)
src/routes/path.ts (1)
  • PATH (1-14)
src/apis/apiClient.ts (2)
src/stores/authStore.ts (1)
  • useAuthStore (12-28)
server/routes/path.ts (2)
  • API_URL (2-3)
  • END_POINTS (5-10)
src/App.tsx (1)
src/hooks/useInitToken.ts (1)
  • useInitToken (5-22)
server/main.ts (1)
server/middlewares/authMiddleware.ts (1)
  • authMiddleware (13-52)
src/routes/routes.tsx (2)
src/components/layout/VisitorLayout.tsx (1)
  • VisitorLayout (6-21)
src/components/layout/UserLayout.tsx (1)
  • UserLayout (6-18)
🪛 GitHub Actions: Test
src/pages/Register/Register.test.tsx

[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

src/pages/Login/Login.test.tsx

[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

src/pages/Home/Home.test.tsx

[error] 51-51: expected "spy" to be called with arguments: [ '/chat', { replace: true } ]

src/hooks/__test__/useInitToken.test.ts

[error] 20-20: Cannot read properties of undefined (reading 'isPending')


[error] 39-39: Cannot read properties of undefined (reading 'isPending')

src/components/layout/UserLayout.test.tsx

[error] 36-36: Unable to find an element by: [data-testid="test-login-page"]

🪛 Biome (1.9.4)
src/routes/routes.tsx

[error] 5-5: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (49)
server/entry.tsx (1)

10-10: 절대 경로 사용 검토
기존 상대 경로('../src/routes')에서 절대 경로('#routes/routes.tsx')로 임포트 경로가 변경되었습니다. 다른 모듈들과 일관성이 유지되는지, 그리고 해당 경로가 올바르게 해석되는지 재확인 부탁드립니다.

src/queries/auth/useLoginMutation.ts (1)

9-10: 라우트 경로 업데이트 확인
PATH 변수의 임포트 경로가 #routes/path.ts로 변경되었습니다. 이 변경으로 인해 navigate(PATH.CHAT, { replace: true })가 의도한 대로 작동하는지 추가 테스트해주시기 바랍니다.

src/queries/auth/useRegisterMutation.ts (1)

8-9: 라우트 경로 변경 점검
PATH 모듈의 경로가 #routes/path.ts로 업데이트되었습니다. 이 변경이 어플리케이션 전반의 라우팅 로직과 일관되게 통합되어 있는지 확인해주세요.

src/components/layout/Footer.test.tsx (1)

6-6: 테스트 파일 내 경로 업데이트 검증
테스트 파일에서도 PATH의 임포트 경로가 #routes/path.ts로 변경되었습니다. 변경된 경로가 테스트 케이스에 문제없이 반영되는지 확인 부탁드립니다.

src/components/layout/Footer.tsx (1)

6-6: PATH 임포트 경로 구조 개선

경로 상수를 별도의 path.ts 파일로 분리한 것은 코드 구조를 개선하는 좋은 리팩토링입니다. 이렇게 하면 경로 정의를 중앙화하여 유지보수성을 높이고 일관성을 보장할 수 있습니다.

src/stores/authStore.ts (1)

9-9: logout 메서드 타입 시그니처 수정

logout 메서드의 반환 타입을 void에서 Promise<void>로 변경한 것은 비동기 구현과 일치시키는 올바른 접근입니다. 이제 이 메서드를 사용하는 쪽에서 await를 통해 적절히 처리할 수 있게 되었습니다.

src/pages/Login/Login.test.tsx (1)

9-9:

Details

❓ Verification inconclusive

PATH 임포트 경로 업데이트 및 파이프라인 오류

경로 상수를 #routes/path.ts로 분리한 리팩토링은 좋은 변화입니다. 그러나 파이프라인 실패 로그에 따르면 컴포넌트 임포트와 관련된 오류가 발생하고 있습니다.

오류 메시지: "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined."

이는 다음과 같은 원인이 있을 수 있습니다:

  1. 컴포넌트가 소스 파일에서 올바르게 내보내지지 않음
  2. 기본 내보내기와 명명된 내보내기/임포트 간의 불일치
  3. 임포트 경로가 잘못됨

이 문제를 해결하기 위해 관련 컴포넌트 파일들을 확인해 보세요:


🏁 Script executed:

#!/bin/bash
# 임포트 문제가 있는 컴포넌트 파일 확인
echo "1. 경로 관련 파일 확인:"
cat src/routes/path.ts || echo "path.ts 파일이 없습니다"
echo "\n2. 이전 경로 파일 확인:"
cat src/routes.tsx || echo "routes.tsx 파일이 없습니다"
echo "\n3. 경로 사용 패턴 확인:"
grep -r "import { PATH }" src/ --include="*.tsx" --include="*.ts" | head -n 10

Length of output: 1425


경로 상수 업데이트 검증 및 추가 확인 필요

  • src/routes/path.ts 파일이 존재하며, 올바르게 export const PATH = { ... } 방식으로 상수를 내보내고 있음을 확인했습니다.
  • 이전 경로 파일인 src/routes.tsx는 더 이상 존재하지 않아, 경로 리팩토링이 올바르게 반영된 것으로 보입니다.
  • 전체 코드베이스에서 import { PATH } from '#routes/path.ts' 구문이 일관되게 사용되고 있어 임포트 경로 관련 문제는 해결된 것으로 확인됩니다.
  • 파이프라인 오류 메시지 "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined."는 PATH 상수 자체와는 직접적인 연관이 없어 보입니다. 해당 오류는 컴포넌트의 내보내기 방식(명명된 내보내기/기본 내보내기) 문제일 가능성이 있으므로, 관련 컴포넌트의 export 방식이 올바른지 함께 검토해 주시기 바랍니다.
src/pages/Chat/index.tsx (1)

9-16: 비동기 로그아웃 처리 개선을 잘 구현하셨습니다!

로그아웃 함수를 비동기적으로 처리하고 await를 사용하여 완료된 후에만 페이지를 새로고침하도록 수정한 것은 매우 좋은 변경사항입니다. 이렇게 하면 로그아웃 프로세스가 완전히 완료되기 전에 페이지가 새로고침되는 잠재적인 문제를 방지할 수 있습니다.

src/pages/Register/index.tsx (1)

13-13: 라우팅 구조 개선이 잘 적용되었습니다.

PATH 상수의 import 경로를 #routes.tsx에서 #routes/path.ts로 변경한 것은 코드 구조를 개선하는 좋은 변화입니다. 이렇게 함으로써 라우트 경로 정의와 라우트 구성을 분리하고, 경로 상수를 한 곳에 집중시켜 유지보수성을 높였습니다.

src/main.tsx (1)

6-6: 라우팅 모듈의 구조 개선이 일관되게 적용되었습니다.

라우트 import 경로를 ./routes.tsx에서 ./routes/routes.tsx로 변경한 것은 전체적인 라우팅 시스템 재구성의 일부로 잘 적용되었습니다. 이러한 구조 변경은 코드의 조직화를 개선하고, 관심사의 분리를 명확히 하며, 애플리케이션이 성장함에 따라 유지보수성을 향상시킵니다.

src/pages/Login/index.tsx (1)

13-13: 라우팅 구조 변경이 일관성 있게 적용되었습니다.

PATH 상수의 import 경로를 #routes.tsx에서 #routes/path.ts로 변경한 점은 Register 컴포넌트와 동일하게 적용되었습니다. 이는 전체 코드베이스에서 일관된 방식으로 경로 상수를 가져오도록 하여 코드의 일관성과 가독성을 향상시켰습니다.

src/pages/Home/Home.test.tsx (2)

9-9: import 경로 변경이 적절하게 이루어졌습니다.

routes 모듈에서 PATH를 별도 파일로 분리하여 조직화한 것은 좋은 변경입니다. 이렇게 하면 라우팅 관련 상수를 더 명확하게 관리할 수 있습니다.


51-51:

Details

❓ Verification inconclusive

테스트 실패 해결 필요: PATH.CHAT 값 검증이 필요합니다.

파이프라인 실패 로그에 따르면 이 테스트에서 mockNavigate[ '/chat', { replace: true } ] 인수로 호출될 것으로 예상했으나 실제로는 다른 값이 전달되고 있습니다. PATH.CHAT의 값이 변경되었거나 다른 경로로 리다이렉트되고 있을 수 있습니다.

경로 값을 확인하기 위해 아래 스크립트를 실행해 보시기 바랍니다:


🏁 Script executed:

#!/bin/bash
# src/routes/path.ts 파일에서 PATH.CHAT 값 확인
cat src/routes/path.ts

Length of output: 370


검증 결과: PATH.CHAT 값은 예상대로 /chat으로 정의되어 있습니다.
파이프라인 실패 로그에서 지적한 문제는 PATH 정의의 문제가 아니라, 테스트 대상 코드에서 mockNavigate가 올바른 인수를 전달하고 있지 않음을 의미하는 것으로 보입니다. 즉, 현재 코드에서는 mockNavigate 호출 시 예상과 다른 인수가 전달되고 있어, 리다이렉트 경로가 변경되었거나 다른 로직 문제일 가능성이 높습니다.

  • 확인 사항:
    • src/routes/path.ts 파일 내 PATH 정의가 올바릅니다.
    • 실제 mockNavigate 호출부가 PATH.CHAT를 사용하지 않거나, 다른 인수를 전달하는지 코드 검토가 필요합니다.

테스트 실패 원인이 PATH 정의 자체가 아니라 호출부 로직에 있을 가능성이 있으므로, 해당 테스트 케이스와 실제 리다이렉트 로직을 다시 점검해 주시기 바랍니다.

🧰 Tools
🪛 GitHub Check: test

[failure] 51-51: src/pages/Home/Home.test.tsx > Home 페이지 기능 테스트 > 인증 상태가 true일 때 채팅 페이지로 리다이렉트한다
AssertionError: expected "spy" to be called with arguments: [ '/chat', { replace: true } ]

Received:

Number of calls: 0

❯ src/pages/Home/Home.test.tsx:51:26

🪛 GitHub Actions: Test

[error] 51-51: expected "spy" to be called with arguments: [ '/chat', { replace: true } ]

src/components/layout/UserLayout.tsx (2)

1-18: 사용자 레이아웃 구조가 잘 설계되었습니다.

UserLayout 컴포넌트가 Header, main content 영역, Footer를 포함하는 명확한 구조로 잘 구현되었습니다. Outlet을 사용하여 중첩된 라우트의 내용을 표시하는 방식도 적절합니다. useLocation을 통해 가져온 pathname을 Footer에 전달하여 현재 경로에 따른 동적 표시를 가능하게 한 점도 좋은 설계입니다.


12-12: 현대적인 CSS 사용이 적절합니다.

h-[calc(100dvh-7.5rem)]에서 dvh 단위를 사용하여 모바일 기기의 동적 뷰포트 높이를 정확하게 계산한 것은 좋은 접근입니다. 또한 overflow-y: auto를 적용하여 내용이 넘칠 경우 스크롤이 생기도록 한 점도 사용자 경험을 향상시킵니다.

src/components/layout/VisitorLayout.tsx (3)

1-21: 방문자 레이아웃 컴포넌트의 구조와 인증 처리가 잘 구현되었습니다.

VisitorLayout 컴포넌트가 인증되지 않은 사용자를 위한 레이아웃을 적절하게 처리하고 있습니다. 인증 상태를 확인하여 인증된 사용자를 리다이렉트하는 로직이 잘 구현되었습니다. Outlet을 사용하여 중첩된 라우트의 내용을 표시하는 방식도 적절합니다.


11-12: URL 검색 매개변수를 활용한 리다이렉트 처리가 좋습니다.

URL 검색 매개변수에서 리다이렉트 URL을 추출하고, 없을 경우 기본값으로 PATH.CHAT을 사용하는 방식은 유연한 네비게이션 처리를 가능하게 합니다. 이는 사용자 경험을 향상시키는 좋은 패턴입니다.


14-18: useEffect의 의존성 배열이 정확합니다.

useEffect에 isAuthenticated, navigate, redirectUrl을 의존성 배열에 포함시켜 이 값들이 변경될 때만 효과가 실행되도록 한 것은 좋은 구현입니다. 이는 불필요한 리다이렉트를 방지하고 성능을 최적화합니다.

src/pages/Register/Register.test.tsx (3)

10-10: import 경로 변경이 적절하게 이루어졌습니다.

routes 모듈에서 PATH를 별도 파일로 분리하여 조직화한 것은 좋은 변경입니다. 이는 다른 파일에서의 변경과 일관성을 유지합니다.


62-62: PATH.CHAT 값 검증이 필요합니다.

성공적인 회원가입 후 사용자가 PATH.CHAT으로 리다이렉트되는 테스트에서, PATH.CHAT의 실제 값이 테스트 기대값과 일치하는지 확인해야 합니다. Home.test.tsx에서도 유사한 이슈가 발견되었습니다.


1-86:

Details

❓ Verification inconclusive

컴포넌트 import/export 오류를 해결해야 합니다.

파이프라인 실패 로그에 따르면 "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined" 오류가 발생하고 있습니다. 이는 컴포넌트가 undefined로 평가되어 렌더링할 수 없다는 의미입니다.

다음 사항을 확인해 보세요:

  1. Register 컴포넌트가 제대로 export되었는지 확인
  2. 관련 컴포넌트들의 import/export 구문이 올바른지 확인
  3. default export와 named export가 혼합되어 사용되지 않았는지 확인

컴포넌트 구조를 확인하기 위해 아래 스크립트를 실행해 보세요:


🏁 Script executed:

#!/bin/bash
# Register 컴포넌트 파일 확인
cat src/pages/Register/index.tsx

Length of output: 3524


컴포넌트 Export 검증 결과 및 추가 확인 요청

Register 페이지의 컴포넌트 파일(src/pages/Register/index.tsx)을 확인한 결과, 기본(default) export가 올바르게 처리되어 있음을 확인했습니다. 테스트 파일(src/pages/Register/Register.test.tsx)에서의 import도 정상적으로 이루어지고 있음을 확인하였습니다.

다만, 파이프라인에서 발생한 “Element type is invalid … got: undefined” 오류는 해당 컴포넌트 외 다른 의존 컴포넌트(예: #components/_common/Button, #components/_common/Input, #components/_common/Label, #components/_common/ErrorMessage)나 경로 alias 설정, 혹은 react-router 관련 import 설정 문제에서 기인할 수 있습니다. 아래 사항들을 추가로 확인해 보시기 바랍니다:

  • 의존 컴포넌트 export 확인:

    • #components/_common/Button, Input, Label, ErrorMessage 등 해당 컴포넌트들이 올바르게 export 되었는지 확인
    • 각 컴포넌트의 import 구문과 사용법이 일치하는지 검토
  • 경로 alias 설정 점검:

    • #components/_common/와 같이 사용하는 alias가 올바르게 설정되어 있는지 확인
  • React Router 관련 확인:

    • 현재 useNavigatereact-router에서 import하고 있는데, 필요시 react-router-dom 사용 여부도 점검

위 사항들을 확인 후, 문제의 원인에 따른 수정이 필요하다면 적절한 조치를 취해주시기 바랍니다.

🧰 Tools
🪛 GitHub Actions: Test

[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.


[error] 1-1: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

src/routes/path.ts (2)

1-14: 라우트 경로 상수화 구현이 잘 되었습니다.

경로를 상수로 관리하는 방식이 잘 구현되었습니다. 경로를 하드코딩하는 대신 이런 방식으로 관리하면 경로 변경 시 한 곳만 수정하면 되어 유지보수성이 크게 향상됩니다. 또한 chatRoom 함수를 통해 동적 세그먼트가 있는 경로를 생성하는 방식도 좋습니다.

as const를 사용하여 객체를 불변으로 만든 것도 타입 안전성을 높이는 좋은 방법입니다.


16-17: 보호된 라우트 분리가 효과적입니다.

인증이 필요한 라우트를 별도의 배열로 분리한 접근 방식이 좋습니다. 이를 통해 인증 미들웨어에서 쉽게 참조할 수 있으며, 보호된 라우트 목록을 한 곳에서 관리할 수 있습니다.

src/pages/Friend/index.tsx (1)

5-8: 임포트 경로 업데이트가 적절합니다.

임포트 경로가 업데이트되어 이제 상대 경로와 새로운 경로 모듈을 사용하고 있습니다. 이는 코드베이스의 구조 변경을 반영하는 좋은 변화입니다.

특히 UserCard 컴포넌트를 src/components/domain/UserCard에서 가져오고 PATH#routes/path.ts에서 가져오는 것은 컴포넌트와 라우트의 조직적인 구조화를 보여줍니다.

src/hooks/useInitToken.ts (3)

2-2: 임포트 간소화가 적절합니다.

useState 훅이 더 이상 사용되지 않아 임포트에서 제거된 것이 적절합니다. 사용하지 않는 임포트를 제거하는 것은 코드 정리에 도움이 됩니다.


5-5: export 방식 변경이 적절합니다.

기본 내보내기(default export)에서 명명된 내보내기(named export)로 변경된 것은 일관된 모듈 패턴을 따르는 좋은 접근입니다. 이는 다른 파일들에서도 동일하게 적용된 패턴으로 보입니다.


18-20: 비동기 처리가 간소화되었습니다.

이전 코드에서는 isPending 상태를 사용하여 초기화 진행 상태를 추적했지만, 이제는 간소화되었습니다. 이는 컴포넌트 렌더링 차단 없이 토큰을 초기화하는 좋은 접근법입니다.

다만 // noinspection JSIgnoredPromiseFromCall 주석은 무시된 프로미스 경고를 방지하기 위한 것으로 보입니다. 이상적으로는 프로미스를 적절히 처리하는 것이 좋지만, 이 경우에는 초기화 프로세스가 UI에 영향을 주지 않도록 하는 의도가 분명해 보입니다.

src/contexts/QueryProvider/index.tsx (1)

26-26: export 방식 변경이 일관성 있습니다.

기본 내보내기(default export)에서 명명된 내보내기(named export)로 변경된 것은 프로젝트 전체의 일관된 패턴을 따르는 좋은 변화입니다. 이는 다른 파일들(예: useInitToken.ts)에서도 동일하게 적용된 패턴으로 보입니다.

명명된 내보내기를 사용하면 IDE의 자동 완성 기능이 더 효과적으로 작동하고, 임포트 시 오타의 가능성을 줄일 수 있습니다. 또한 한 파일에서 여러 항목을 내보낼 때도 일관된 방식을 유지할 수 있어 좋습니다.

src/pages/Home/index.tsx (2)

6-6: import 경로 변경

PATH의 import 경로가 '#routes.tsx'에서 '#routes/path.ts'로 변경되었습니다. 이는 라우팅 구조의 재구성을 반영하며, 프로젝트 전체적으로 일관성 있게 적용되어야 합니다.


8-61: 인증 관련 리다이렉션 로직 제거

이전에 있던 useEffect와 useAuthStore를 사용한 인증 확인 및 리다이렉션 로직이 제거되었습니다. 이는 아마도 라우팅 구조의 변경으로 인해 인증 확인 로직이 다른 곳으로 이동되었기 때문일 것입니다.

인증 로직이 제거되었으니, 이제 이 컴포넌트는 인증 여부와 상관없이 항상 같은 내용을 렌더링합니다. 다른 곳(예: 라우터 구성, 레이아웃 컴포넌트 등)에서 인증 관련 리다이렉션을 처리하고 있는지 확인하는 것이 좋습니다.

src/components/layout/VisitorLayout.test.tsx (2)

5-8: 임포트 경로 및 컴포넌트 업데이트

임포트 경로와 컴포넌트 이름이 업데이트되었습니다:

  1. useAuthStore 임포트에 .ts 확장자 추가
  2. VisitorOutlet 대신 VisitorLayout 컴포넌트 사용
  3. PATH 임포트 경로 변경됨

이 변경은 프로젝트 구조의 전반적인 재구성과 일치합니다.


16-16: 컴포넌트 변경

VisitorOutlet에서 VisitorLayout으로 컴포넌트가 변경되었습니다. 이는 프로젝트 내 레이아웃 구조 변경의 일부로 보입니다.

src/components/layout/UserLayout.test.tsx (3)

7-8: import문 경로가 잘 변경되었습니다.
사용하려는 컴포넌트와 상수(PATH)를 정상적으로 가리키고 있는지 다시 한번 확인해 주시면 좋겠습니다.


10-10: 테스트 설명을 명확하게 바꾸셨네요.
UserLayout 컴포넌트에 맞춰 테스트 설명을 잘 변경하셨습니다. 명확한 테스트 목적을 드러내고 있어 좋습니다.


16-16: 라우트 요소 설정이 합리적으로 보입니다.
새로 import한 UserLayout<Route element={…}>로 설정하여, 자식 라우트에 대해 일관된 레이아웃이 적용될 것으로 보입니다.

server/main.ts (2)

13-13: 신규 인증 미들웨어 import 확인
authMiddleware를 올바르게 import하고 있으므로, 충돌이나 오타가 없는지 최종적으로 점검해 주세요.


116-116: 에러 로깅을 추가하셨습니다.
console에 에러를 출력할 때, 민감한 정보를 로깅하지 않도록 주의해 주세요. 필요하다면 에러 내용을 일부 마스킹하거나 상세 내용은 디버그 모드에서만 노출하도록 설계하는 것이 좋습니다.

src/App.tsx (2)

5-5: useInitToken 훅 import를 명시적으로 바꾸셨네요.
named export로 변경되어 import도 맞춰서 수정하신 점이 좋습니다.


7-7: QueryProvider import도 명시적 변경이 잘 되었습니다.
Context provider 사용 시, named export 방식을 통해 가독성을 높일 수 있습니다.

server/middlewares/authMiddleware.ts (2)

1-3: 주요 의존성 import가 적절해 보입니다.
FastifyRequest, FastifyReply, 그리고 TokenService를 사용한 미들웨어 구성이 자연스럽습니다.


12-52: SSR 환경에서의 토큰 검증 흐름이 타당합니다.

  1. isProtectedRoute를 통해 보호된 라우트인지 판별
  2. 쿠키의 refreshToken 서명 검증
  3. 토큰 검증 실패 시 쿠키 제거 후 로그인 페이지로 리다이렉트

SSR 렌더링을 고려하는 환경에서도 상당히 자연스러운 흐름이며, 명시적 리다이렉트 코드를 통해 즉시 응답을 종료하므로 안정적입니다. 향후 쿠키 이름이나 경로 등이 변경될 경우 충돌 방지 차원에서 상수를 한 군데서 관리해도 좋겠습니다.

src/apis/apiClient.ts (4)

6-7: 토큰 리프레시 요청 중복 방지를 위한 효과적인 패턴 구현!

refreshTokenPromise 변수를 통해 동시에 여러 토큰 리프레시 요청이 발생하는 것을 효과적으로 방지하고 있습니다. 이는 동시성 문제를 해결하고 불필요한 네트워크 요청을 줄이는 좋은 패턴입니다.


8-23: 토큰 리프레시 로직 분리 및 에러 처리가 잘 구현되었습니다!

토큰 리프레시 로직을 별도의 함수로 분리하여 관심사 분리가 잘 되었습니다. 특히:

  1. Zustand 스토어를 컴포넌트 외부에서 접근할 때 getState()를 올바르게 사용
  2. API 요청 후 적절하게 상태 업데이트
  3. finally 블록을 통해 성공/실패 여부와 관계없이 refreshTokenPromise 변수를 초기화하여 다음 리프레시 요청이 가능하도록 처리

이러한 구현은 인증 토큰 관리의 안정성과 신뢰성을 높여줍니다.


34-37: 동시 토큰 리프레시 요청 방지 로직이 효과적으로 개선되었습니다!

기존의 인라인 토큰 리프레시 로직을 개선하여:

  1. 이미 진행 중인 리프레시 요청이 있는지 확인
  2. 없으면 새로운 리프레시 요청 시작
  3. 있으면 기존 요청의 프로미스를 재사용
  4. 항상 토큰 리프레시가 완료될 때까지 대기

이 접근 방식은 동시성 문제를 효과적으로 해결하고 코드 유지보수성을 높입니다.


45-45: 로그아웃 프로세스 완료 보장을 위한 비동기 처리 적용!

logout 함수를 await로 처리하여 로그아웃 프로세스가 완전히 완료될 때까지 기다리도록 수정했습니다. 이는 로그아웃 과정에서 API 요청이나 상태 변경과 같은 비동기 작업이 모두 완료된 후에 다음 코드가 실행되도록 보장하여 상태 불일치 문제를 방지합니다.

src/routes/routes.tsx (4)

3-3: App 컴포넌트 import 경로 업데이트

App 컴포넌트의 import 경로가 상대 경로로 변경되었습니다. 이는 프로젝트 구조 개선의 일환으로 보입니다. 파일 확장자(.tsx)를 명시적으로 포함하는 것은 일부 번들러 설정이나 ESM 호환성에 도움이 될 수 있습니다.


7-8: 레이아웃 컴포넌트 구조 개선 및 의미있는 이름 변경

레이아웃 관련 컴포넌트의 import가 개선되었습니다:

  1. VisitorOutlet에서 VisitorLayout으로, Layout에서 UserLayout으로 이름이 변경되어 더 명확한 의미 전달
  2. 전용 #components/layout/ 경로를 사용하여 컴포넌트 조직 구조 개선
  3. 경로 별칭(#)을 사용하여 import 일관성 향상

이러한 변경은 코드베이스의 구조와 가독성을 크게 향상시킵니다.


20-20: 라우트 경로 정의의 중앙화로 유지보수성 향상

PATH 상수를 별도의 모듈(#routes/path.ts)로 분리한 것은 다음과 같은 이점이 있습니다:

  1. 경로 정의 중앙화로 유지보수 용이성 증가
  2. 코드 중복 없이 여러 파일에서 경로 재사용 가능
  3. 경로 일관성 보장
  4. routes.tsx 파일의 복잡도 감소

이는 라우팅 코드의 구조적 개선으로 볼 수 있습니다.


41-41: 라우팅 구조에서 레이아웃 컴포넌트 업데이트

라우팅 구조에서 레이아웃 컴포넌트 사용이 업데이트되었습니다. 새 컴포넌트 이름(VisitorLayout, UserLayout)은 이전 이름보다 더 의미적으로 명확하여 이 컴포넌트들이 단순한 outlet이 아닌 레이아웃 역할을 한다는 것을 분명히 나타냅니다.

Also applies to: 54-54

@GWjun GWjun merged commit 7593f83 into main Mar 29, 2025
3 checks passed
@GWjun GWjun deleted the refactor/token-blocking/#23 branch March 29, 2025 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common common job refactor refactoring code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

토큰 로직 재설정

1 participant