Skip to content

Conversation

@minkyung5x5
Copy link
Contributor

@minkyung5x5 minkyung5x5 commented Nov 14, 2024

🔖 Issue Ticket

Ticket

✍️ Description

�fetchAPI 수정
auth API 리팩토링

✅ Checklist

PR

  • Branch Convention 확인

    feat/ 피쳐, fix/ 버그 수정, refactor/ 개선

  • Base Branch 확인
  • 적절한 Label 지정
  • Assignee 및 Reviewer 지정

Test

  • 로컬 작동 확인

Summary by CodeRabbit

  • New Features

    • 사용자 인증을 위한 새로운 signuplogin 기능 추가.
    • 사용자 데이터를 가져오는 getUser 기능 추가.
    • 로그인 및 가입 프로세스를 관리하는 커스텀 훅 usePostLoginQueryusePostSignupQuery 추가.
    • 인증 성공 처리를 위한 useHandleAuthSuccess 훅 추가.
  • Bug Fixes

    • 인증 관련 함수 및 쿼리 구조 조정으로 인한 오류 수정.
  • Chores

    • 불필요한 인증 관련 파일 삭제 및 구조 개선.

@minkyung5x5 minkyung5x5 linked an issue Nov 14, 2024 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Nov 14, 2024

Walkthrough

이 변경 사항은 사용자 인증과 관련된 여러 기능을 포함하는 파일을 삭제하고, 새로운 파일에 새로운 기능을 추가하는 구조로 구성되어 있습니다. 기존의 signupUser, loginUser, getUser 함수가 삭제되었고, 각각의 기능이 새로운 파일에 signup, login, getUser 함수로 재구성되었습니다. 또한, React Query를 활용한 사용자 인증 관련 쿼리 훅도 새로 추가되었습니다.

Changes

파일 경로 변경 요약
src/_apis/auth/auth-apis.tsx signupUser, loginUser, getUser 함수 삭제
src/_apis/auth/login-apis.ts login 함수 추가: 로그인 요청을 처리하는 POST 요청을 수행
src/_apis/auth/signup-apis.ts signup 함수 추가: 사용자 가입 요청을 처리하는 POST 요청을 수행
src/_apis/auth/user-apis.ts getUser 함수 추가: 사용자 데이터를 가져오는 GET 요청을 수행
src/_queries/auth/auth-queries.tsx usePostSignupQuery, usePostLoginQuery, getUserQuery, useHandleAuthSuccess 함수 삭제
src/_queries/auth/login-queries.ts usePostLoginQuery 훅 추가: 로그인 요청을 처리
src/_queries/auth/signup-queries.ts usePostSignupQuery 훅 추가: 사용자 가입 요청을 처리
src/_queries/auth/use-handle-auth-success.ts useHandleAuthSuccess 훅 추가: 인증 성공 후 처리 로직 관리
src/_queries/auth/user-apis.ts getUserQuery 함수 추가: 사용자 데이터를 가져오는 쿼리 구성
src/app/(auth)/login/page.tsx usePostLoginQuery의 import 경로 수정
src/app/(auth)/signup/page.tsx usePostSignupQuery의 import 경로 수정
src/utils/api.ts fetchApi 함수에 isAuth 매개변수 추가 및 ApiError 클래스의 생성자 수정

Possibly related PRs

  • Feat/101/login signup api #106: 이 PR은 signupUserloginUser 함수의 수정과 관련이 있으며, 사용자 인증 프로세스와 관련된 기능을 다룹니다.
  • DetailPage api 연결 #114: 이 PR은 사용자 인증 및 데이터 검색과 상호작용할 가능성이 있는 세부 페이지를 위한 새로운 컴포넌트를 도입합니다.

Suggested labels

api, fix

Suggested reviewers

  • yulrang
  • HaeJungg
  • Rangbyeolang

Poem

🐇
인증의 길을 달리는 토끼,
새로워진 함수들로 기쁘게 뛰네.
가입과 로그인, 사용자 정보,
모두 함께 손잡고 나아가네!
🐾✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/_apis/auth/login-apis.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't determine the plugin "react-hooks" uniquely.

  • /node_modules/eslint-plugin-react-hooks/index.js (loaded in ".eslintrc.js")
  • /node_modules/eslint-config-next/node_modules/eslint-plugin-react-hooks/index.js (loaded in ".eslintrc.js » eslint-config-next/core-web-vitals » /node_modules/eslint-config-next/index.js » plugin:react-hooks/recommended")

Please remove the "plugins" setting from either config or remove either plugin installation.

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • 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 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

Copy link
Contributor

@yulrang yulrang left a comment

Choose a reason for hiding this comment

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

수고하셨습니다~!~!

Copy link
Contributor

@ChoYenii ChoYenii left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!

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

🧹 Outside diff range and nitpick comments (7)
src/_apis/auth/user-apis.ts (1)

4-11: API 구조 개선을 위한 제안

현재 독립적인 함수로 구현되어 있지만, 다음과 같은 구조적 개선을 고려해보시면 좋을 것 같습니다:

  1. AuthService 클래스로 래핑하여 관련 기능들을 그룹화
  2. 공통 설정(베이스 URL, 헤더 등)의 중앙화
  3. 응답 타입에 대한 인터페이스 정의

예시 구조:

interface AuthResponse<T> {
  data: T;
  status: number;
  message?: string;
}

class AuthService {
  private static instance: AuthService;
  
  private constructor() {}
  
  static getInstance(): AuthService {
    if (!AuthService.instance) {
      AuthService.instance = new AuthService();
    }
    return AuthService.instance;
  }

  async getUser(): Promise<AuthResponse<User>> {
    // 현재 구현 로직
  }
  
  // 추가 인증 관련 메서드들...
}
src/_queries/auth/user-apis.ts (1)

5-11: React Query 구성에 대한 개선 제안

현재 구현은 기본적인 기능을 잘 수행하고 있습니다. 하지만 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:

다음과 같이 추가 설정을 고려해보세요:

 export function getUserQuery() {
   return {
     queryKey: ['user'],
     queryFn: getUser,
     select: (data: User) => transformKeysToCamel(data),
+    retry: 1,
+    staleTime: 5 * 60 * 1000, // 5분
+    cacheTime: 30 * 60 * 1000, // 30분
+    onError: (error: Error) => {
+      console.error('사용자 정보를 가져오는데 실패했습니다:', error);
+    },
   };
 }

이러한 설정들은:

  • 네트워크 오류 시 재시도 횟수를 제한합니다
  • 불필요한 API 호출을 줄이기 위한 캐시 전략을 구현합니다
  • 오류 상황에 대한 처리를 추가합니다
src/_apis/auth/login-apis.ts (1)

14-14: 타임아웃 값을 환경 설정으로 관리하는 것이 좋습니다.

하드코딩된 타임아웃 값(5000ms)을 환경 변수나 설정 파일로 분리하여 관리하는 것을 추천드립니다.

+const API_TIMEOUT = process.env.API_TIMEOUT || 5000;
 export function login(data: LoginRequest): Promise<{ data: LoginResponse }> {
   return fetchApi<{ data: LoginResponse; headers: Headers }>(
     '/auths/login',
     {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: JSON.stringify(data),
     },
-    5000,
+    API_TIMEOUT,
     true,
   ).then((response) => {
src/_queries/auth/login-queries.ts (1)

7-16: 에러 처리와 로딩 상태 관리를 개선하면 좋을 것 같습니다.

현재 구현은 기본적인 기능은 잘 동작하겠지만, 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:

  1. 토큰 유효성 검증 로직 추가
  2. 에러 처리 강화
  3. 로딩 상태에 따른 UI 피드백 처리

다음과 같이 개선해보시는 건 어떨까요?:

 export function usePostLoginQuery() {
   const handleAuthSuccess = useHandleAuthSuccess();
 
   return useMutation<{ data: LoginResponse }, ApiError, LoginRequest>({
     mutationFn: login,
     onSuccess: async (response) => {
+      if (!response.data.token) {
+        throw new Error('토큰이 존재하지 않습니다.');
+      }
       await handleAuthSuccess(response.data.token);
     },
+    onError: (error: ApiError) => {
+      console.error('로그인 중 오류가 발생했습니다:', error.message);
+    }
   });
 }
src/_queries/auth/signup-queries.ts (1)

7-16: 회원가입 뮤테이션 구현이 깔끔합니다

React Query의 useMutation을 활용한 구현이 잘 되어있습니다. 특히:

  • 제네릭을 통한 타입 안전성 확보
  • 성공 시 토큰 처리 로직의 분리
  • 간결하고 목적이 명확한 코드

다만, 에러 처리를 위한 onError 콜백이 없는데, 추가하는 것을 고려해보시면 좋을 것 같습니다.

다음과 같이 에러 처리를 추가하는 것을 제안드립니다:

 export function usePostSignupQuery() {
   const handleAuthSuccess = useHandleAuthSuccess();

   return useMutation<{ data: SignupResponse }, ApiError, SignupRequest>({
     mutationFn: signup,
     onSuccess: async (response) => {
       await handleAuthSuccess(response.data.token);
     },
+    onError: (error: ApiError) => {
+      // 에러 처리 로직 추가
+      console.error('회원가입 실패:', error.message);
+    },
   });
 }
src/_queries/auth/use-handle-auth-success.ts (1)

1-4: 관련 임포트 그룹화 제안

임포트문을 다음과 같이 그룹화하면 코드의 구조를 더 명확하게 파악할 수 있습니다:

  1. 외부 라이브러리
  2. 내부 스토어
  3. 타입
  4. API 관련
 import { useQueryClient } from '@tanstack/react-query';
+
 import { useAuthStore } from '@/src/store/use-auth-store';
+
 import { User } from '@/src/types/auth';
 import { getUserQuery } from './user-apis';
src/app/(auth)/signup/page.tsx (1)

Line range hint 27-33: 타입 캐스팅 개선이 필요합니다

에러 처리 부분에서 key as 'email'와 같은 타입 캐스팅이 모든 가능한 필드를 고려하지 않고 있습니다. 이는 잠재적인 타입 안전성 문제를 야기할 수 있습니다.

다음과 같이 수정하는 것을 제안합니다:

-setError(key as 'email', {
+setError(key as keyof SignupFormValues, {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 0b23703 and 7c600df.

📒 Files selected for processing (12)
  • src/_apis/auth/auth-apis.tsx (0 hunks)
  • src/_apis/auth/login-apis.ts (1 hunks)
  • src/_apis/auth/signup-apis.ts (1 hunks)
  • src/_apis/auth/user-apis.ts (1 hunks)
  • src/_queries/auth/auth-queries.tsx (0 hunks)
  • src/_queries/auth/login-queries.ts (1 hunks)
  • src/_queries/auth/signup-queries.ts (1 hunks)
  • src/_queries/auth/use-handle-auth-success.ts (1 hunks)
  • src/_queries/auth/user-apis.ts (1 hunks)
  • src/app/(auth)/login/page.tsx (1 hunks)
  • src/app/(auth)/signup/page.tsx (1 hunks)
  • src/utils/api.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • src/_apis/auth/auth-apis.tsx
  • src/_queries/auth/auth-queries.tsx
🔇 Additional comments (17)
src/_apis/auth/user-apis.ts (2)

1-2: 임포트 구문이 적절합니다!

필요한 유틸리티와 타입이 올바르게 임포트되어 있습니다.


4-11: 🛠️ Refactor suggestion

에러 처리와 응답 유효성 검사가 필요합니다.

현재 구현에서 다음 사항들을 고려해야 합니다:

  1. API 호출 실패 시의 에러 처리
  2. 응답 데이터의 유효성 검사
  3. 인증 토큰 처리 방식

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

 export function getUser(): Promise<{ data: User }> {
-  return fetchApi<{ data: User }>('/auths/user', {
+  return fetchApi<{ data: User }>('/auths/user', {
     method: 'GET',
     headers: {
       'Content-Type': 'application/json',
+      Authorization: `Bearer ${getAuthToken()}`, // 인증 토큰 추가
     },
-  });
+  }).then((response) => {
+    if (!response.data) {
+      throw new Error('사용자 데이터가 없습니다');
+    }
+    return response;
+  }).catch((error) => {
+    throw new Error(`사용자 정보 조회 실패: ${error.message}`);
+  });
 }

아래 스크립트로 인증 토큰 처리 방식을 확인해보겠습니다:

src/_queries/auth/user-apis.ts (1)

1-3: 임포트 구조가 깔끔합니다!

필요한 의존성들이 명확하게 정의되어 있고, 절대 경로를 일관성 있게 사용하고 있습니다.

src/_apis/auth/login-apis.ts (2)

1-2: 타입 정의와 유틸리티 임포트가 잘 구성되어 있습니다.

필요한 의존성들이 명확하게 정의되어 있고, 타입 안전성이 보장되어 있습니다.


16-19: 보안 강화를 위한 토큰 검증이 필요합니다.

토큰의 형식이나 유효성을 검증하는 로직을 추가하는 것이 좋습니다.

src/_queries/auth/login-queries.ts (2)

1-5: 임포트 구성이 깔끔합니다!

외부 라이브러리와 내부 모듈의 임포트가 잘 구성되어 있으며, 필요한 타입들도 적절히 임포트되어 있습니다.


12-14: 토큰 처리 방식 검증이 필요합니다.

토큰 처리와 관련된 보안 사항을 확인해주세요.

다음 스크립트로 토큰 처리 방식을 검증할 수 있습니다:

✅ Verification successful

토큰 처리 방식이 적절하게 구현되어 있습니다.

코드베이스 분석 결과:

  • 토큰은 sessionStorage를 통해 안전하게 저장되고 있습니다 (localStorage 대신)
  • handleAuthSuccess 함수에서 토큰 존재 여부를 검증합니다
  • Bearer 토큰 형식을 준수하며 적절한 인증 헤더로 사용됩니다
  • Zustand 상태 관리를 통해 토큰 상태가 체계적으로 관리됩니다
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 토큰 처리 관련 코드 검색
echo "토큰 저장 및 처리 방식 확인:"
rg -l "token" src/

echo "\n토큰 사용 패턴 확인:"
ast-grep --pattern 'token' 

echo "\nLocalStorage 사용 패턴 확인:"
rg -l "localStorage" src/

Length of output: 1160


Script:

#!/bin/bash
# Check token validation and storage implementation
echo "토큰 검증 및 저장 구현 확인:"
rg -A 5 "handleAuthSuccess" src/

echo "\n토큰 저장소 구현 확인:"
cat src/store/use-auth-store.tsx

echo "\n토큰 유효성 검사 패턴:"
rg "token.*valid|valid.*token" src/

Length of output: 2758

src/_apis/auth/signup-apis.ts (2)

4-7: API 엔드포인트 검증 필요

'/auths/signup' 엔드포인트가 백엔드 API 명세와 일치하는지 확인이 필요합니다.

#!/bin/bash
# Description: Search for API endpoint usage consistency

# Search for the endpoint usage across the codebase
rg -t typescript "'/auths/signup'" --type-add 'typescript:*.{ts,tsx}'

# Search for environment configuration files
fd -e ts -e js -e json "env|config" --exec grep -l "API|URL|ENDPOINT"

1-2: 타입 안전성 검증 필요

SignupRequestSignupResponse 타입이 올바르게 정의되어 있는지 확인이 필요합니다.

✅ Verification successful

타입 정의가 명확하게 구현되어 있습니다

SignupRequestSignupResponse 인터페이스가 적절하게 정의되어 있음을 확인했습니다:

  • SignupRequest: 사용자 가입에 필요한 nickname, email, password 필드를 포함
  • SignupResponse: 인증 토큰을 위한 token 필드를 포함
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify type definitions for SignupRequest and SignupResponse

# Search for type definitions
rg -t typescript "type SignupRequest|type SignupResponse|interface SignupRequest|interface SignupResponse" --type-add 'typescript:*.{ts,tsx}'

Length of output: 200


Script:

#!/bin/bash
# Let's search for type definitions in the types/auth directory
fd -e ts "auth" -d 3 --exec cat {}

# Also search for any type definitions containing "Signup"
ast-grep --pattern 'type Signup$_' --lang ts
ast-grep --pattern 'interface Signup$_' --lang ts

Length of output: 1215

src/_queries/auth/signup-queries.ts (2)

1-5: 깔끔한 의존성 관리와 타입 정의 👍

필요한 의존성들이 명확하게 구분되어 있고, 타입 정의도 잘 되어있습니다. 특히 API 에러 처리를 위한 별도의 타입을 import 한 것이 좋습니다.


8-8: 인증 성공 처리 로직 검증 필요

useHandleAuthSuccess 훅의 구현을 확인하여 토큰 저장 및 처리가 안전하게 이루어지는지 검증이 필요합니다.

✅ Verification successful

Let me gather more information about the token handling implementation.


토큰 처리 로직이 안전하게 구현되어 있음을 확인했습니다

useHandleAuthSuccess 훅의 구현을 검토한 결과:

  • 토큰 유효성 검사가 적절히 수행됨
  • Bearer 토큰 형식이 올바르게 처리됨
  • 토큰은 Zustand 상태 관리를 통해 안전하게 저장됨
  • 토큰 저장 후 사용자 정보를 가져와 상태를 업데이트하는 과정이 체계적으로 구현됨
  • 오류 처리가 적절히 구현되어 있음
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of useHandleAuthSuccess hook
# Expected: Find the implementation and verify token handling

# Search for the implementation file
echo "Searching for useHandleAuthSuccess implementation..."
rg -l "useHandleAuthSuccess"

# Look for token handling logic
echo "Checking token handling implementation..."
rg -A 5 "useHandleAuthSuccess" 

Length of output: 2197


Script:

#!/bin/bash
# Check the complete implementation of useHandleAuthSuccess
ast-grep --pattern 'export function useHandleAuthSuccess() {
  $$$
}'

# Check auth store implementation
rg -A 10 "useAuthStore"

# Check token storage related code
rg -A 5 "token" src/_queries/auth/

Length of output: 11907

src/_queries/auth/use-handle-auth-success.ts (1)

6-9: 스토어 초기화 상태 검증 필요

useAuthStore에서 가져온 메서드들의 존재 여부를 확인하는 것이 안전합니다.

다음 스크립트로 useAuthStore의 구현을 확인하겠습니다:

src/app/(auth)/login/page.tsx (2)

Line range hint 1-46: 컴포넌트 구조 및 에러 처리가 잘 구현되어 있습니다

  • React Hook Form을 활용한 폼 처리가 깔끔하게 구현되어 있습니다
  • 인증 실패 시의 에러 처리가 사용자 친화적으로 구현되어 있습니다
  • 회원가입 링크 제공으로 사용자 플로우가 자연스럽게 연결됩니다

7-7: 쿼리 파일 구조 변경 확인 필요

쿼리 파일의 구조가 auth-queries에서 login-queries로 변경되었습니다. 이는 인증 관련 쿼리들을 더 명확하게 분리하는 좋은 구조 개선입니다.

다음 스크립트를 실행하여 관련 파일들이 올바르게 구성되어 있는지 확인하겠습니다:

✅ Verification successful

쿼리 파일 구조가 올바르게 구성되어 있음을 확인했습니다

auth 관련 쿼리들이 각각의 책임에 맞게 잘 분리되어 있으며, login-queries.ts 파일이 정상적으로 구현되어 있습니다. 기존 auth-queries에서 참조하던 코드들도 모두 새로운 구조로 마이그레이션되었음을 확인했습니다.

  • src/_queries/auth/ 디렉토리에 login, signup, logout 등 기능별로 쿼리 파일이 잘 분리되어 있습니다
  • usePostLoginQuery 훅이 login-queries.ts에 올바르게 구현되어 있습니다
  • 기존 auth-queries를 참조하는 코드가 없어 마이그레이션이 완전히 이루어졌습니다
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the new query file structure and its dependencies

# Check if the new query file exists and contains the hook
echo "Checking login queries file..."
rg -l "usePostLoginQuery" "src/_queries/auth/login-queries.ts"

# Check for any remaining references to the old path
echo "Checking for old import references..."
rg "from.*auth-queries'" --type ts

Length of output: 291


Script:

#!/bin/bash
# Let's verify the query structure more thoroughly

# First, check if the login-queries file exists and see its content
echo "=== Checking login-queries file content ==="
fd "login-queries.ts" src/_queries/auth -x cat {}

# Check for any files importing from auth-queries
echo -e "\n=== Checking imports from auth-queries ==="
rg "from.*auth-queries" --type ts

# Check for any files importing from login-queries
echo -e "\n=== Checking imports from login-queries ==="
rg "from.*login-queries" --type ts

# Check if there are other query files in the auth directory
echo -e "\n=== Listing files in auth queries directory ==="
fd . src/_queries/auth

Length of output: 1416

src/app/(auth)/signup/page.tsx (1)

7-7: 임포트 경로 변경이 적절합니다

쿼리 관련 파일을 기능별로 분리한 것은 코드 구조를 개선하는 좋은 변경입니다.

src/utils/api.ts (2)

Line range hint 1-13: 타입 정의가 명확하게 되어있습니다!

ValidationError의 타입을 명시적으로 정의한 것이 코드의 안정성을 높여줍니다.


22-22: 인증 관련 응답 처리를 위한 매개변수 추가가 적절합니다.

isAuth 매개변수를 통해 인증이 필요한 요청과 그렇지 않은 요청을 구분하여 처리할 수 있게 되었습니다.

Comment on lines +4 to +20
export function login(data: LoginRequest): Promise<{ data: LoginResponse }> {
return fetchApi<{ data: LoginResponse; headers: Headers }>(
'/auths/login',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
},
5000,
true,
).then((response) => {
const token = response.headers.get('Authorization');
return { data: { token } };
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

토큰 처리와 에러 핸들링의 개선이 필요합니다.

다음 사항들을 고려해주시기 바랍니다:

  1. Authorization 헤더가 없는 경우에 대한 처리가 필요합니다.
  2. 입력값 검증이 누락되어 있습니다.
  3. 토큰을 안전하게 처리하는 방법을 검토해야 합니다.

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

 export function login(data: LoginRequest): Promise<{ data: LoginResponse }> {
+  if (!data.email || !data.password) {
+    throw new Error('이메일과 비밀번호는 필수입니다.');
+  }
   return fetchApi<{ data: LoginResponse; headers: Headers }>(
     '/auths/login',
     {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: JSON.stringify(data),
     },
     5000,
     true,
   ).then((response) => {
     const token = response.headers.get('Authorization');
+    if (!token) {
+      throw new Error('인증 토큰을 받지 못했습니다.');
+    }
     return { data: { token } };
   });
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +4 to +20
export function signup(data: SignupRequest): Promise<{ data: SignupResponse }> {
return fetchApi<{ data: SignupResponse; headers: Headers }>(
'/auths/signup',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
},
5000,
true,
).then((response) => {
const token = response.headers.get('Authorization');
return { data: { token } };
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

에러 처리 로직 추가 필요

현재 구현에서 다음과 같은 개선사항이 필요합니다:

  1. API 호출 실패 시 에러 처리가 없습니다
  2. Authorization 헤더가 없을 경우의 처리가 없습니다
  3. 타임아웃이 5초로 설정되어 있는데, 네트워크 상태가 좋지 않은 경우 문제가 될 수 있습니다

다음과 같이 수정하는 것을 제안드립니다:

 export function signup(data: SignupRequest): Promise<{ data: SignupResponse }> {
   return fetchApi<{ data: SignupResponse; headers: Headers }>(
     '/auths/signup',
     {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: JSON.stringify(data),
     },
-    5000,
+    10000,
     true,
   ).then((response) => {
     const token = response.headers.get('Authorization');
+    if (!token) {
+      throw new Error('인증 토큰을 받지 못했습니다');
+    }
     return { data: { token } };
+  }).catch((error) => {
+    if (error.name === 'AbortError') {
+      throw new Error('요청 시간이 초과되었습니다');
+    }
+    throw error;
   });
 }
📝 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
export function signup(data: SignupRequest): Promise<{ data: SignupResponse }> {
return fetchApi<{ data: SignupResponse; headers: Headers }>(
'/auths/signup',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
},
5000,
true,
).then((response) => {
const token = response.headers.get('Authorization');
return { data: { token } };
});
}
export function signup(data: SignupRequest): Promise<{ data: SignupResponse }> {
return fetchApi<{ data: SignupResponse; headers: Headers }>(
'/auths/signup',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
},
10000,
true,
).then((response) => {
const token = response.headers.get('Authorization');
if (!token) {
throw new Error('인증 토큰을 받지 못했습니다');
}
return { data: { token } };
}).catch((error) => {
if (error.name === 'AbortError') {
throw new Error('요청 시간이 초과되었습니다');
}
throw error;
});
}

Comment on lines +10 to +23
return async function handleAuthSuccess(token: string | null) {
if (!token) {
throw new Error('토큰이 없습니다');
}

try {
const accessToken = token.replace(/^Bearer\s/, '');
login(accessToken);
const user: User = await queryClient.fetchQuery(getUserQuery());
setUser(user);
} catch (error) {
throw new Error('사용자 상태 업데이트 실패');
}
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

토큰 처리 및 에러 핸들링 개선 필요

현재 구현에서 몇 가지 개선이 필요한 부분이 있습니다:

  1. 토큰 형식 검증이 미흡합니다
  2. 에러 메시지가 너무 일반적입니다
  3. 실패 시 정리(cleanup) 로직이 없습니다

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

   return async function handleAuthSuccess(token: string | null) {
     if (!token) {
-      throw new Error('토큰이 없습니다');
+      throw new Error('인증 토큰이 제공되지 않았습니다');
     }
+    
+    const tokenFormat = /^Bearer\s[\w-]+\.[\w-]+\.[\w-]+$/;
+    if (!tokenFormat.test(token)) {
+      throw new Error('유효하지 않은 토큰 형식입니다');
+    }

     try {
       const accessToken = token.replace(/^Bearer\s/, '');
       login(accessToken);
       const user: User = await queryClient.fetchQuery(getUserQuery());
       setUser(user);
     } catch (error) {
-      throw new Error('사용자 상태 업데이트 실패');
+      // 실패 시 정리
+      login(null);
+      setUser(null);
+      throw new Error(
+        error instanceof Error
+          ? `인증 처리 실패: ${error.message}`
+          : '알 수 없는 인증 오류가 발생했습니다'
+      );
     }
   };

토큰 관련 로직을 별도의 유틸리티 함수로 분리하는 것을 고려해보세요. 이렇게 하면 재사용성이 높아지고 테스트가 용이해집니다.

📝 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
return async function handleAuthSuccess(token: string | null) {
if (!token) {
throw new Error('토큰이 없습니다');
}
try {
const accessToken = token.replace(/^Bearer\s/, '');
login(accessToken);
const user: User = await queryClient.fetchQuery(getUserQuery());
setUser(user);
} catch (error) {
throw new Error('사용자 상태 업데이트 실패');
}
};
return async function handleAuthSuccess(token: string | null) {
if (!token) {
throw new Error('인증 토큰이 제공되지 않았습니다');
}
const tokenFormat = /^Bearer\s[\w-]+\.[\w-]+\.[\w-]+$/;
if (!tokenFormat.test(token)) {
throw new Error('유효하지 않은 토큰 형식입니다');
}
try {
const accessToken = token.replace(/^Bearer\s/, '');
login(accessToken);
const user: User = await queryClient.fetchQuery(getUserQuery());
setUser(user);
} catch (error) {
// 실패 시 정리
login(null);
setUser(null);
throw new Error(
error instanceof Error
? `인증 처리 실패: ${error.message}`
: '알 수 없는 인증 오류가 발생했습니다'
);
}
};

import { usePostSignupQuery } from '@/src/_queries/auth/signup-queries';
import SignupForm, { SignupFormValues } from './_component/signup-form';

export default function LoginPage() {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

컴포넌트 이름이 기능과 일치하지 않습니다

LoginPage라는 컴포넌트 이름이 회원가입 기능을 담당하는 페이지의 실제 목적과 일치하지 않습니다. 이는 코드의 가독성과 유지보수성을 저해할 수 있습니다.

다음과 같이 수정하는 것을 제안합니다:

-export default function LoginPage() {
+export default function SignupPage() {
📝 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
export default function LoginPage() {
export default function SignupPage() {

Comment on lines +54 to +56
const data = await response.json();
if (isAuth) return { data, headers: response.headers } as T;
return { data } as T;
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. as T 타입 캐스팅은 런타임에서 타입 안전성을 보장하지 않습니다.
  2. 반환 타입이 isAuth 값에 따라 달라지는데, 이를 타입 시스템에서 정확하게 표현하지 못하고 있습니다.

다음과 같은 개선을 제안드립니다:

type AuthResponse<T> = {
  data: T;
  headers: Headers;
};

type NonAuthResponse<T> = {
  data: T;
};

export async function fetchApi<T>(
  url: string,
  options: RequestInit = {},
  timeout = 5000,
  isAuth = false,
): Promise<isAuth extends true ? AuthResponse<T> : NonAuthResponse<T>> {
  // ... existing implementation ...
}

이렇게 수정하면:

  1. 조건부 타입을 통해 isAuth 값에 따른 반환 타입이 명확해집니다.
  2. 타입 안전성이 향상됩니다.

@minkyung5x5 minkyung5x5 merged commit 243dc0d into develop Nov 14, 2024
@coderabbitai coderabbitai bot mentioned this pull request Nov 21, 2024
5 tasks
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.

auth api 수정

4 participants