feat(ui): 문서 추출 실패/저신뢰 시 CSV 전환 동선 및 후보 테이블 선택 UI 추가#41
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 98bfb0852d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| UI.candidateTableSelect.innerHTML = candidateTables.map((table, idx) => { | ||
| const label = table?.label || table?.name || `후보 ${idx + 1}`; | ||
| const score = toNumberOrNull(table?.confidence ?? table?.score); | ||
| const suffix = score === null ? '' : ` (신뢰도 ${score.toFixed(2)})`; | ||
| return `<option value="${idx}">${label}${suffix}</option>`; |
There was a problem hiding this comment.
Escape candidate labels before setting select innerHTML
renderCandidateTableSelection writes table.label/table.name directly into innerHTML, so analyze-response data is treated as markup instead of plain text. If a candidate label contains HTML (for example from extracted document content), it can break the DOM or inject executable elements in the page context; this is especially risky because the value comes from server response data, not a trusted constant. Build the <option> nodes with document.createElement and textContent (or escape the label) to prevent HTML injection.
Useful? React with 👍 / 👎.
| setMode('quick'); | ||
| if (UI.inputType) UI.inputType.value = 'csv'; | ||
| UI.csvFile?.focus(); | ||
| setStatus('CSV 업로드로 전환되었습니다. CSV 파일을 선택한 뒤 다시 분석하세요.'); |
There was a problem hiding this comment.
Clear stale file selection when switching to CSV mode
The CSV-switch click handler only changes inputType to csv but keeps the previous file selection intact, so users who came from an extraction failure can immediately re-run analysis against the old non-CSV file. In buildAnalyzeRequest, that stale file is then read with file.text() as if it were CSV, which commonly produces another parsing failure instead of actually switching workflows. Resetting the file input (or forcing a new CSV pick) when this button is used would prevent this retry loop.
Useful? React with 👍 / 👎.
Motivation
error_detail패널과 일관되게 오류 세부 정보를 연결해 디버깅 경험을 개선하려고 했습니다.Description
analyzeAssist를 추가하고confidenceBadge,switchToCsvBtn,analyzeRecommendation,candidateTableWrap,candidateTableSelect,candidateTablePreview마크업을 추가했습니다 (bitnet_tools/ui/index.html).confidence,confidence_threshold,candidate_tables,error_detail, 추출 실패 플래그 등)를 통합 파싱하는 유틸을 추가하고(extractAnalyzeSignals), 이를 기반으로 보조 UI를 렌더링하도록 구현했습니다 (bitnet_tools/ui/app.js).renderCandidateTableSelection,renderCandidateTablePreview).resetAnalyzeAssist) 및 응답 직후 보조 UI 표시(renderAnalyzeAssist)를 호출하도록 통합했습니다.CSV 업로드로 전환버튼 클릭 핸들러를 바인딩했고, 후보 선택 변경 이벤트를 바인딩했습니다.error_detail을 발견하면 기존 오류 상세 패널(showError)에 내용을 채워 일관된 오류 노출을 유지합니다.bitnet_tools/ui/index.html,bitnet_tools/ui/app.js(프론트엔드 변경만, 백엔드 API 계약 변경 없음).Testing
node --check bitnet_tools/ui/app.js로 문법 검사(정상 종료) — 성공.python -m bitnet_tools.cli ui --host 0.0.0.0 --port 8765로 서버 기동 후 접속 확인 — 성공.http://127.0.0.1:8765에 접속해fetch를 mock(저신뢰 + 복수 후보 시나리오)한 뒤 보조 UI 렌더링을 검증하고 스크린샷을 캡처함(artifacts/ui-analyze-assist.png) — 성공.Codex Task