[Feat/#107] 사장님 승격 및 결제 완료 처리 API 연동#109
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthrough결제 성공 흐름에 Kakao Pay 승인 후 admin settlement 완료 뮤테이션을 추가하고, owner 가입 흐름을 비즈니스 라이센스 검증에서 스토어 매니저 업그레이드로 변경하며, settlement-preview 기능을 제거하는 API 구조 개편입니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client<br/>(Payment Success Page)
participant API as Compasser API
participant QueryCache as React Query<br/>Cache
participant DB as Backend<br/>Database
Client->>API: POST /kakao/complete<br/>(reservationId)
API->>DB: 결제 승인 처리
DB-->>API: 승인 성공
API-->>Client: 성공 응답
Note over Client: 보류 중 결제에서<br/>storeId 추출
Client->>API: POST /admin/settlements/{storeId}/complete<br/>(reservationIds)
API->>DB: Settlement 완료 기록
DB-->>API: Settlement 완료 데이터
API-->>Client: 응답 반환
Client->>QueryCache: 캐시 업데이트<br/>(완료 결과 저장)
QueryCache->>QueryCache: Admin Settlement 데이터<br/>무효화 및 재검증
Note over Client: 모달 열기 & 세션 정리
Client->>Client: UI 업데이트 완료
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/owner/src/app/signup/business/page.tsx (1)
55-81:⚠️ Potential issue | 🟠 Major | ⚡ Quick win업그레이드 API와 검증 게이트가 불일치합니다.
Line 56-61에서 사업자번호 검증 실패 시 진행을 막고 있지만, Line 68에서 호출하는
upgradeMutation은undefined로 호출되어 해당 값을 전혀 사용하지 않습니다. 현재 상태면 “서버에 필요 없는 입력값” 때문에 승격이 차단될 수 있습니다.
/owners/upgrade플로우를 유지할 거라면 이 검증 게이트를 제거(또는 안내 문구/입력 UI 자체 정리)하고, 사업자 검증이 필수라면 검증 API 호출 플로우로 되돌려야 합니다.수정 예시 (업그레이드 API 기준)
const handleNext = () => { - const message = validate(); - - if (message) { - setError(message); - return; - } - if (!email) { router.replace("/signup"); return; } upgradeMutation.mutate(undefined, {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/owner/src/app/signup/business/page.tsx` around lines 55 - 81, The validation gate in handleNext (validate() and the email check) is inconsistent with calling upgradeMutation.mutate(undefined); fix by making the validation result feed the upgrade flow: after validate() succeeds, call upgradeMutation.mutate with the required payload (e.g., businessNumber and/or email) instead of undefined and/or call the business-validation API first and only call upgradeMutation on its success; update handleNext (and related UI) so validate(), email, and upgradeMutation.mutate(payload) all use the same required fields and remove any dead/contradictory checks if you choose to move validation server-side.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/customer/src/app/payment/success/page.tsx`:
- Around line 57-63: Wrap the JSON.parse of savedPayment in a try-catch and
handle parse failures (e.g., log the error and abort/redirect), and before
calling completeAdminSettlementMutation.mutate ensure parsedPayment is an object
with the expected shape (check parsedPayment?.store and
parsedPayment.store?.storeId) and that reservationId is defined; if validations
fail, bail out with a safe fallback or error path instead of accessing nested
fields directly in completeAdminSettlementMutation.mutate to prevent runtime
crashes.
---
Outside diff comments:
In `@apps/owner/src/app/signup/business/page.tsx`:
- Around line 55-81: The validation gate in handleNext (validate() and the email
check) is inconsistent with calling upgradeMutation.mutate(undefined); fix by
making the validation result feed the upgrade flow: after validate() succeeds,
call upgradeMutation.mutate with the required payload (e.g., businessNumber
and/or email) instead of undefined and/or call the business-validation API first
and only call upgradeMutation on its success; update handleNext (and related UI)
so validate(), email, and upgradeMutation.mutate(payload) all use the same
required fields and remove any dead/contradictory checks if you choose to move
validation server-side.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 41a7172d-d9a2-4b83-a5af-409b28c766f4
📒 Files selected for processing (11)
apps/customer/src/app/payment/success/page.tsxapps/customer/src/shared/api/api.tsapps/customer/src/shared/queries/mutation/admin-settlement/useCompleteAdminSettlementMutation.tsapps/owner/src/app/signup/business/page.tsxapps/owner/src/shared/queries/mutation/auth/useUpgradeToStoreManagerMutation.tsapps/owner/src/shared/queries/mutation/auth/useVerifyBusinessMutation.tspackages/api/src/domains/admin-settlement.tspackages/api/src/domains/owner.tspackages/api/src/index.tspackages/api/src/models/admin-settlement.tspackages/api/src/models/owner.ts
💤 Files with no reviewable changes (1)
- packages/api/src/domains/owner.ts
| completeAdminSettlementMutation.mutate( | ||
| { | ||
| storeId: parsedPayment.store.storeId, | ||
| body: { | ||
| reservationIds: [reservationId], | ||
| }, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 결제 성공 페이지에서 역직렬화/필드 접근 무가드 구간 확인
rg -n -C3 'JSON.parse\(savedPayment\)|parsedPayment\.store\.storeId|reservationIds:\s*\[' apps/customer/src/app/payment/success/page.tsxRepository: CUK-Compasser/FE
Length of output: 519
🏁 Script executed:
cat -n apps/customer/src/app/payment/success/page.tsxRepository: CUK-Compasser/FE
Length of output: 3646
🏁 Script executed:
# reservationId 변수 출처 확인
rg -n "reservationId" apps/customer/src/app/payment/success/page.tsx | head -20Repository: CUK-Compasser/FE
Length of output: 357
🏁 Script executed:
# savedPayment 변수 출처 및 초기값 확인
rg -n "savedPayment|sessionStorage" apps/customer/src/app/payment/success/page.tsx | head -20Repository: CUK-Compasser/FE
Length of output: 331
세션 데이터 파싱과 필드 접근이 무가드라 런타임 크래시 위험이 있습니다.
Line 46에서 JSON.parse(savedPayment)가 try-catch 없이 호출되고 있어, sessionStorage 데이터가 손상된 경우 SyntaxError로 결제 성공 플로우가 깨질 수 있습니다. 또한 Line 59의 parsedPayment.store.storeId 중첩 접근도 파싱된 객체의 구조를 검증하지 않아 TypeScript 타입 정보가 런타임에 제거되면 런타임 에러가 발생할 수 있습니다.
🔧 제안 수정안
- const parsedPayment = JSON.parse(savedPayment) as PendingPayment;
+ let parsedPayment: PendingPayment;
+ try {
+ parsedPayment = JSON.parse(savedPayment) as PendingPayment;
+ } catch {
+ sessionStorage.removeItem("pendingPayment");
+ return;
+ }
+
+ if (!parsedPayment?.store?.storeId || !parsedPayment?.reservationId) {
+ sessionStorage.removeItem("pendingPayment");
+ return;
+ }
setPendingPayment(parsedPayment);
approveKakaoPayMutation.mutate(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/customer/src/app/payment/success/page.tsx` around lines 57 - 63, Wrap
the JSON.parse of savedPayment in a try-catch and handle parse failures (e.g.,
log the error and abort/redirect), and before calling
completeAdminSettlementMutation.mutate ensure parsedPayment is an object with
the expected shape (check parsedPayment?.store and parsedPayment.store?.storeId)
and that reservationId is defined; if validations fail, bail out with a safe
fallback or error path instead of accessing nested fields directly in
completeAdminSettlementMutation.mutate to prevent runtime crashes.
✅ 작업 내용
📝 Description
PATCH /owners/upgrade연동POST /admin/settlements/{storeId}/complete연동🚀 설계 의도 및 개선점
📎 기타 참고사항
Summary by CodeRabbit
릴리스 노트
신기능
제거된 기능