Skip to content

feat: 마이페이지 로그아웃 API 구현 (#86) #92

Merged
wkdtnqls0506 merged 5 commits intomainfrom
feature/PRODUCT-188
Jul 21, 2025
Merged

feat: 마이페이지 로그아웃 API 구현 (#86) #92
wkdtnqls0506 merged 5 commits intomainfrom
feature/PRODUCT-188

Conversation

@wkdtnqls0506
Copy link
Contributor

@wkdtnqls0506 wkdtnqls0506 commented Jul 21, 2025

✅ 이슈 번호

close #86


🪄 작업 내용 (변경 사항)

  • /app/api/auth/logout/route.ts 생성
  • AlertModal 디자인 요청사항에 맞게 radius 값 변경

📸 스크린샷


💡 설명

서버 (/api/auth/logout/route.ts)

  • getSessionFromServer()로 현재 세션을 확인
  • 세션이 없으면 401 반환, 세션이 존재하면 session.destroy() 후 200 반환
  • 로그아웃 처리 중 에러 발생 시 500 반환

클라이언트

  • useDeleteSessionMutation()으로 DELETE /api/auth/logout 호출
  • onSuccess → clearClientSessionCache() 실행 후 router.replace("/")로 메인 페이지 이동
  • onError → 추후 Toast 메시지로 에러 안내 예정

🗣️ 리뷰어에게 전달 사항

  1. 로그아웃 플로우는 정상 동작하는 것 확인했습니다만, 로직상 더 나은 방식이나 개선할 부분이 있다면 편하게 리뷰 부탁드립니다~! 🙇🏻‍♀️
  2. Toast 컴포넌트는 구현 후 연결 예정입니다!

📍 트러블 슈팅

Summary by CodeRabbit

  • New Features

    • 로그아웃 시 확인 모달이 추가되어, 로그아웃 버튼 클릭 시 확인 메시지가 표시됩니다.
    • 로그아웃 API가 도입되어 세션이 안전하게 종료됩니다.
    • 로그아웃 시 세션 및 관련 캐시가 완전히 삭제되어 데이터 일관성이 향상되었습니다.
  • Style

    • 로그아웃 모달 버튼에 flex 스타일이 적용되어 버튼 배치가 개선되었습니다.
    • AlertModal의 모서리 둥글기가 더 커져 시각적으로 부드러워졌습니다.

@wkdtnqls0506 wkdtnqls0506 added the ✨ feature 새로운 기능 추가 label Jul 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 21, 2025

Walkthrough

이 변경에서는 마이페이지 로그아웃 기능이 구현되었습니다. 로그아웃 API 엔드포인트가 추가되고, 프로필 메뉴에서 로그아웃 시 확인 모달이 표시되며, 로그아웃 성공 시 세션 캐시가 정리되고 메인 페이지로 리다이렉트됩니다. 일부 스타일도 조정되었습니다.

Changes

파일/경로 변경 요약
src/app/api/auth/logout/route.ts 로그아웃용 DELETE API 엔드포인트 신설 및 세션 파기 처리 추가
src/app/(auth)/_api/auth/auth.queries.ts useDeleteSessionMutation에 onSuccess 콜백으로 세션 및 쿼리 캐시 정리 추가
src/app/member/profile/_components/MenuList/MenuList.tsx 로그아웃 메뉴에 확인 모달 추가, 로그아웃 처리 및 리다이렉트 구현
src/app/member/profile/_components/MenuList/MenuList.css.ts modalButton 스타일(flex: 1) 신규 추가
src/components/ui/AlertModal/AlertModal.css.ts AlertModal의 content border-radius 값 변경

Estimated code review effort

3 (30–60분)

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/app/(auth)/_api/auth/auth.queries.ts

Oops! Something went wrong! :(

ESLint: 9.27.0

ESLint couldn't find the plugin "eslint-plugin-react-hooks".

(The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react-hooks@latest --save-dev

The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.27.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js".

If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.


📜 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 0291175 and 6c70ae3.

📒 Files selected for processing (1)
  • src/app/(auth)/_api/auth/auth.queries.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/nextjs-folder-structure.mdc)

All files must use TypeScript.

Files:

  • src/app/(auth)/_api/auth/auth.queries.ts
🧠 Learnings (1)
src/app/(auth)/_api/auth/auth.queries.ts (1)

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.408Z
Learning: Applies to {src/hooks/use*.ts,src/hooks/use*.tsx,src/app//_hooks/use*.ts,src/app//_hooks/use*.tsx,src/app//feature//_hooks/use*.ts,src/app//feature//_hooks/use*.tsx} : Hook files must use camelCase with a use prefix (e.g., useLocalStorage.ts, useDomainData.ts).

🧬 Code Graph Analysis (1)
src/app/(auth)/_api/auth/auth.queries.ts (2)
src/app/(auth)/_api/auth/auth.api.ts (1)
  • deleteClientSession (74-76)
src/lib/session/clientSession.ts (1)
  • clearClientSessionCache (16-18)
⏰ 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: test
🔇 Additional comments (1)
src/app/(auth)/_api/auth/auth.queries.ts (1)

31-31: LGTM! 쿼리 클라이언트 인스턴스 추가가 적절합니다.

useLoginMutation과 동일한 패턴을 따라 일관성 있게 구현되었습니다.

✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • @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 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.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

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 generate sequence diagram to generate a sequence diagram of the changes in 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 Jul 21, 2025

🎨 Storybook Preview: https://685a32a1c0bbd269fdb67af4-uyhjqjiunm.chromatic.com/
🔗 Chromatic Build: https://www.chromatic.com/build?appId=685a32a1c0bbd269fdb67af4&number=123
🕖 Updated at: 2025년 07월 21일 23시 14분 04초

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 (2)
src/app/member/profile/_components/MenuList/MenuList.tsx (2)

19-30: 로그아웃 핸들러 구현이 좋습니다

로그아웃 로직이 적절히 구현되었습니다:

  • 성공 시 메인 페이지로 리다이렉트
  • 에러 핸들링 구조 포함

향후 Toast 컴포넌트 구현 시 더 나은 사용자 피드백을 제공할 수 있을 것입니다.


42-74: 인라인 스타일을 CSS 파일로 이동하는 것을 고려해보세요

로그아웃 확인 모달 구현이 잘 되었습니다. 하지만 버튼의 borderRadius 인라인 스타일을 CSS 파일로 이동하는 것을 고려해보세요.

다음과 같이 CSS 파일에 스타일을 추가할 수 있습니다:

MenuList.css.ts에 추가:

+export const modalButtonLeft = style({
+  flex: 1,
+  borderRadius: "0 0 0 1.2rem",
+});
+
+export const modalButtonRight = style({
+  flex: 1,
+  borderRadius: "0 0 1.2rem 0",
+});

그리고 컴포넌트에서 사용:

-                        className={styles.modalButton}
-                        style={{ borderRadius: "0 0 0 1.2rem" }}
+                        className={styles.modalButtonLeft}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ee8d451 and 0291175.

📒 Files selected for processing (5)
  • src/app/(auth)/_api/auth/auth.queries.ts (1 hunks)
  • src/app/api/auth/logout/route.ts (1 hunks)
  • src/app/member/profile/_components/MenuList/MenuList.css.ts (1 hunks)
  • src/app/member/profile/_components/MenuList/MenuList.tsx (2 hunks)
  • src/components/ui/AlertModal/AlertModal.css.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{src/styles/**/*.css.ts,src/app/**/_components/**/*.css.ts,src/components/**/*.css.ts}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/nextjs-folder-structure.mdc
src/**/*.{ts,tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/nextjs-folder-structure.mdc
{src/app/**/_components/**/*.tsx,src/components/**/*.tsx}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/nextjs-folder-structure.mdc
🧠 Learnings (3)
src/components/ui/AlertModal/AlertModal.css.ts (2)

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.398Z
Learning: Applies to {src/app/**/_components/.css.ts,src/components/.css.ts} : Component-specific styles should be co-located with the component file.

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.398Z
Learning: Applies to {src/styles//*.css.ts,src/app//_components//*.css.ts,src/components//*.css.ts} : Style files must use camelCase naming with the .css.ts extension (e.g., Button.css.ts, theme.css.ts).

src/app/(auth)/_api/auth/auth.queries.ts (1)

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.398Z
Learning: Applies to {src/hooks/use*.ts,src/hooks/use*.tsx,src/app//_hooks/use*.ts,src/app//_hooks/use*.tsx,src/app//feature//_hooks/use*.ts,src/app//feature//_hooks/use*.tsx} : Hook files must use camelCase with a use prefix (e.g., useLocalStorage.ts, useDomainData.ts).

src/app/member/profile/_components/MenuList/MenuList.css.ts (2)

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.398Z
Learning: Applies to {src/styles//*.css.ts,src/app//_components//*.css.ts,src/components//*.css.ts} : Style files must use camelCase naming with the .css.ts extension (e.g., Button.css.ts, theme.css.ts).

Learnt from: CR
PR: YAPP-Github/26th-Web-Team-1-FE#0
File: .cursor/rules/nextjs-folder-structure.mdc:0-0
Timestamp: 2025-07-20T14:21:47.398Z
Learning: Applies to {src/app/**/_components/.css.ts,src/components/.css.ts} : Component-specific styles should be co-located with the component file.

🧬 Code Graph Analysis (1)
src/app/(auth)/_api/auth/auth.queries.ts (1)
src/lib/session/clientSession.ts (1)
  • clearClientSessionCache (16-18)
🔇 Additional comments (6)
src/components/ui/AlertModal/AlertModal.css.ts (1)

23-23: 디자인 요구사항에 따른 스타일 조정 승인

border radius 값을 radius[120]에서 radius[160]으로 증가시킨 변경사항이 적절합니다. PR 목표에서 언급된 디자인 요청에 따른 조정으로 보입니다.

src/app/member/profile/_components/MenuList/MenuList.css.ts (1)

18-20: 모달 버튼 레이아웃을 위한 스타일 추가 승인

modalButton 스타일 추가가 적절합니다. flex: 1 속성으로 모달의 취소/확인 버튼이 동일한 너비를 가지도록 하여 좋은 사용자 경험을 제공합니다.

src/app/api/auth/logout/route.ts (1)

5-25: session.destroy() 메서드 구현 확인 완료

  • getIronSession() 호출로 반환되는 세션 객체(IronSession)에 destroy() 메서드가 기본 제공되므로, await session.destroy()는 정상 동작합니다.
  • console.error("로그아웃 중 에러:", error) 로깅에는 세션 토큰 등 민감 정보가 포함되지 않으므로, 별도 추가 조치 없이도 안전합니다.

변경사항 그대로 승인합니다.

src/app/(auth)/_api/auth/auth.queries.ts (1)

33-35: 클라이언트 세션 캐시 정리 로직 추가 승인

로그아웃 성공 시 clearClientSessionCache()를 호출하여 클라이언트 측 세션 캐시를 정리하는 것이 적절합니다. 이는 useLoginMutation과 동일한 패턴을 따르며 세션 상태 일관성을 보장합니다.

src/app/member/profile/_components/MenuList/MenuList.tsx (2)

3-17: 필요한 의존성 import 승인

AlertDialog, useRouter, useDeleteSessionMutation 등 로그아웃 기능에 필요한 모든 의존성이 적절히 import되었습니다.


22-23: 리다이렉트 동작 검증 요청

로그아웃 후 router.replace("/")로 메인 페이지로 이동하는 것이 의도된 동작인지 확인해주세요. 일부 애플리케이션에서는 로그인 페이지로 리다이렉트하는 경우도 있습니다.

Copy link
Member

@Seojunhwan Seojunhwan left a comment

Choose a reason for hiding this comment

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

빠르시네요 , , 코멘트 남겨뒀습니다!

Comment on lines +33 to +35
onSuccess: () => {
clearClientSessionCache();
},
Copy link
Member

Choose a reason for hiding this comment

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

P1: queryClient.clear()도 추가하는 것은 어떨까요?

그러면 흠,, onSettled에 넣어야 하려나 , , 성공했을 때만 지워도 될 것 같기도 하고 , ,

refs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

6c70ae3

queryClient.clear()도 추가했습니다~!

준환님 말씀처럼 onSettled로 항상 지워주기 보다는 에러가 발생했을 땐 세션이 남아있을 수도 있는 상황이라 토스트만 띄우는 편이 더 나을 거 같아여!!
그리고 전체 캐시를 다 날려서 로그인과 상관없는 다른 캐시 데이터들도 같이 초기화될 수 있을 것 같은데, 이 부분 추후에 얘기해봐도 좋을 것 같아요 👍🏻👍🏻

Copy link
Member

Choose a reason for hiding this comment

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

역시!

Comment on lines +42 to +74
<AlertModal
title='로그아웃하시나요?'
trigger={
<button type='button' className={styles.menuItem}>
로그아웃
</button>
}
footer={
<>
<AlertDialog.Cancel asChild>
<Button
variant='assistive'
size='large'
className={styles.modalButton}
style={{ borderRadius: "0 0 0 1.2rem" }}
>
취소
</Button>
</AlertDialog.Cancel>
<AlertDialog.Action asChild>
<Button
variant='primary'
size='large'
onClick={handleLogout}
className={styles.modalButton}
style={{ borderRadius: "0 0 1.2rem" }}
>
확인
</Button>
</AlertDialog.Action>
</>
}
/>
Copy link
Member

Choose a reason for hiding this comment

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

고냥 참고만 해주십사!

https://overlay-kit.slash.page/ko <- 애용하는 녀석인데 지금 이 코드도 잘 읽혀서 , , 나중에 참고만 해주셔용

Copy link
Contributor Author

Choose a reason for hiding this comment

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

오!! 문서 쭉 읽어봤는데 확실히 상태 따로 선언 안 하고 바로 overlay.open으로 관리할 수 있는 게 깔끔하네요@@!!
버튼 클릭 시 그 안에 들어갈 UI만 넘기면 돼서 모달같은 오버레이 로직이 훨씬 단순해질 것 같아요..!
시간날 때 리팩토링 해볼게요!!👍🏻 감사함돠 🙇🏻‍♀️

Copy link
Member

@Seojunhwan Seojunhwan left a comment

Choose a reason for hiding this comment

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

고생하셨어요~!~!

@wkdtnqls0506 wkdtnqls0506 merged commit 4662e18 into main Jul 21, 2025
6 checks passed
@wkdtnqls0506 wkdtnqls0506 deleted the feature/PRODUCT-188 branch July 21, 2025 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feature 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PRODUCT-188] 마이페이지 로그아웃 API 구현

2 participants