Skip to content

feat: 견적요청 API 연동 및 토스트 피드백 추가 - #12

Merged
juengseulki merged 3 commits into
devfrom
feature/estimate-request
Jul 24, 2026
Merged

feat: 견적요청 API 연동 및 토스트 피드백 추가#12
juengseulki merged 3 commits into
devfrom
feature/estimate-request

Conversation

@youngmis

@youngmis youngmis commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

📋 작업 내용

  1. 견적요청 폼의 [견적 요청하기] 버튼에 백엔드 POST API에 연결
  2. 인증 토큰 처리
  3. 견적 요청 결과를 시각적으로 확인할 수 있도록 성공/실패 토스트를 추가

🔥 변경 사항

  1. src/components/common/Toast.tsx: 견적요청 성공/실패 메시지를 화면 상단에 띄우는 공통 토스트 컴포넌트

  2. src/components/estimate/EstimateRequestForm.tsx: 선택한 이사 유형·날짜·출발지/도착지를 백엔드 POST 형식으로 보내고, 제출 결과에 따라 토스트를 띄우도록 연결 (현재는 로그인 후 테스트를 위해 하드코딩으로 계정 포함 -> 추후 삭제 예정)

  3. src/lib/api/auth.ts: 백엔드 로그인 API(/auth/login)를 호출하여 로그인 성공 시 access/refresh 토큰을 저장해 이후 API 요청에서 사용

  4. src/lib/api/axiosInstance.ts: 기존 파일 중 요청 인터셉터에서 access token을 Authorization: Bearer 헤더에 자동으로 붙여, 인증이 필요한 API를 공통으로 호출할 수 있도록 로직 추가

  5. src/lib/api/estimateRequest.ts: 프론트 선택값(small/home/office, Date, 주소 객체)을 백엔드 스키마(SMALL/HOME/OFFICE, YYYY-MM-DD, from/to 주소)로 변환해 POST /estimate-requests로 전송

  6. src/lib/auth/token.ts: access/refresh 토큰을 localStorage에 저장·조회·삭제하는 유틸

  7. src/lib/constants/apiRoutes.ts: 백엔드 실제 경로에 맞게 인증 관련 라우트(LOGIN, LOGOUT, SIGN_UP_CUSTOMER 등)를 수정·추가한 파일

  8. src/lib/utils/date.ts: 날짜 유틸에 formatDateToISODate를 추가(Date 객체를 백엔드 moveDate 형식인 YYYY-MM-DD 문자열로 변환)


✅ 체크리스트

  • 로컬에서 정상 동작을 확인했습니다.
  • 기존 기능에 영향을 주지 않는지 확인했습니다.
  • 불필요한 console.log를 제거했습니다.
  • lint를 통과했습니다.
  • README 또는 문서를 수정했습니다. (필요 시)
  • API 명세와 일치하는지 확인했습니다.

📷 스크린샷 (선택)

image

🔗 관련 이슈

Closes #


💬 To Reviewer

  1. 견적 성공/실패 시. 뜨는 토스트 디자인 및 노출 시간(3초)이 너무 짧지 않은지 괜찮은지 확인해주세요.
  2. 더불어 백엔드 POST 연동 방식 확인부탁드립니다.
  3. 현재는 요청 POST 테스트를 위해 하드코딩된 계정 및 자동로그인 로직이 들어가있지만 추후 GNB가 합쳐지면 삭제 예정입니다. 하단 코드는 무시해주세요!
  • 하드 코딩 계정 삭제 예정
    const TEST_CUSTOMER = {
    email: "customer1@test.com",
    password: "Moving123!",
    } as const;

  • async function ensureLogin() 페이지 로드 시 자동로그인 관련 로직 삭제 예정

Summary by CodeRabbit

  • New Features
    • 상단에 자동으로 사라지는 토스트 알림을 추가했습니다.
    • 견적 요청 폼 제출 흐름을 개선하고(주소/일자/이동 정보), 진행 중 버튼 상태와 메시지를 보다 명확히 표시합니다.
    • 로그인 처리 및 인증이 필요한 요청에 대한 자동 인증 처리를 추가했습니다.
  • Bug Fixes
    • 인증 만료 시 자동 갱신 및 재시도를 통해 요청 실패를 줄였습니다.
    • 주소/날짜 입력 형식 검증 및 오류 메시지 처리를 개선했습니다.

견적요청 폼을 백엔드 POST API에 연결하고,
인증 토큰 처리와 성공/실패 토스트를 추가했다.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

인증 API와 메모리 기반 토큰 관리, Axios 토큰 갱신, 견적 요청 페이로드 변환 및 제출 흐름이 추가되었습니다. 견적 요청 폼은 주소 객체, ZIP 검증, 로그인·mutation 상태와 토스트 피드백을 관리합니다.

Changes

견적 요청 흐름

Layer / File(s) Summary
인증 및 요청 인증
src/lib/constants/apiRoutes.ts, src/lib/api/auth.ts, src/lib/auth/token.ts, src/lib/api/axiosInstance.ts
인증 경로, 로그인·갱신·로그아웃 API, 메모리 액세스 토큰 저장, Axios 인증 헤더와 401 재시도를 구현합니다.
견적 요청 페이로드 및 API
src/lib/api/estimateRequest.ts, src/lib/utils/date.ts, src/lib/api/getApiError.ts
이동 유형과 주소 타입, 날짜 포맷, 주소 변환, 응답 오류 처리를 정의하고 견적 요청 POST를 구현합니다.
폼 제출과 토스트 피드백
src/components/estimate/EstimateRequestForm.tsx, src/components/common/Toast.tsx
폼이 주소·로그인·mutation 상태를 관리하고 ZIP 검증 후 요청을 제출합니다. 결과는 ARIA 상태 영역 토스트로 표시되며 자동 종료됩니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EstimateRequestForm
  participant login
  participant axiosInstance
  participant createEstimateRequest
  participant Toast

  EstimateRequestForm->>login: 로그인 상태 확보
  login->>axiosInstance: AUTH.LOGIN 또는 AUTH.REFRESH 요청
  axiosInstance-->>login: accessToken 반환 및 저장
  EstimateRequestForm->>createEstimateRequest: 견적 페이로드 제출
  createEstimateRequest->>axiosInstance: ESTIMATE_REQUESTS POST
  axiosInstance-->>createEstimateRequest: 성공 또는 오류 반환
  createEstimateRequest-->>EstimateRequestForm: 제출 결과 전달
  EstimateRequestForm->>Toast: 결과 메시지 표시
  Toast-->>EstimateRequestForm: durationMs 후 onClose 호출
Loading

Suggested reviewers: karrum5692

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 견적요청 API 연동과 토스트 피드백 추가라는 핵심 변경을 잘 요약하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/estimate-request

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/components/common/Toast.tsx (1)

44-49: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace arbitrary design values with project token utilities.

z-[60], h-[60px], max-w-[640px], rounded-[16px], and the raw shadow bypass the shared scale. Prefer existing token utilities (for example, rounded-16) and retain arbitrary values only where no token can represent the Figma requirement.

As per coding guidelines, “Use the project's existing design tokens for colors, fonts, spacing, radius, and shadows instead of hardcoding design values.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/common/Toast.tsx` around lines 44 - 49, Update the Toast
container classes in the component around the cn call to replace arbitrary
z-index, height, width, radius, and shadow values with the closest existing
project token utilities. Retain arbitrary values only when no matching token
exists, while preserving the current layout and appearance.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/estimate/EstimateRequestForm.tsx`:
- Around line 22-26: Remove the TEST_CUSTOMER credentials and the automatic
authentication/retry flow in EstimateRequestForm, including the effects and
submission logic that use them. Require a valid authenticated session before
allowing request submission; otherwise redirect the visitor to the existing
sign-in flow, preserving normal behavior for already authenticated users.

In `@src/lib/api/auth.ts`:
- Around line 31-34: Reject unsuccessful HTTP-200 envelopes before treating
either operation as successful: in src/lib/api/auth.ts lines 31-34, update login
to validate data.success before setAuthTokens and throw on failure; in
src/lib/api/estimateRequest.ts lines 68-75, validate the response success flag
and throw on false so React Query invokes onError. Preserve the existing success
handling when the flag is true.

In `@src/lib/auth/token.ts`:
- Around line 14-16: Update setAuthTokens so it no longer writes
tokens.refreshToken to localStorage via REFRESH_TOKEN_KEY; preserve only the
browser-readable access-token handling and move refresh-token persistence to the
existing secure, HttpOnly, SameSite cookie mechanism, or add that mechanism if
none exists.

---

Nitpick comments:
In `@src/components/common/Toast.tsx`:
- Around line 44-49: Update the Toast container classes in the component around
the cn call to replace arbitrary z-index, height, width, radius, and shadow
values with the closest existing project token utilities. Retain arbitrary
values only when no matching token exists, while preserving the current layout
and appearance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 11bc6e48-7feb-419e-8d5b-128310287089

📥 Commits

Reviewing files that changed from the base of the PR and between c0b9d55 and 0790906.

📒 Files selected for processing (8)
  • src/components/common/Toast.tsx
  • src/components/estimate/EstimateRequestForm.tsx
  • src/lib/api/auth.ts
  • src/lib/api/axiosInstance.ts
  • src/lib/api/estimateRequest.ts
  • src/lib/auth/token.ts
  • src/lib/constants/apiRoutes.ts
  • src/lib/utils/date.ts

Comment thread src/components/estimate/EstimateRequestForm.tsx
Comment thread src/lib/api/auth.ts Outdated
Comment thread src/lib/auth/token.ts Outdated

@juengseulki juengseulki left a comment

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.

📋 PR 리뷰

견적 요청 폼을 백엔드 API에 연결하고 요청 결과를 토스트로 안내하는 작업 확인했습니다.

👍 좋았던 점

  • 견적 요청 API 호출을 별도 파일로 분리하여 폼 컴포넌트가 HTTP 요청 세부 구현을 직접 담당하지 않도록 구성한 점이 좋았습니다.
  • 화면의 small, home, office 값을 백엔드 Enum인 SMALL, HOME, OFFICE로 변환하는 책임을 API 계층에 둔 점이 적절했습니다.
  • 카카오 주소 결과를 백엔드의 from, to 스키마에 맞게 변환하는 함수가 분리되어 있어 요청 데이터 구성이 명확했습니다.
  • 날짜 변환 로직을 공통 날짜 유틸로 분리하여 폼 안에서 직접 문자열을 조합하지 않은 점도 좋았습니다.
  • 요청 중에는 버튼을 비활성화하고 문구를 요청 중...으로 변경하여 중복 제출을 방지한 점이 좋았습니다.
  • 토스트에 role="status"aria-live="polite"를 적용하여 메시지가 보조 기술에도 전달되도록 고려한 점도 확인했습니다.
  • 요청 인터셉터에서 Access Token을 공통으로 추가하도록 구성하여 인증이 필요한 API마다 헤더를 반복 작성하지 않도록 한 점이 좋았습니다.

🔍 확인 및 제안

  • 현재 모든 실패 상황에 기존 견적 확인을 안내하는 동일한 토스트가 표시되므로, 기본 실패 메시지와 오류별 메시지를 구분하면 좋을 것 같습니다.
  • 토스트 노출 시간 3초는 일반적인 성공·실패 안내를 읽기에 크게 짧아 보이지 않습니다. 다만 실패 메시지가 두 문장 이상으로 길어진다면 4초 정도로 늘리거나 닫기 버튼을 제공하는 방안도 고려할 수 있습니다.

API 요청 데이터 변환과 공통 인증 헤더 적용은 역할에 맞게 잘 분리되어 있었습니다. 다만 테스트 계정 정보와 자동 로그인 로직은 사용자 인증과 실제 데이터 생성에 직접 영향을 주고 클라이언트에 계정 정보가 노출되는 문제도 있으므로, 추후 작업으로 넘기기보다 이번 PR에서 제거한 뒤 병합하는 것이 필요해 보입니다. 수고하셨습니다! 😊

Comment thread src/components/estimate/EstimateRequestForm.tsx Outdated
XSS에 노출되는 refresh 토큰 저장을 제거하고, 실패 토스트는 오류 코드에 맞게 표시합니다.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/api/getApiError.ts`:
- Around line 21-22: Update the Error handling in getApiError so custom API
errors preserve and return their code alongside the message. Ensure
estimateRequest’s success:false path throws that custom error with both code and
message, and change downstream error branching to use error.code rather than
comparing error.message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ca33fb87-4196-45c8-b0c5-051757017b15

📥 Commits

Reviewing files that changed from the base of the PR and between 0790906 and 30242b5.

📒 Files selected for processing (6)
  • src/components/estimate/EstimateRequestForm.tsx
  • src/lib/api/auth.ts
  • src/lib/api/axiosInstance.ts
  • src/lib/api/estimateRequest.ts
  • src/lib/api/getApiError.ts
  • src/lib/auth/token.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/api/estimateRequest.ts
  • src/components/estimate/EstimateRequestForm.tsx

Comment thread src/lib/api/getApiError.ts
@juengseulki
juengseulki merged commit 10d9ebf into dev Jul 24, 2026
1 check passed
}, durationMs);

return () => window.clearTimeout(timer);
}, [open, durationMs, onClose]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

deps에 message가 없어서 토스트가 떠 있는 동안 새 토스트를 띄우면 타이머가 리셋되지 않고 일찍 닫힐 수 있을 것 같아요.
deps에 message를 추가하는 것도 좋을 것 같습니다!

Comment on lines +80 to +82
if (!data.success) {
throw new Error(data.error?.message || data.message || "견적 요청이 실패하였습니다.");
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

여기서 messageError에 담겨서 code가 사용되지 않는 것 같습니다.
이 경우 ACTIVE_REQUEST_EXISTS 분기가 동작하지 않을 수 있어서, 서버에서 에러 응답이 어떤 형태로 내려오는지 한번 확인해보시면 좋을 것 같습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants