Image rights / copyright detection system: SQLite store, HTTP app, search integrations (Naver, Google Custom Search, Google Cloud Vision web detection), image analysis (fingerprints, face/person detection, evidence enrichment, risk scoring), an admin/review layer, governance and retention policies, batch jobs, and a browser-based operator GUI. This baseline incorporates a full code-review remediation pass (46 fixes; 358 tests passing). Highlights: CRITICAL - Prevent evidence cascade-delete during the schema-constraint migration by disabling FK enforcement around the table rebuild. Security - Sandbox served media (neutralize stored XSS from uploaded/collected SVGs) via CSP + nosniff on the untrusted media routes. - Strip embedded EXIF/GPS from external image derivatives before they are sent to third-party APIs. - Return a clean 404 (not an uncaught StopIteration) for PATCH on an unknown provider. Correctness - LLM-summary failures no longer add +30 to the risk score. - Decode only explicit JS escapes so Korean image URLs are not mangled. - Consume search quota only after a successful request. - Naver/Google adapters map responses inside the failure boundary, so a malformed response degrades to evidence instead of crashing enrichment. - Domain-aware provider attribution; face-box IoU de-duplication; count searches (not result items); per-box crop isolation; clamp evidence confidence and Google CSE num; real submittedEpoch; and more. Robustness - Offline LLM connect fast-fails (short connect timeout) so seed/reload requests are not stalled; full read timeout preserved for generation. - Malformed numeric env vars fall back to defaults instead of crashing startup. Performance - Per-submission evidence reads (no full-table scan per rescore), audit-log LIMIT, lazy active-store lookup, hoisted timestamps. Tests - ~24 regression tests added pinning the above fixes. Runtime data (data/, outputs/, *.sqlite3, *.log), secrets (.env), and node_modules are gitignored.
7.4 KiB
| status | created | type | title |
|---|---|---|---|
| active | 2026-05-28 | feat | Operator UI overhaul |
Operator UI Overhaul Plan
Problem Frame
The current operator console has drifted into a patched layout instead of a coherent review workspace. The top evidence coverage card scrolls inside the header, queue columns create awkward gaps between top evidence and provider state, Knowledge DB badges wrap unevenly, and "Case review" and "Search evidence" are separate top-level tabs even though both depend on the same selected case.
This plan rebuilds the information architecture around the operator's real workflow: filter the queue, select a case, inspect all evidence in one workbench, decide, and maintain reference knowledge.
Requirements
- Replace the top scrolling evidence coverage panel with a horizontal tab/segmented indicator.
- Remove "Search evidence" as an independent top-level navigation destination.
- Combine case review, evidence, query history, relevant knowledge, and decision controls into one case workbench.
- Rebuild queue rows so top evidence and provider state sit next to each other without unused whitespace.
- Normalize Knowledge DB badge wrapping and action alignment.
- Preserve existing API endpoints and local static deployment.
- Verify with static tests and browser screenshots across desktop and mobile.
Key Technical Decisions
- Keep the existing no-framework static app (
index.html,app.js,styles.css) and avoid adding dependencies. - Use CSS grid rows for the queue instead of table column sizing for the primary desktop layout.
- Use a compact horizontal
.coverage-tabscontrol for provider coverage. It should be filter-capable, not just decorative. - Treat the workbench as the only selected-case surface. Evidence search becomes a workbench tab.
- Use one shared chip/badge alignment system for Knowledge DB, evidence, providers, and queue summaries.
Implementation Units
U1: Header Coverage Tabs And Queue Row Grid
Files:
web/operator-gui/index.htmlweb/operator-gui/app.jsweb/operator-gui/styles.csstests/operator_gui/test_static_workbench.py
Approach:
- Replace
#search-coveragecard semantics with#coverage-tabs. - Render coverage as one horizontal segmented row: all, evidence coverage, provider query counts, failures.
- Add provider/source filter behavior through
data-coverage-filter. - Replace queue table visual styling with
.queue-grid/.queue-rowclasses while keeping accessible table markup if needed for low-risk migration. - Reduce queue provider/evidence whitespace by explicitly sizing grid areas.
Test scenarios:
- Static shell exposes
id="coverage-tabs"and does not expose a scrollablesearch-coverageheader panel. - Script contains
renderCoverageTabsandapplyCoverageFilter. - CSS contains
.coverage-tabs,.coverage-tab,.queue-grid, and.queue-row. - CSS does not set
overflow: autoon the top coverage control.
Verification:
python -m pytest tests/operator_gui/test_static_workbench.py- Browser screenshot at 1440x1000 and 390x844 with no document horizontal overflow.
U2: Case Workbench Internal Tabs
Files:
web/operator-gui/index.htmlweb/operator-gui/app.jsweb/operator-gui/styles.csstests/operator_gui/test_static_workbench.py
Approach:
- Rename the case surface to a workbench.
- Move query history and searchable evidence from the former
evidence-viewinto workbench internal tabs. - Add workbench tabs: summary, evidence, queries, knowledge, decision.
- Keep the selected case state shared, but stop representing evidence as an independent top-level route.
Test scenarios:
- Top-level view set excludes
evidence. - Workbench markup contains
data-workbench-tab="evidence"anddata-workbench-panel="evidence". - Selecting a case routes to workbench and preserves selected submission.
- Search evidence renderer targets the workbench panel.
Verification:
- Static tests.
- Browser click test: select queue row, switch internal tabs, confirm no top-level route mismatch.
U3: Knowledge DB Badge And Action Alignment
Files:
web/operator-gui/app.jsweb/operator-gui/styles.csstests/operator_gui/test_static_workbench.py
Approach:
- Split Knowledge DB row into media, content, chip rail, and actions.
- Move name/title out of chip row.
- Use a deterministic chip order: status, type, provenance, samples, watchlist meta.
- Align actions to a fixed rail on desktop and full-width row on mobile.
Test scenarios:
- Script renders
.knowledge-chip-rowseparate from.row-title. - CSS defines
.knowledge-rowgrid areas and.knowledge-actionsalignment. - Long aliases/keywords wrap in metadata text, not inside status badges.
Verification:
- Static tests.
- Browser screenshot of Knowledge DB desktop and mobile.
U4: Navigation Simplification And Labels
Files:
web/operator-gui/index.htmlweb/operator-gui/app.jsweb/operator-gui/styles.csstests/operator_gui/test_static_workbench.py
Approach:
- Reduce top-level navigation to queue, workbench, knowledge, providers, audit.
- Move correction tools under Knowledge DB or workbench decision context, depending on current behavior preservation.
- Ensure URL hash handling maps old
#caseand#evidencegracefully to the new workbench during transition.
Test scenarios:
- Top-level nav does not include
data-view="evidence". - Old hash routes map to workbench instead of blank state.
- Existing correction controls remain reachable.
Verification:
- Static tests.
- Browser hash smoke checks.
U5: Visual Verification And Cleanup
Files:
data/logs/web/operator-gui/styles.csstests/operator_gui/test_static_workbench.py
Approach:
- Capture screenshots for queue, workbench tabs, Knowledge DB, providers.
- Remove obsolete CSS tied to scroll coverage panels and table-only queue spacing.
- Keep only compatibility styles needed during transition.
Test scenarios:
- No document horizontal overflow at 390px mobile.
- Header has no nested scroll control.
- Queue row content is visible and aligned at desktop and mobile.
Verification:
python -m pytest tests/operator_gui/test_static_workbench.py- Playwright screenshot audit with overflow diagnostics.
Scope Boundaries
In scope:
- Static operator console UI structure, interaction state, and visual layout.
- Existing local server and current API response shape.
- Tests for UI contracts and visual regression smoke checks.
Out of scope:
- Backend API schema changes.
- New frontend framework migration.
- Authentication, deployment, or production process management.
- Rewriting garbled legacy Korean copy except where labels are touched by the UI structure change.
Risks
- The existing static test file contains legacy string assertions and one unrelated
NaNcontract failure. Update tests deliberately so failures point to the new UI contract. - Moving evidence into the workbench can break event listeners if IDs are duplicated or moved without updating render targets.
- Keeping table markup while visually converting to grid is a migration compromise; if it creates accessibility or CSS complexity, switch to semantic list/card rows with explicit labels.
Verification Plan
- Run static UI contract tests after each implementation unit.
- Use Playwright to capture desktop and mobile screenshots after U1, U2, and U3.
- Record overflow diagnostics:
document.documentElement.scrollWidth === document.documentElement.clientWidth. - Inspect console errors and distinguish data 404s from UI regressions.