--- status: active created: 2026-06-03 type: quality title: Operator console quality improvement plan --- # Operator Console Quality Improvement Plan ## Scope This plan responds to the concrete quality issues raised during review of the current operator console: - static tests rely too heavily on string presence; - visible Korean copy is partially corrupted; - `web/operator-gui/app.js` carries too many responsibilities; - the case workbench still needs stronger next-action guidance; - submission upload and folder reload UX needs clearer operator feedback. - the product purpose is not explicit enough in the UI. ## 1. Strengthen Tests Beyond String Presence Problem: The operator GUI tests catch missing selectors and accidental deletion, but they do not prove the main flows work in a browser. Plan: - Keep static tests as fast contract checks. - Add server-backed behavior tests for upload, reload, and manual search. - Add future browser smoke tests for queue selection, workbench tab switching, and suggested-query fill behavior. Immediate action: Completed: - `tests/operator_gui/test_browser_smoke.py` now verifies the suggested-query browser flow: selecting a recommendation fills the manual query input without running a search. - `tests/operator_gui/test_browser_smoke.py` now verifies the real browser upload flow through the local HTTP server: file selection, `/api/submissions/upload-image`, saved image file, new queue item, workbench navigation, and selected uploaded submission. - `tests/rights_filter/server/test_http_app.py::test_http_server_uploads_submission_image_into_active_queue` verifies the upload HTTP contract saves the image into the active queue and returns the uploaded submission in the refreshed bootstrap payload. - `tests/operator_gui/test_static_workbench.py` retains fast structural checks and now also protects module load order, mojibake prevention, product purpose copy, workflow guidance, and upload UX contracts. ## 2. Repair Corrupted Korean Copy Problem: Several operator-facing status strings in `app.js` are mojibake. This weakens trust in a review tool. Plan: - Prioritize visible workflow copy over legacy compatibility strings. - Replace high-use status text first: reload, folder import, image upload, bulk rerun, manual search, and decision memo errors. - Keep compatibility-only tokens isolated until tests can be rewritten around clean labels. Immediate action: Completed: - Reload, folder import, upload, bulk rerun, manual search, evidence, provider, knowledge DB, candidate, correction, and empty-state copy were normalized to readable Korean. - A mojibake regression check now scans the operator GUI files for common corrupted UTF-8 fragments. - The operator GUI JavaScript files pass `node --check`. ## 3. Split `app.js` Responsibilities Problem: `app.js` owns queue rendering, workbench rendering, search, knowledge DB, provider controls, upload, and audit events. Plan: - First extract pure helpers: file payload reading, evidence sufficiency, query suggestions, and import status formatting. - Then split rendering domains into small static modules if the deployment can safely move to module scripts. - Avoid a broad framework migration. Immediate action: Completed: - `web/operator-gui/operator-labels.js` owns visible label dictionaries. - `web/operator-gui/submission-import.js` owns submission import/upload file payload helpers and import status message helpers. - `web/operator-gui/evidence-guidance.js` owns evidence sufficiency checks, follow-up reasons, query seed normalization, and suggested evidence queries. - `web/operator-gui/operator-search.js` owns query status labels, query strategy labels, and manual search provider normalization. - `web/operator-gui/app.js` now delegates those concerns to the extracted helpers while retaining rendering and event orchestration. Remaining: - Rendering domains are still mostly in `app.js`. Further extraction should focus on evidence rendering and knowledge/candidate rendering only if needed, because the current no-framework static runtime is now split enough to reduce the most immediate risk. ## 4. Improve Next-Action Guidance Problem: The workbench shows evidence, but does not always tell the operator what to do when evidence is thin. Plan: - Keep the existing "근거 보강 추천" panel. - Expand the sufficiency heuristic with clearer reasons: no direct match, too few searchable results, provider empty state, or duplicate queries. - Add a browser smoke test to ensure clicking a recommendation fills the manual query form without running a search. Immediate action: Completed: - The "근거 보강 추천" panel now explains concrete insufficiency reasons such as missing direct/page evidence, fewer than two searchable results, empty provider results, and failed provider history. - Suggested queries fill the manual search input and switch to the query tab without automatically running a search. - Browser smoke coverage verifies this non-automatic behavior. ## 5. Clarify Upload And Folder Reload UX Problem: Operators should not need to understand active queue internals. After adding a photo or changing folders, the UI should say what happened. Plan: - Provide a file picker for adding a photo to the active queue. - Save uploaded files into the active queue folder and rescan immediately. - Select the uploaded submission when available. - Show clear status text for imported count, selected ID, upload progress, and active folder label. Immediate action: Completed: - The upload endpoint and UI are implemented. - Upload success selects the uploaded submission, resets queue filters, moves to the workbench evidence tab, and tells the operator the new case was selected. - The queue header now explains that adding a photo creates a new review case and opens it for case review. - Browser smoke coverage verifies the real upload flow end to end. ## 6. Clarify Product Purpose And Workflow Problem: The console exposed many implementation concepts and actions, but the product purpose and operator flow were not explicit enough. Plan: - State the product purpose in the top bar. - Show the operator's expected flow on the queue screen. - Keep this copy stable with static tests. Completed: - The top bar now states: "이미지 저작권 위험 심사" and explains that submitted images, external search evidence, and the internal criteria DB are reviewed together. - The queue screen now shows a three-step operating flow: "심사 건 추가", "근거 보강", and "운영 결정". - Static tests protect the purpose copy and workflow copy. ## Verification Run: ```powershell python -m pytest tests\operator_gui\test_static_workbench.py python -m pytest tests\operator_gui\test_browser_smoke.py python -m pytest tests\rights_filter\server\test_http_app.py::test_http_server_uploads_submission_image_into_active_queue node --check web\operator-gui\app.js node --check web\operator-gui\operator-labels.js node --check web\operator-gui\submission-import.js node --check web\operator-gui\evidence-guidance.js node --check web\operator-gui\operator-search.js ``` Latest local verification: - `python -m pytest tests\operator_gui\test_static_workbench.py tests\operator_gui\test_browser_smoke.py` -> 39 passed. - `python -m pytest tests\rights_filter\server\test_http_app.py::test_http_server_uploads_submission_image_into_active_queue` -> 1 passed. - `node --check` passed for `app.js`, `operator-labels.js`, `submission-import.js`, `evidence-guidance.js`, and `operator-search.js`. Future verification: - If more rendering code is extracted from `app.js`, add a browser smoke check for that affected flow before relying on static checks. - If the visual layout changes again, refresh the `ui-overhaul-final-results.json` overflow audit and screenshots.