Skip to content

feat: 비밀번호 api 연결#51

Open
dasosann wants to merge 1 commit intomainfrom
feat/reset-api
Open

feat: 비밀번호 api 연결#51
dasosann wants to merge 1 commit intomainfrom
feat/reset-api

Conversation

@dasosann
Copy link
Copy Markdown
Contributor

@dasosann dasosann commented Apr 5, 2026

No description provided.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

비밀번호 재설정 API 연동 구현

✨ Enhancement

Grey Divider

Walkthroughs

Description
• 비밀번호 재설정 API 연동 완료
• 이메일 전송 및 인증번호 검증 훅 추가
• 비밀번호 변경 요청 API 통합
• 로딩 상태 및 에러 처리 개선
Diagram
flowchart LR
  A["이메일 입력"] -->|useSendPasswordCode| B["인증번호 전송"]
  B -->|성공| C["인증번호 입력"]
  C -->|저장| D["새 비밀번호 입력"]
  D -->|useResetPassword| E["비밀번호 변경"]
  E -->|성공| F["완료 페이지"]
Loading

Grey Divider

File Changes

1. hooks/useResetPassword.ts ✨ Enhancement +56/-0

비밀번호 변경 API 훅 구현

• 비밀번호 변경 API 호출을 위한 커스텀 훅 신규 생성
• PATCH /api/auth/password/code 엔드포인트 연동
• 이메일, 인증코드, 새 비밀번호를 함께 전송
• Axios 에러 처리 및 상태 코드 검증 로직 포함

hooks/useResetPassword.ts


2. hooks/useSendPasswordCode.ts ✨ Enhancement +50/-0

인증번호 전송 API 훅 구현

• 인증번호 전송 API 호출을 위한 커스텀 훅 신규 생성
• POST /api/auth/password/code 엔드포인트 연동
• 이메일 기반 인증코드 발송 처리
• 에러 응답 메시지 추출 및 전달 로직 구현

hooks/useSendPasswordCode.ts


3. app/reset/password/_components/ScreenPasswordResetPage.tsx ✨ Enhancement +15/-9

이메일 전송 API 연동 완료

useSendPasswordCode 훅 통합으로 API 연동
• TODO 주석 제거 및 실제 API 호출 로직 구현
• 로딩 상태(isPending) 기반 버튼 비활성화 및 텍스트 변경
• 에러 메시지 표시 기능 추가

app/reset/password/_components/ScreenPasswordResetPage.tsx


View more (2)
4. app/reset/password/new/_components/ScreenNewPasswordPage.tsx ✨ Enhancement +37/-13

비밀번호 변경 API 연동 완료

useResetPassword 훅 통합으로 비밀번호 변경 API 연동
• sessionStorage에서 이메일과 인증코드 조회 후 API 전송
• 로딩 상태 기반 버튼 비활성화 및 텍스트 변경
• 에러 메시지 표시 영역 추가 및 세션 정리 로직 개선

app/reset/password/new/_components/ScreenNewPasswordPage.tsx


5. app/reset/password/verification/_components/ScreenVerificationPage.tsx ✨ Enhancement +19/-24

인증번호 재전송 API 연동

useSendPasswordCode 훅으로 재전송 기능 API 연동
• 인증번호 검증 로직 단순화 (sessionStorage에만 저장)
• 실제 검증은 새 비밀번호 페이지의 PATCH API에서 처리
• 불필요한 setIsSending 상태 제거 및 훅 상태 활용

app/reset/password/verification/_components/ScreenVerificationPage.tsx


Grey Divider

Qodo Logo


✨ Describe tool usage guide:

Overview:
The describe tool scans the PR code changes, and generates a description for the PR - title, type, summary, walkthrough and labels. The tool can be triggered automatically every time a new PR is opened, or can be invoked manually by commenting on a PR.

When commenting, to edit configurations related to the describe tool (pr_description section), use the following template:

/describe --pr_description.some_config1=... --pr_description.some_config2=...

With a configuration file, use the following template:

[pr_description]
some_config1=...
some_config2=...
Enabling\disabling automation
  • When you first install the app, the default mode for the describe tool is:
pr_commands = ["/describe", ...]

meaning the describe tool will run automatically on every PR.

  • Markers are an alternative way to control the generated description, to give maximal control to the user. If you set:
pr_commands = ["/describe --pr_description.use_description_markers=true", ...]

the tool will replace every marker of the form pr_agent:marker_name in the PR description with the relevant content, where marker_name is one of the following:

  • type: the PR type.
  • summary: the PR summary.
  • walkthrough: the PR walkthrough.
  • diagram: the PR sequence diagram (if enabled).

Note that when markers are enabled, if the original PR description does not contain any markers, the tool will not alter the description at all.

Custom labels

The default labels of the describe tool are quite generic: [Bug fix, Tests, Enhancement, Documentation, Other].

If you specify custom labels in the repo's labels page or via configuration file, you can get tailored labels for your use cases.
Examples for custom labels:

  • Main topic:performance - pr_agent:The main topic of this PR is performance
  • New endpoint - pr_agent:A new endpoint was added in this PR
  • SQL query - pr_agent:A new SQL query was added in this PR
  • Dockerfile changes - pr_agent:The PR contains changes in the Dockerfile
  • ...

The list above is eclectic, and aims to give an idea of different possibilities. Define custom labels that are relevant for your repo and use cases.
Note that Labels are not mutually exclusive, so you can add multiple label categories.
Make sure to provide proper title, and a detailed and well-phrased description for each label, so the tool will know when to suggest it.

Inline File Walkthrough 💎

For enhanced user experience, the describe tool can add file summaries directly to the "Files changed" tab in the PR page.
This will enable you to quickly understand the changes in each file, while reviewing the code changes (diffs).

To enable inline file summary, set pr_description.inline_file_summary in the configuration file, possible values are:

  • 'table': File changes walkthrough table will be displayed on the top of the "Files changed" tab, in addition to the "Conversation" tab.
  • true: A collapsable file comment with changes title and a changes summary for each file in the PR.
  • false (default): File changes walkthrough will be added only to the "Conversation" tab.
Utilizing extra instructions

The describe tool can be configured with extra instructions, to guide the model to a feedback tailored to the needs of your project.

Be specific, clear, and concise in the instructions. With extra instructions, you are the prompter. Notice that the general structure of the description is fixed, and cannot be changed. Extra instructions can change the content or style of each sub-section of the PR description.

Examples for extra instructions:

[pr_description]
extra_instructions="""- The PR title should be in the format: '<PR type>: <title>'
- The title should be short and concise (up to 10 words)
- ...
"""

Use triple quotes to write multi-line instructions. Use bullet points to make the instructions more readable.

More PR-Agent commands

To invoke the PR-Agent, add a comment using one of the following commands:

  • /review: Request a review of your Pull Request.
  • /describe: Update the PR title and description based on the contents of the PR.
  • /improve [--extended]: Suggest code improvements. Extended mode provides a higher quality feedback.
  • /ask <QUESTION>: Ask a question about the PR.
  • /update_changelog: Update the changelog based on the PR's contents.
  • /help_docs <QUESTION>: Given a path to documentation (either for this repository or for a given one), ask a question.
  • /add_docs 💎: Generate docstring for new components introduced in the PR.
  • /generate_labels 💎: Generate labels for the PR based on the PR's contents.
  • /analyze 💎: Automatically analyzes the PR, and presents changes walkthrough for each component.

See the tools guide for more details.
To list the possible configuration parameters, add a /config comment.

See the describe usage page for a comprehensive guide on using this tool.

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Apr 5, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. Bypass shared axios instance 🐞 Bug ☼ Reliability
Description
useSendPasswordCode/useResetPassword가 프로젝트 공통 axios 인스턴스(api)를 쓰지 않고 raw axios +
NEXT_PUBLIC_API_URL을 직접 조합해 호출하여 withCredentials/401 재발급 인터셉터/공통 설정이 적용되지 않습니다. 또한
NEXT_PUBLIC_API_URL이 비어있을 경우 "undefined/api/..." 같은 잘못된 URL로 요청이 나갈 수 있습니다.
Code

hooks/useSendPasswordCode.ts[R14-17]

+  const { data } = await axios.post<SendPasswordCodeResponse>(
+    `${process.env.NEXT_PUBLIC_API_URL}/api/auth/password/code`,
+    { email },
+  );
Evidence
레포에는 baseURL/withCredentials 및 401 시 토큰 재발급 재시도 로직을 포함한 공통 api 인스턴스가 있으며, 기존 훅들은 이를 사용합니다. 하지만 본 PR의
두 훅은 axios를 직접 사용해 위 공통 동작에서 이탈합니다.

hooks/useSendPasswordCode.ts[1-19]
hooks/useResetPassword.ts[17-25]
lib/axios.ts[3-12]
lib/axios.ts[14-38]
hooks/useSendEmail.ts[1-15]
hooks/useVerifyEmail.ts[16-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`useSendPasswordCode` / `useResetPassword`가 `axios`를 직접 사용하면서 프로젝트 공통 설정(`baseURL`, `withCredentials`, 401 재발급 인터셉터)을 우회합니다. 또한 `NEXT_PUBLIC_API_URL` 누락 시 문자열 결합으로 잘못된 URL("undefined/api/...")이 만들어질 수 있습니다.

## Issue Context
레포에는 `lib/axios.ts`에서 `api` 인스턴스를 만들고, 다른 훅들은 `api.post('/api/...')` 형태로 호출합니다.

## Fix Focus Areas
- hooks/useSendPasswordCode.ts[1-18]
- hooks/useResetPassword.ts[1-25]
- lib/axios.ts[3-42]

## What to change
- 두 훅에서 `import axios from "axios"` 대신 `import { api } from "@/lib/axios"` 사용
- URL은 `${process.env...}` 조합 대신 상대경로로 호출: 
 - `api.post("/api/auth/password/code", { email })`
 - `api.patch("/api/auth/password/code", payload)`
- (선택) 필요 시 에러 메시지 파싱은 기존 `useVerifyEmail` 패턴 유지

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Reset payload may be empty 🐞 Bug ≡ Correctness
Description
ScreenNewPasswordPage가 sessionStorage에서 email/code를 못 읽으면 빈 문자열로 대체한 뒤 그대로 PATCH 요청을 보내 invalid
request를 발생시킵니다. reset_verified만 검사하므로 sessionStorage가 중간에 지워지거나 불일치할 때 사용자는 복구 없이 실패 메시지만 보게 됩니다.
Code

app/reset/password/new/_components/ScreenNewPasswordPage.tsx[R46-52]

+    const email = sessionStorage.getItem("reset_email_to_verify") ?? "";
+    const code = sessionStorage.getItem("reset_code") ?? "";
+
+    reset(
+      { email, code, newPassword: password },
+      {
+        onSuccess: () => {
Evidence
페이지 접근 가드는 reset_verified만 확인하고, 실제 API 호출 직전에 email/code 존재 여부를 검사하지 않습니다. 그 결과 email/code가 없을 때도
reset({ email: "", code: "", ... })가 실행됩니다.

app/reset/password/new/_components/ScreenNewPasswordPage.tsx[26-35]
app/reset/password/new/_components/ScreenNewPasswordPage.tsx[42-65]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`/reset/password/new`에서 `reset_email_to_verify` 또는 `reset_code`가 없을 때도 빈 문자열로 PATCH 요청을 보내 플로우가 깨집니다.

## Issue Context
현재는 `reset_verified === 'true'`만 확인하고, `email/code` 유효성은 보장되지 않습니다(사용자 스토리지 삭제/브라우저 정책/이전 플로우 잔재 등).

## Fix Focus Areas
- app/reset/password/new/_components/ScreenNewPasswordPage.tsx[26-65]

## What to change
- `handleSubmit`에서 `email`/`code`가 비어있으면:
 - 에러 메시지 표시(예: "세션이 만료되었습니다. 처음부터 다시 시도해 주세요")
 - `reset_verified`, `reset_email_to_verify`, `reset_code` 정리 후 `/reset/password`로 이동
- `code.length === 6` 같은 최소 검증도 함께 적용

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Verification submit lacks guard 🐞 Bug ☼ Reliability
Description
ScreenVerificationPage.handleVerify가 verificationCode 길이/형식을 검증하지 않고 reset_code를 저장한 뒤 다음 단계로 이동합니다.
버튼 disabled 조건은 onSubmit을 직접 막지 못할 수 있고, isVerifying는 설정되지 않아 중복 제출 방지도 동작하지 않습니다.
Code

app/reset/password/verification/_components/ScreenVerificationPage.tsx[R80-84]

+    // 인증코드와 이메일을 sessionStorage에 저장만 하고 새 비밀번호 페이지에서 PATCH API 호출
+    // (PATCH /api/auth/password/code 는 email+code+newPassword 를 한 번에 요청)
+    sessionStorage.setItem("reset_verified", "true");
+    sessionStorage.setItem("reset_code", verificationCode);
+    router.replace("/reset/password/new");
Evidence
handleVerify에는 길이 체크가 없고, isVerifying는 선언만 되어 있으며 setIsVerifying 호출이 없습니다. 그런데 submit 버튼은
isVerifying에 의존해 비활성/로딩 텍스트를 표시하므로 현재 상태에서는 검증/중복제출 방지가 불완전합니다.

app/reset/password/verification/_components/ScreenVerificationPage.tsx[14-20]
app/reset/password/verification/_components/ScreenVerificationPage.tsx[78-85]
app/reset/password/verification/_components/ScreenVerificationPage.tsx[184-190]
app/reset/password/verification/_components/ScreenVerificationPage.tsx[141-167]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
인증 페이지에서 submit 시점에 `verificationCode` 검증이 없어 빈 값/짧은 값이 저장될 수 있고, `isVerifying`가 실사용되지 않아 UX/중복 제출 방지가 깨집니다.

## Issue Context
백엔드에서 최종 검증을 하더라도, 클라이언트 단계 이동 전에 최소 입력 검증이 있어야 불필요한 실패/혼란을 줄입니다.

## Fix Focus Areas
- app/reset/password/verification/_components/ScreenVerificationPage.tsx[78-90]
- app/reset/password/verification/_components/ScreenVerificationPage.tsx[184-190]

## What to change
- `handleVerify`에서 `verificationCode.length !== 6` (및 필요 시 숫자만) 이면 `setErrorMessage(...)` 후 `return`
- `isVerifying`를 실제로 사용하려면 submit 시작 시 `setIsVerifying(true)` 후 라우팅/에러 시 되돌리기
 - 또는 `isVerifying` 상태를 제거하고 버튼 disabled 조건에서 제거하여 혼동 방지

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Reset session not fully cleared 🐞 Bug ☼ Reliability
Description
새 비밀번호 재설정 프로세스를 시작할 때 reset_verified만 제거하고 reset_email_to_verify/reset_code는 남겨 이전 시도의 값이 다음 플로우에
섞일 수 있습니다. 특히 사용자가 중간에 재시도/다른 이메일로 재요청할 때 상태 불일치가 발생합니다.
Code

app/reset/password/_components/ScreenPasswordResetPage.tsx[R30-36]

    // 새로운 프로세스 시작 시 이전 잔여 세션이 있다면 초기화
    sessionStorage.removeItem("reset_verified");

-    // TODO: 비밀번호 재설정 이메일 발송 API 연동
-    console.log("Password reset requested for:", email);
-
-    // 이메일 전송 단계 정보 저장
-    sessionStorage.setItem("reset_email_to_verify", email);
-
-    // 전송 완료 후 인증번호 입력 페이지로 이동 (이후 단계부터는 replace 사용)
-    router.replace("/reset/password/verification");
+    sendCode(email, {
+      onSuccess: () => {
+        sessionStorage.setItem("reset_email_to_verify", email);
+        router.replace("/reset/password/verification");
Evidence
시작 페이지는 reset_verified만 제거하지만, 이후 페이지들은 reset_email_to_verify/reset_code를 sessionStorage에서 읽어 API
payload를 구성합니다. 시작 단계에서 나머지 키를 정리하지 않으면 이전 값이 남아 있을 수 있습니다.

app/reset/password/_components/ScreenPasswordResetPage.tsx[30-37]
app/reset/password/verification/_components/ScreenVerificationPage.tsx[64-66]
app/reset/password/verification/_components/ScreenVerificationPage.tsx[80-84]
app/reset/password/new/_components/ScreenNewPasswordPage.tsx[46-50]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
리셋 플로우 시작 시 sessionStorage 키가 부분적으로만 정리되어, 이전 시도 값이 남을 수 있습니다.

## Issue Context
플로우 전반에서 사용하는 키:
- reset_verified
- reset_email_to_verify
- reset_code

## Fix Focus Areas
- app/reset/password/_components/ScreenPasswordResetPage.tsx[28-37]

## What to change
- 새 프로세스 시작 시 위 3개 키를 모두 제거한 뒤 진행
 - 예: `['reset_verified','reset_email_to_verify','reset_code'].forEach(k => sessionStorage.removeItem(k))`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 풀 리퀘스트는 비밀번호 재설정 프로세스에 실제 API 연동을 위해 useSendPasswordCode 및 useResetPassword 커스텀 훅을 도입하고, 이메일 발송 및 비밀번호 변경 로직을 구현했습니다. 코드 리뷰 결과, 보안 및 성능 최적화를 위해 axios 대신 Server Actions 사용이 권장되며, useMutation을 중복으로 래핑한 로직의 단순화가 필요합니다. 또한, 가독성을 위해 200줄이 넘는 컴포넌트를 서브 컴포넌트로 분리하고, 사용자 경험을 개선하기 위해 인증 번호를 세션에 저장하는 대신 즉시 서버에서 검증하는 로직을 추가할 것을 제안합니다.

Comment on lines +17 to +25
const resetPassword = async (
payload: ResetPasswordRequest,
): Promise<ResetPasswordResponse> => {
const { data } = await axios.patch<ResetPasswordResponse>(
`${process.env.NEXT_PUBLIC_API_URL}/api/auth/password/code`,
payload,
);
return data;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Repository Style Guide (2.2 - 43)에 따라 데이터 변이(Mutation)는 클라이언트 측 axios 호출 대신 Server Actions를 사용하여 처리하는 것이 권장됩니다. 이는 보안성을 높이고 클라이언트 번들 크기를 최적화하는 데 도움이 됩니다.

References
  1. API Route 대신 Server Actions를 사용하여 데이터 변이(Mutation)를 처리해야 함 (link)

Comment on lines +33 to +53
const reset = (
payload: ResetPasswordRequest,
options: { onSuccess: () => void; onError: (msg?: string) => void },
) => {
mutation.mutate(payload, {
onSuccess: (data) => {
if (data.status === 200) {
options.onSuccess();
} else {
options.onError(data.message);
}
},
onError: (error) => {
if (isAxiosError(error) && error.response?.data?.message) {
options.onError(error.response.data.message);
} else {
options.onError();
}
},
});
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

useMutation의 mutate 함수는 이미 onSuccess와 onError 콜백을 지원하므로, 이를 래핑하는 별도의 reset 함수를 정의하는 것은 다소 중복적입니다. 또한 Axios는 기본적으로 2xx 이외의 응답에 대해 에러를 발생시키므로 로직을 단순화할 수 있으나, 에러 핸들링 시 컨텍스트 보존을 위해 원래의 에러 객체를 그대로 던져야 합니다.

References
  1. API 에러 핸들링 시 컨텍스트(상태 코드 등)를 보존하기 위해 새로운 일반 에러를 생성하는 대신 원래의 에러 객체를 던져야 함

import { Check, Eye, EyeOff, X } from "lucide-react";
import { useResetPassword } from "@/hooks/useResetPassword";

const ScreenNewPasswordPage = () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

컴포넌트 파일이 200줄을 초과하고 있습니다. 가독성과 유지보수성을 위해 입력 필드 등을 별도의 서브 컴포넌트로 분리하는 것을 권장합니다. 특히 비밀번호 조건 체크와 같은 검증 로직은 순수 함수이므로, 공통 유틸리티 파일로 추출하여 관심사를 분리하고 재사용성을 높여야 합니다.

References
  1. 컴포넌트 파일이 200줄을 초과하면 더 작은 서브 컴포넌트로 분리 권장 (link)
  2. 검증 로직과 같은 순수 함수는 재사용성과 관심사 분리를 위해 공통 유틸리티 파일로 추출해야 함

Comment on lines 78 to 85
const handleVerify = (e: React.FormEvent) => {
e.preventDefault();
setIsVerifying(true);

// TODO: 인증번호 확인 API 연동
console.log("Verifying code:", verificationCode);

if (verificationCode === "123456") {
// 성공 시 세션 저장 후 비밀번호 재설정 입력 페이지로 이동
sessionStorage.setItem("reset_verified", "true");
// 인증 완료 시 이전 단계 정보는 유지(new 페이지 접근용)하되, success 도달 시 파기할 예정
alert("인증에 성공했습니다.");
router.replace("/reset/password/new");
} else {
setErrorMessage("인증번호를 다시 확인해 주세요.");
setIsVerifying(false);
}
// 인증코드와 이메일을 sessionStorage에 저장만 하고 새 비밀번호 페이지에서 PATCH API 호출
// (PATCH /api/auth/password/code 는 email+code+newPassword 를 한 번에 요청)
sessionStorage.setItem("reset_verified", "true");
sessionStorage.setItem("reset_code", verificationCode);
router.replace("/reset/password/new");
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

인증번호를 서버에서 즉시 검증하지 않고 sessionStorage에 저장한 뒤 다음 페이지로 넘기는 방식은 사용자 경험 측면에서 개선이 필요합니다. 사용자가 잘못된 번호를 입력했을 때 alert() 등을 통해 즉각적인 피드백을 줄 수 있도록 이 단계에서 검증 API를 호출하는 로직을 추가하는 것이 좋습니다.

References
  1. 에러 메시지 표시를 위해 토스트 알림 대신 네이티브 alert() 함수 사용을 선호함

Comment on lines +14 to +17
const { data } = await axios.post<SendPasswordCodeResponse>(
`${process.env.NEXT_PUBLIC_API_URL}/api/auth/password/code`,
{ email },
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Bypass shared axios instance 🐞 Bug ☼ Reliability

useSendPasswordCode/useResetPassword가 프로젝트 공통 axios 인스턴스(api)를 쓰지 않고 raw axios +
NEXT_PUBLIC_API_URL을 직접 조합해 호출하여 withCredentials/401 재발급 인터셉터/공통 설정이 적용되지 않습니다. 또한
NEXT_PUBLIC_API_URL이 비어있을 경우 "undefined/api/..." 같은 잘못된 URL로 요청이 나갈 수 있습니다.
Agent Prompt
## Issue description
`useSendPasswordCode` / `useResetPassword`가 `axios`를 직접 사용하면서 프로젝트 공통 설정(`baseURL`, `withCredentials`, 401 재발급 인터셉터)을 우회합니다. 또한 `NEXT_PUBLIC_API_URL` 누락 시 문자열 결합으로 잘못된 URL("undefined/api/...")이 만들어질 수 있습니다.

## Issue Context
레포에는 `lib/axios.ts`에서 `api` 인스턴스를 만들고, 다른 훅들은 `api.post('/api/...')` 형태로 호출합니다.

## Fix Focus Areas
- hooks/useSendPasswordCode.ts[1-18]
- hooks/useResetPassword.ts[1-25]
- lib/axios.ts[3-42]

## What to change
- 두 훅에서 `import axios from "axios"` 대신 `import { api } from "@/lib/axios"` 사용
- URL은 `${process.env...}` 조합 대신 상대경로로 호출: 
  - `api.post("/api/auth/password/code", { email })`
  - `api.patch("/api/auth/password/code", payload)`
- (선택) 필요 시 에러 메시지 파싱은 기존 `useVerifyEmail` 패턴 유지

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +46 to +52
const email = sessionStorage.getItem("reset_email_to_verify") ?? "";
const code = sessionStorage.getItem("reset_code") ?? "";

reset(
{ email, code, newPassword: password },
{
onSuccess: () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Reset payload may be empty 🐞 Bug ≡ Correctness

ScreenNewPasswordPage가 sessionStorage에서 email/code를 못 읽으면 빈 문자열로 대체한 뒤 그대로 PATCH 요청을 보내 invalid
request를 발생시킵니다. reset_verified만 검사하므로 sessionStorage가 중간에 지워지거나 불일치할 때 사용자는 복구 없이 실패 메시지만 보게 됩니다.
Agent Prompt
## Issue description
`/reset/password/new`에서 `reset_email_to_verify` 또는 `reset_code`가 없을 때도 빈 문자열로 PATCH 요청을 보내 플로우가 깨집니다.

## Issue Context
현재는 `reset_verified === 'true'`만 확인하고, `email/code` 유효성은 보장되지 않습니다(사용자 스토리지 삭제/브라우저 정책/이전 플로우 잔재 등).

## Fix Focus Areas
- app/reset/password/new/_components/ScreenNewPasswordPage.tsx[26-65]

## What to change
- `handleSubmit`에서 `email`/`code`가 비어있으면:
  - 에러 메시지 표시(예: "세션이 만료되었습니다. 처음부터 다시 시도해 주세요")
  - `reset_verified`, `reset_email_to_verify`, `reset_code` 정리 후 `/reset/password`로 이동
- `code.length === 6` 같은 최소 검증도 함께 적용

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant