From a3f62f309053904cbb8eba7391d7a1468d9c9944 Mon Sep 17 00:00:00 2001 From: HYOJIN Date: Fri, 20 Mar 2026 18:29:54 +0900 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=EC=8B=A4=ED=8C=A8=20=EA=B1=B4=20?= =?UTF-8?q?=EC=88=98=EB=8F=99=20=EC=9E=AC=EC=88=98=EC=A7=91=20=EC=8B=9C=20?= =?UTF-8?q?414=20Request-URI=20Too=20Long=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - retryRecordKeys URL 파라미터 제거 (서버에서 DB 조회로 대체) - sourceStepExecutionId → sourceJobExecutionId로 변경 - FailedRecordsToggle에 jobExecutionId 전달 --- frontend/src/api/batchApi.ts | 7 +++---- frontend/src/pages/ExecutionDetail.tsx | 11 ++++++----- frontend/src/pages/RecollectDetail.tsx | 11 +++++------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/frontend/src/api/batchApi.ts b/frontend/src/api/batchApi.ts index 581e7d6..8f99daa 100644 --- a/frontend/src/api/batchApi.ts +++ b/frontend/src/api/batchApi.ts @@ -363,13 +363,12 @@ export const batchApi = { `${BASE}/jobs/${jobName}/execute${qs}`); }, - retryFailedRecords: (jobName: string, recordKeys: string[], stepExecutionId: number) => { + retryFailedRecords: (jobName: string, failedCount: number, jobExecutionId: number) => { const qs = new URLSearchParams({ - retryRecordKeys: recordKeys.join(','), - sourceStepExecutionId: String(stepExecutionId), + sourceJobExecutionId: String(jobExecutionId), executionMode: 'RECOLLECT', executor: 'MANUAL_RETRY', - reason: `실패 건 수동 재수집 (${recordKeys.length}건)`, + reason: `실패 건 수동 재수집 (${failedCount}건)`, }); return postJson<{ success: boolean; message: string; executionId?: number }>( `${BASE}/jobs/${jobName}/execute?${qs.toString()}`); diff --git a/frontend/src/pages/ExecutionDetail.tsx b/frontend/src/pages/ExecutionDetail.tsx index f2c7707..f861986 100644 --- a/frontend/src/pages/ExecutionDetail.tsx +++ b/frontend/src/pages/ExecutionDetail.tsx @@ -40,9 +40,10 @@ const EXECUTION_DETAIL_GUIDE = [ interface StepCardProps { step: StepExecutionDto; jobName: string; + jobExecutionId: number; } -function StepCard({ step, jobName }: StepCardProps) { +function StepCard({ step, jobName, jobExecutionId }: StepCardProps) { const stats = [ { label: '읽기', value: step.readCount }, { label: '쓰기', value: step.writeCount }, @@ -158,7 +159,7 @@ function StepCard({ step, jobName }: StepCardProps) { {/* 호출 실패 데이터 토글 */} {step.failedRecords && step.failedRecords.length > 0 && ( - + )} {step.exitMessage && ( @@ -364,6 +365,7 @@ export default function ExecutionDetail() { key={step.stepExecutionId} step={step} jobName={detail.jobName} + jobExecutionId={executionId} /> ))} @@ -382,7 +384,7 @@ export default function ExecutionDetail() { const FAILED_PAGE_SIZE = 10; -function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: FailedRecordDto[]; jobName: string; stepExecutionId: number }) { +function FailedRecordsToggle({ records, jobName, jobExecutionId }: { records: FailedRecordDto[]; jobName: string; jobExecutionId: number }) { const [open, setOpen] = useState(false); const [showConfirm, setShowConfirm] = useState(false); const [showResolveConfirm, setShowResolveConfirm] = useState(false); @@ -419,8 +421,7 @@ function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: F const handleRetry = async () => { setRetrying(true); try { - const keys = failedRecords.map((r) => r.recordKey); - const result = await batchApi.retryFailedRecords(jobName, keys, stepExecutionId); + const result = await batchApi.retryFailedRecords(jobName, failedRecords.length, jobExecutionId); if (result.success) { setShowConfirm(false); if (result.executionId) { diff --git a/frontend/src/pages/RecollectDetail.tsx b/frontend/src/pages/RecollectDetail.tsx index f6e4f48..12bc3c4 100644 --- a/frontend/src/pages/RecollectDetail.tsx +++ b/frontend/src/pages/RecollectDetail.tsx @@ -20,7 +20,7 @@ import GuideModal, { HelpButton } from '../components/GuideModal'; const POLLING_INTERVAL_MS = 10_000; -function StepCard({ step, jobName }: { step: StepExecutionDto; jobName: string }) { +function StepCard({ step, jobName, jobExecutionId }: { step: StepExecutionDto; jobName: string; jobExecutionId: number }) { const stats = [ { label: '읽기', value: step.readCount }, { label: '쓰기', value: step.writeCount }, @@ -114,7 +114,7 @@ function StepCard({ step, jobName }: { step: StepExecutionDto; jobName: string } {/* 호출 실패 데이터 토글 */} {step.failedRecords && step.failedRecords.length > 0 && ( - + )} {step.exitMessage && ( @@ -434,7 +434,7 @@ export default function RecollectDetail() { ) : (
{stepExecutions.map((step) => ( - + ))}
)} @@ -452,7 +452,7 @@ export default function RecollectDetail() { const FAILED_PAGE_SIZE = 10; -function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: FailedRecordDto[]; jobName: string; stepExecutionId: number }) { +function FailedRecordsToggle({ records, jobName, jobExecutionId }: { records: FailedRecordDto[]; jobName: string; jobExecutionId: number }) { const [open, setOpen] = useState(false); const [showConfirm, setShowConfirm] = useState(false); const [showResolveConfirm, setShowResolveConfirm] = useState(false); @@ -489,8 +489,7 @@ function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: F const handleRetry = async () => { setRetrying(true); try { - const keys = failedRecords.map((r) => r.recordKey); - const result = await batchApi.retryFailedRecords(jobName, keys, stepExecutionId); + const result = await batchApi.retryFailedRecords(jobName, failedRecords.length, jobExecutionId); if (result.success) { setShowConfirm(false); if (result.executionId) {