Conversation
MM-181 S2 기본 온보딩 화면을 구현했습니다.
MM-180 채팅 애착유형 테스트 알림
…-test-cta Revert "MM-180 채팅 애착유형 테스트 알림"
MM-183 Github Actions 개선
This reverts commit 6c8f456.
[FIX/MM-184] 스프린트2 QA
[FIX/MM-186] 채팅 타임스탬프 노출 로직 수정
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 Pull Request는 스프린트2 종료 후 배포를 위한 기능 업데이트를 포함합니다. 주요 변경 사항은 사용자 온보딩 경험을 확장하고 프로필 관리 기능을 강화하는 것입니다. 특히, 사용자의 연애 상태와 MBTI 정보를 수집하고 관리할 수 있도록 새로운 온보딩 플로우와 마이페이지 내 프로필 관리 섹션을 도입했습니다. 또한, 채팅 기능의 안정성과 사용자 경험을 개선하기 위해 메시지 스트리밍 로직을 최적화하고, 애착유형 테스트 유도 방식을 사용자 친화적으로 변경했습니다. 전반적으로 사용자 데이터의 풍부함을 더하고, 앱의 핵심 기능인 채팅 경험을 더욱 견고하게 만드는 데 중점을 두었습니다. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
이번 PR은 스프린트2의 결과물을 배포하기 위한 변경으로 보입니다. 새로운 온보딩 플로우(연애 상태, MBTI)와 프로필 관리 기능이 추가되었고, 채팅 컨텍스트가 리팩터링되어 안정성이 향상되었습니다. 전반적으로 많은 기능 개선과 코드 품질 향상이 이루어진 점이 인상적입니다. 하지만, API client 구현에서 민감한 사용자 데이터와 인증 토큰이 콘솔에 로깅되는 보안 취약점이 발견되었습니다. 이는 프로덕션 환경에서 데이터 노출로 이어질 수 있으므로, 개발 환경에서만 로깅되도록 처리하는 것이 권장됩니다. 또한, 홈 화면에서 필수 프로필 정보 입력을 유도하는 로직에 잠재적인 버그가 있어 수정이 필요해 보입니다. 온보딩 네비게이션 훅에서 경로를 정규화하는 로직이 중복 구현되어 있어 공통 유틸리티로 분리하면 더 좋을 것 같습니다. 자세한 내용은 각 파일에 남긴 리뷰 코멘트를 참고해주세요.
| useEffect(() => { | ||
| if (!requiredProfileStartPath) { | ||
| hasOpenedRequiredProfileDialog = false | ||
| return | ||
| } | ||
|
|
||
| if (hasOpenedRequiredProfileDialog) return | ||
| if (isAlertDialogOpen) return | ||
|
|
||
| hasOpenedRequiredProfileDialog = true | ||
|
|
||
| openAlertDialog({ | ||
| title: '모모의 연애 상담이 새로워졌어요', | ||
| description: ( | ||
| <> | ||
| 모모가 기억할 연애 정보를 입력하고 | ||
| <br /> | ||
| 연애 상담을 시작해 보세요 | ||
| </> | ||
| ), | ||
| image: ( | ||
| <img src={momoHomeChattingImage} alt="연애 상담 정보 입력" className="h-[164px] w-[184px] object-contain" /> | ||
| ), | ||
| confirmText: '정보 입력하러 가기', | ||
| onConfirm: wrapWithTracking(BUTTON_NAMES.GO_REQUIRED_PROFILE_FLOW, CATEGORIES.MAIN, () => { | ||
| const parsedSearch = requiredProfileFlowSearchSchema.parse({ requiredProfileFlow: true }) | ||
| navigate({ to: requiredProfileStartPath, search: parsedSearch, replace: true }) | ||
| }), | ||
| preventClose: true, | ||
| }) | ||
| }, [isAlertDialogOpen, navigate, openAlertDialog, requiredProfileStartPath]) |
There was a problem hiding this comment.
필수 프로필 정보 입력 플로우를 제어하기 위해 모듈 스코프의 hasOpenedRequiredProfileDialog 플래그를 사용하고 계신데요, 이 방식에는 잠재적인 버그가 있습니다.
유저가 정보 입력을 일부만 완료하고 홈으로 돌아올 경우, hasOpenedRequiredProfileDialog가 true로 유지되어 더 이상 다이얼로그가 표시되지 않습니다. 이로 인해 필수 정보 입력 프로세스가 중단될 수 있습니다.
isAlertDialogOpen 체크만으로도 다이얼로그가 중복으로 열리는 것을 방지할 수 있으므로, hasOpenedRequiredProfileDialog 플래그와 관련 로직을 제거하는 것을 제안합니다. 이렇게 하면 프로필 정보가 불완전할 때마다 홈 화면에서 항상 다이얼로그를 띄워 필수 플로우를 확실하게 유도할 수 있습니다.
preventClose: true 옵션 덕분에 사용자가 다이얼로그를 무시하기 어려우므로, 매번 띄워도 사용자 경험을 크게 해치지 않을 것입니다.
아래와 같이 수정하는 것을 제안합니다. (35번째 줄의 hasOpenedRequiredProfileDialog 변수 선언도 함께 제거해주세요.)
useEffect(() => {
if (!requiredProfileStartPath) {
return
}
if (isAlertDialogOpen) return
openAlertDialog({
title: '모모의 연애 상담이 새로워졌어요',
description: (
<>
모모가 기억할 연애 정보를 입력하고
<br />
연애 상담을 시작해 보세요
</>
),
image: (
<img src={momoHomeChattingImage} alt="연애 상담 정보 입력" className="h-[164px] w-[184px] object-contain" />
),
confirmText: '정보 입력하러 가기',
onConfirm: wrapWithTracking(BUTTON_NAMES.GO_REQUIRED_PROFILE_FLOW, CATEGORIES.MAIN, () => {
const parsedSearch = requiredProfileFlowSearchSchema.parse({ requiredProfileFlow: true })
navigate({ to: requiredProfileStartPath, search: parsedSearch, replace: true })
}),
preventClose: true,
})
}, [isAlertDialogOpen, navigate, openAlertDialog, requiredProfileStartPath])
| console.log( | ||
| `API Request: ${safeStringify({ | ||
| url: config.url, | ||
| payload: config.data, | ||
| })}` | ||
| ) |
There was a problem hiding this comment.
The API request interceptor logs the entire request payload to the console. This data can contain sensitive information such as social login tokens (in login requests) and Personally Identifiable Information (PII) like nicknames or relationship details (in profile update requests). These logs are active in production environments, which could lead to the exposure of sensitive user data in the browser console or log aggregation systems.
| console.log( | |
| `API Request: ${safeStringify({ | |
| url: config.url, | |
| payload: config.data, | |
| })}` | |
| ) | |
| if (import.meta.env.DEV) { | |
| console.log( | |
| `API Request: ${safeStringify({ | |
| url: config.url, | |
| payload: config.data, | |
| })}` | |
| ) | |
| } |
| apiInstance.interceptors.response.use( | ||
| (response) => { | ||
| console.log('API Response:', response.data) | ||
| console.log(`API Response: ${safeStringify(response.data)}`) |
There was a problem hiding this comment.
The API response interceptor logs the entire response body to the console. This can include sensitive user data (PII) returned by the server, such as email addresses and detailed profile information. Logging this data in production is a security risk as it exposes user information in the client-side environment.
if (import.meta.env.DEV) {
console.log(`API Response: ${safeStringify(response.data)}`)
}| const currentPath = window.location.pathname | ||
| return ONBOARDING_STEPS.findIndex((step) => currentPath.endsWith(step)) | ||
| // trailing slash 제거 후 비교 | ||
| const currentPath = location.pathname.replace(/\/$/, '') |
이슈 번호
작업내용
변경한 주요 내용 목록
리뷰어에게 전할 말
스크린샷 (선택사항)