임동욱 임동욱 09-03
Merge branch 'claude/confident-bell-efa28b' into hub
@784fbb02ef39add0684c1598971eac191c6b96d2
app/(protected)/(basic)/system/merchants/_actions.ts
--- app/(protected)/(basic)/system/merchants/_actions.ts
+++ app/(protected)/(basic)/system/merchants/_actions.ts
@@ -1,21 +1,22 @@
 'use server';
 
-import { unstable_rethrow } from 'next/navigation';
-import { revalidatePath } from 'next/cache';
 import { verifySession } from '@/lib/auth/dal';
-import { BackendRequestError } from '@/lib/http/backend-fetch';
-import { createMerchant } from '@/lib/data/repositories/merchant-repository';
 import {
   validateMerchant,
   type MerchantFormState,
 } from '@/lib/domain/merchant-form';
-import { MERCHANTS_PATH } from '@/lib/domain/merchant-query';
 
-const SAVE_FAILED_MESSAGE = '저장하지 못했습니다. 잠시 후 다시 시도해 주세요.';
-
-function failureMessage(error: unknown, fallback: string): string {
-  return error instanceof BackendRequestError ? error.message : fallback;
-}
+/**
+ * TODO(백엔드): 등록이 자체 저장에서 BizPlay 외부 가맹점 등록 API 위임으로 바뀌었다 —
+ *   `POST /api/v1/mngr/voc`가 @RequestBody(JSON)가 되고 `bizPlayVocApiService.insertVoc`를
+ *   부른다. 예금주명·입금은행코드·입금계좌번호·업태코드가 새로 필수인데 이 폼은 받지 않는다.
+ *   항목이 정해질 때까지 등록을 막는다.
+ *
+ *   화면의 [등록] 버튼만 비활성화하면 막은 것이 아니다 — Server Action은 UI를 거치지 않고도
+ *   직접 호출된다. 그래서 저장 직전에서 끊는다.
+ */
+const DISABLED_MESSAGE =
+  '가맹점 등록은 현재 사용할 수 없습니다. 등록 항목이 확정되면 다시 열립니다.';
 
 function readString(formData: FormData, key: string): string {
   const value = formData.get(key);
@@ -48,15 +49,5 @@
     return { status: 'error', errors: validation.errors };
   }
 
-  // TODO(백엔드): 수정 API가 없다(`/api/v1/mngr/voc`는 목록·등록 둘뿐). 생기면 여기서 가른다.
-  try {
-    await createMerchant(validation.values);
-  } catch (error) {
-    // 이슈: 세션이 밀렸을 때 backendFetch가 던지는 redirect를 이 catch가 삼키면 안 된다.
-    unstable_rethrow(error);
-    return { status: 'error', message: failureMessage(error, SAVE_FAILED_MESSAGE) };
-  }
-
-  revalidatePath(MERCHANTS_PATH);
-  return { status: 'success' };
+  return { status: 'error', message: DISABLED_MESSAGE };
 }
app/(protected)/(basic)/system/merchants/_components/merchant-list.tsx
--- app/(protected)/(basic)/system/merchants/_components/merchant-list.tsx
+++ app/(protected)/(basic)/system/merchants/_components/merchant-list.tsx
@@ -1,7 +1,6 @@
 'use client';
 
 import { useRouter } from 'next/navigation';
-import { useState } from 'react';
 import { FoxButton } from '@fox/core/components/fox-button';
 import {
   FoxListContainer,
@@ -28,7 +27,6 @@
   type MerchantQuery,
   type MerchantSearchField,
 } from '@/lib/domain/merchant-query';
-import { MerchantFormModal } from './merchant-form-modal';
 import { MerchantRowActions } from './merchant-row-actions';
 import styles from './merchant-filter.module.scss';
 
@@ -51,7 +49,6 @@
   totalCount,
 }: MerchantListProps) {
   const router = useRouter();
-  const [isCreateOpen, setIsCreateOpen] = useState(false);
 
   function go(patch: Partial<MerchantQuery>) {
     router.replace(buildMerchantHref(query, { ...patch, page: 1 }));
@@ -200,6 +197,10 @@
                 label="엑셀다운로드"
               />
             </form>
+            {/* TODO(백엔드): 등록이 자체 저장에서 BizPlay 외부 가맹점 등록 API 위임으로 바뀌었다
+                (`POST /api/v1/mngr/voc`가 @RequestBody JSON이 되고 bizPlayVocApiService.insertVoc를
+                부른다). 예금주명·입금은행코드·입금계좌번호·업태코드가 새로 필요한데 이 폼은 받지
+                않는다. 항목이 정해지면 MerchantFormModal과 함께 다시 연다. */}
             <FoxButton
               type="primary"
               size="md"
@@ -207,7 +208,7 @@
                 <i className="fox-ico fox-ico-Plus" aria-hidden="true" />
               }
               label="등록"
-              onAction={() => setIsCreateOpen(true)}
+              disabled
             />
             <FoxButton
               type="default"
@@ -232,10 +233,6 @@
           }
         }}
       />
-
-      {isCreateOpen && (
-        <MerchantFormModal onClose={() => setIsCreateOpen(false)} />
-      )}
     </>
   );
 }
lib/data/repositories/merchant-repository.ts
--- lib/data/repositories/merchant-repository.ts
+++ lib/data/repositories/merchant-repository.ts
@@ -154,6 +154,13 @@
     : [];
 }
 
+/**
+ * TODO(백엔드): 아래 form 전송은 옛 계약이다. 지금 `POST /api/v1/mngr/voc`는 @RequestBody(JSON)
+ *   `MngrVocInsertReqVo`를 받고 BizPlay 외부 API로 위임하며, 예금주명(bankDpstrNm)·입금은행코드
+ *   (dpstBankCd)·입금계좌번호(dpstActNo)·업태코드(frcsBzstatCd)를 새로 요구한다. lat·lng는 요청
+ *   VO에서 빠졌다. 등록 화면이 그 항목을 받게 되면 이 함수를 JSON으로 바꿔 다시 연결한다
+ *   (현재 호출부 없음 — `_actions.ts` 참고).
+ */
 export async function createMerchant(values: MerchantValues): Promise<void> {
   const accessToken = await getSessionAccessToken();
 
Add a comment
List