Merge branch 'claude/confident-bell-efa28b' into hub
@784fbb02ef39add0684c1598971eac191c6b96d2
--- app/(protected)/(basic)/system/merchants/_actions.ts
+++ app/(protected)/(basic)/system/merchants/_actions.ts
... | ... | @@ -1,21 +1,22 @@ |
| 1 | 1 |
'use server'; |
| 2 | 2 |
|
| 3 |
-import { unstable_rethrow } from 'next/navigation';
|
|
| 4 |
-import { revalidatePath } from 'next/cache';
|
|
| 5 | 3 |
import { verifySession } from '@/lib/auth/dal';
|
| 6 |
-import { BackendRequestError } from '@/lib/http/backend-fetch';
|
|
| 7 |
-import { createMerchant } from '@/lib/data/repositories/merchant-repository';
|
|
| 8 | 4 |
import {
|
| 9 | 5 |
validateMerchant, |
| 10 | 6 |
type MerchantFormState, |
| 11 | 7 |
} from '@/lib/domain/merchant-form'; |
| 12 |
-import { MERCHANTS_PATH } from '@/lib/domain/merchant-query';
|
|
| 13 | 8 |
|
| 14 |
-const SAVE_FAILED_MESSAGE = '저장하지 못했습니다. 잠시 후 다시 시도해 주세요.'; |
|
| 15 |
- |
|
| 16 |
-function failureMessage(error: unknown, fallback: string): string {
|
|
| 17 |
- return error instanceof BackendRequestError ? error.message : fallback; |
|
| 18 |
-} |
|
| 9 |
+/** |
|
| 10 |
+ * TODO(백엔드): 등록이 자체 저장에서 BizPlay 외부 가맹점 등록 API 위임으로 바뀌었다 — |
|
| 11 |
+ * `POST /api/v1/mngr/voc`가 @RequestBody(JSON)가 되고 `bizPlayVocApiService.insertVoc`를 |
|
| 12 |
+ * 부른다. 예금주명·입금은행코드·입금계좌번호·업태코드가 새로 필수인데 이 폼은 받지 않는다. |
|
| 13 |
+ * 항목이 정해질 때까지 등록을 막는다. |
|
| 14 |
+ * |
|
| 15 |
+ * 화면의 [등록] 버튼만 비활성화하면 막은 것이 아니다 — Server Action은 UI를 거치지 않고도 |
|
| 16 |
+ * 직접 호출된다. 그래서 저장 직전에서 끊는다. |
|
| 17 |
+ */ |
|
| 18 |
+const DISABLED_MESSAGE = |
|
| 19 |
+ '가맹점 등록은 현재 사용할 수 없습니다. 등록 항목이 확정되면 다시 열립니다.'; |
|
| 19 | 20 |
|
| 20 | 21 |
function readString(formData: FormData, key: string): string {
|
| 21 | 22 |
const value = formData.get(key); |
... | ... | @@ -48,15 +49,5 @@ |
| 48 | 49 |
return { status: 'error', errors: validation.errors };
|
| 49 | 50 |
} |
| 50 | 51 |
|
| 51 |
- // TODO(백엔드): 수정 API가 없다(`/api/v1/mngr/voc`는 목록·등록 둘뿐). 생기면 여기서 가른다. |
|
| 52 |
- try {
|
|
| 53 |
- await createMerchant(validation.values); |
|
| 54 |
- } catch (error) {
|
|
| 55 |
- // 이슈: 세션이 밀렸을 때 backendFetch가 던지는 redirect를 이 catch가 삼키면 안 된다. |
|
| 56 |
- unstable_rethrow(error); |
|
| 57 |
- return { status: 'error', message: failureMessage(error, SAVE_FAILED_MESSAGE) };
|
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- revalidatePath(MERCHANTS_PATH); |
|
| 61 |
- return { status: 'success' };
|
|
| 52 |
+ return { status: 'error', message: DISABLED_MESSAGE };
|
|
| 62 | 53 |
} |
--- app/(protected)/(basic)/system/merchants/_components/merchant-list.tsx
+++ app/(protected)/(basic)/system/merchants/_components/merchant-list.tsx
... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 |
'use client'; |
| 2 | 2 |
|
| 3 | 3 |
import { useRouter } from 'next/navigation';
|
| 4 |
-import { useState } from 'react';
|
|
| 5 | 4 |
import { FoxButton } from '@fox/core/components/fox-button';
|
| 6 | 5 |
import {
|
| 7 | 6 |
FoxListContainer, |
... | ... | @@ -28,7 +27,6 @@ |
| 28 | 27 |
type MerchantQuery, |
| 29 | 28 |
type MerchantSearchField, |
| 30 | 29 |
} from '@/lib/domain/merchant-query'; |
| 31 |
-import { MerchantFormModal } from './merchant-form-modal';
|
|
| 32 | 30 |
import { MerchantRowActions } from './merchant-row-actions';
|
| 33 | 31 |
import styles from './merchant-filter.module.scss'; |
| 34 | 32 |
|
... | ... | @@ -51,7 +49,6 @@ |
| 51 | 49 |
totalCount, |
| 52 | 50 |
}: MerchantListProps) {
|
| 53 | 51 |
const router = useRouter(); |
| 54 |
- const [isCreateOpen, setIsCreateOpen] = useState(false); |
|
| 55 | 52 |
|
| 56 | 53 |
function go(patch: Partial<MerchantQuery>) {
|
| 57 | 54 |
router.replace(buildMerchantHref(query, { ...patch, page: 1 }));
|
... | ... | @@ -200,6 +197,10 @@ |
| 200 | 197 |
label="엑셀다운로드" |
| 201 | 198 |
/> |
| 202 | 199 |
</form> |
| 200 |
+ {/* TODO(백엔드): 등록이 자체 저장에서 BizPlay 외부 가맹점 등록 API 위임으로 바뀌었다
|
|
| 201 |
+ (`POST /api/v1/mngr/voc`가 @RequestBody JSON이 되고 bizPlayVocApiService.insertVoc를 |
|
| 202 |
+ 부른다). 예금주명·입금은행코드·입금계좌번호·업태코드가 새로 필요한데 이 폼은 받지 |
|
| 203 |
+ 않는다. 항목이 정해지면 MerchantFormModal과 함께 다시 연다. */} |
|
| 203 | 204 |
<FoxButton |
| 204 | 205 |
type="primary" |
| 205 | 206 |
size="md" |
... | ... | @@ -207,7 +208,7 @@ |
| 207 | 208 |
<i className="fox-ico fox-ico-Plus" aria-hidden="true" /> |
| 208 | 209 |
} |
| 209 | 210 |
label="등록" |
| 210 |
- onAction={() => setIsCreateOpen(true)}
|
|
| 211 |
+ disabled |
|
| 211 | 212 |
/> |
| 212 | 213 |
<FoxButton |
| 213 | 214 |
type="default" |
... | ... | @@ -232,10 +233,6 @@ |
| 232 | 233 |
} |
| 233 | 234 |
}} |
| 234 | 235 |
/> |
| 235 |
- |
|
| 236 |
- {isCreateOpen && (
|
|
| 237 |
- <MerchantFormModal onClose={() => setIsCreateOpen(false)} />
|
|
| 238 |
- )} |
|
| 239 | 236 |
</> |
| 240 | 237 |
); |
| 241 | 238 |
} |
--- lib/data/repositories/merchant-repository.ts
+++ lib/data/repositories/merchant-repository.ts
... | ... | @@ -154,6 +154,13 @@ |
| 154 | 154 |
: []; |
| 155 | 155 |
} |
| 156 | 156 |
|
| 157 |
+/** |
|
| 158 |
+ * TODO(백엔드): 아래 form 전송은 옛 계약이다. 지금 `POST /api/v1/mngr/voc`는 @RequestBody(JSON) |
|
| 159 |
+ * `MngrVocInsertReqVo`를 받고 BizPlay 외부 API로 위임하며, 예금주명(bankDpstrNm)·입금은행코드 |
|
| 160 |
+ * (dpstBankCd)·입금계좌번호(dpstActNo)·업태코드(frcsBzstatCd)를 새로 요구한다. lat·lng는 요청 |
|
| 161 |
+ * VO에서 빠졌다. 등록 화면이 그 항목을 받게 되면 이 함수를 JSON으로 바꿔 다시 연결한다 |
|
| 162 |
+ * (현재 호출부 없음 — `_actions.ts` 참고). |
|
| 163 |
+ */ |
|
| 157 | 164 |
export async function createMerchant(values: MerchantValues): Promise<void> {
|
| 158 | 165 |
const accessToken = await getSessionAccessToken(); |
| 159 | 166 |
|
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?