diff --git a/docs/RELEASE-NOTES.md b/docs/RELEASE-NOTES.md index 3a74099..ce2765e 100644 --- a/docs/RELEASE-NOTES.md +++ b/docs/RELEASE-NOTES.md @@ -55,6 +55,7 @@ - AIS WebClient 버퍼 제한 50MB→100MB 확대 및 타임아웃 설정 추가 (DataBufferLimitException 해결) - ShipDetailUpdateDataReader beforeFetch에서 allImoNumbers 미할당으로 인한 NPE 수정 - 재수집 모드 afterFetch 중복 실행으로 인한 실패 레코드 중복 INSERT 수정 (#64) +- 실패 건 수동 재수집 시 414 Request-URI Too Long 오류 수정 (#71) ### 변경 - 재수집 실패건 추적 기준 sourceStepExecutionId → sourceJobExecutionId로 변경 (#64) 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) {