fix(ui): 실패 건 수동 재수집 시 414 Request-URI Too Long 오류 수정

- retryRecordKeys URL 파라미터 제거 (서버에서 DB 조회로 대체)
- sourceStepExecutionId → sourceJobExecutionId로 변경
- FailedRecordsToggle에 jobExecutionId 전달
This commit is contained in:
HYOJIN 2026-03-20 18:29:54 +09:00
부모 859d290164
커밋 a3f62f3090
3개의 변경된 파일14개의 추가작업 그리고 15개의 파일을 삭제

파일 보기

@ -363,13 +363,12 @@ export const batchApi = {
`${BASE}/jobs/${jobName}/execute${qs}`); `${BASE}/jobs/${jobName}/execute${qs}`);
}, },
retryFailedRecords: (jobName: string, recordKeys: string[], stepExecutionId: number) => { retryFailedRecords: (jobName: string, failedCount: number, jobExecutionId: number) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
retryRecordKeys: recordKeys.join(','), sourceJobExecutionId: String(jobExecutionId),
sourceStepExecutionId: String(stepExecutionId),
executionMode: 'RECOLLECT', executionMode: 'RECOLLECT',
executor: 'MANUAL_RETRY', executor: 'MANUAL_RETRY',
reason: `실패 건 수동 재수집 (${recordKeys.length}건)`, reason: `실패 건 수동 재수집 (${failedCount}건)`,
}); });
return postJson<{ success: boolean; message: string; executionId?: number }>( return postJson<{ success: boolean; message: string; executionId?: number }>(
`${BASE}/jobs/${jobName}/execute?${qs.toString()}`); `${BASE}/jobs/${jobName}/execute?${qs.toString()}`);

파일 보기

@ -40,9 +40,10 @@ const EXECUTION_DETAIL_GUIDE = [
interface StepCardProps { interface StepCardProps {
step: StepExecutionDto; step: StepExecutionDto;
jobName: string; jobName: string;
jobExecutionId: number;
} }
function StepCard({ step, jobName }: StepCardProps) { function StepCard({ step, jobName, jobExecutionId }: StepCardProps) {
const stats = [ const stats = [
{ label: '읽기', value: step.readCount }, { label: '읽기', value: step.readCount },
{ label: '쓰기', value: step.writeCount }, { label: '쓰기', value: step.writeCount },
@ -158,7 +159,7 @@ function StepCard({ step, jobName }: StepCardProps) {
{/* 호출 실패 데이터 토글 */} {/* 호출 실패 데이터 토글 */}
{step.failedRecords && step.failedRecords.length > 0 && ( {step.failedRecords && step.failedRecords.length > 0 && (
<FailedRecordsToggle records={step.failedRecords} jobName={jobName} stepExecutionId={step.stepExecutionId} /> <FailedRecordsToggle records={step.failedRecords} jobName={jobName} jobExecutionId={jobExecutionId} />
)} )}
{step.exitMessage && ( {step.exitMessage && (
@ -364,6 +365,7 @@ export default function ExecutionDetail() {
key={step.stepExecutionId} key={step.stepExecutionId}
step={step} step={step}
jobName={detail.jobName} jobName={detail.jobName}
jobExecutionId={executionId}
/> />
))} ))}
</div> </div>
@ -382,7 +384,7 @@ export default function ExecutionDetail() {
const FAILED_PAGE_SIZE = 10; 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 [open, setOpen] = useState(false);
const [showConfirm, setShowConfirm] = useState(false); const [showConfirm, setShowConfirm] = useState(false);
const [showResolveConfirm, setShowResolveConfirm] = useState(false); const [showResolveConfirm, setShowResolveConfirm] = useState(false);
@ -419,8 +421,7 @@ function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: F
const handleRetry = async () => { const handleRetry = async () => {
setRetrying(true); setRetrying(true);
try { try {
const keys = failedRecords.map((r) => r.recordKey); const result = await batchApi.retryFailedRecords(jobName, failedRecords.length, jobExecutionId);
const result = await batchApi.retryFailedRecords(jobName, keys, stepExecutionId);
if (result.success) { if (result.success) {
setShowConfirm(false); setShowConfirm(false);
if (result.executionId) { if (result.executionId) {

파일 보기

@ -20,7 +20,7 @@ import GuideModal, { HelpButton } from '../components/GuideModal';
const POLLING_INTERVAL_MS = 10_000; 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 = [ const stats = [
{ label: '읽기', value: step.readCount }, { label: '읽기', value: step.readCount },
{ label: '쓰기', value: step.writeCount }, { label: '쓰기', value: step.writeCount },
@ -114,7 +114,7 @@ function StepCard({ step, jobName }: { step: StepExecutionDto; jobName: string }
{/* 호출 실패 데이터 토글 */} {/* 호출 실패 데이터 토글 */}
{step.failedRecords && step.failedRecords.length > 0 && ( {step.failedRecords && step.failedRecords.length > 0 && (
<FailedRecordsToggle records={step.failedRecords} jobName={jobName} stepExecutionId={step.stepExecutionId} /> <FailedRecordsToggle records={step.failedRecords} jobName={jobName} jobExecutionId={jobExecutionId} />
)} )}
{step.exitMessage && ( {step.exitMessage && (
@ -434,7 +434,7 @@ export default function RecollectDetail() {
) : ( ) : (
<div className="space-y-4"> <div className="space-y-4">
{stepExecutions.map((step) => ( {stepExecutions.map((step) => (
<StepCard key={step.stepExecutionId} step={step} jobName={history.jobName} /> <StepCard key={step.stepExecutionId} step={step} jobName={history.jobName} jobExecutionId={history.jobExecutionId ?? 0} />
))} ))}
</div> </div>
)} )}
@ -452,7 +452,7 @@ export default function RecollectDetail() {
const FAILED_PAGE_SIZE = 10; 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 [open, setOpen] = useState(false);
const [showConfirm, setShowConfirm] = useState(false); const [showConfirm, setShowConfirm] = useState(false);
const [showResolveConfirm, setShowResolveConfirm] = useState(false); const [showResolveConfirm, setShowResolveConfirm] = useState(false);
@ -489,8 +489,7 @@ function FailedRecordsToggle({ records, jobName, stepExecutionId }: { records: F
const handleRetry = async () => { const handleRetry = async () => {
setRetrying(true); setRetrying(true);
try { try {
const keys = failedRecords.map((r) => r.recordKey); const result = await batchApi.retryFailedRecords(jobName, failedRecords.length, jobExecutionId);
const result = await batchApi.retryFailedRecords(jobName, keys, stepExecutionId);
if (result.success) { if (result.success) {
setShowConfirm(false); setShowConfirm(false);
if (result.executionId) { if (result.executionId) {