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.
97 lines
2.1 KiB
JavaScript
97 lines
2.1 KiB
JavaScript
(function attachOperatorLabels(global) {
|
|
const riskLabels = {
|
|
high: "높음",
|
|
medium: "중간",
|
|
low: "낮음",
|
|
failed: "실패",
|
|
pending: "대기",
|
|
};
|
|
|
|
const decisionLabels = {
|
|
unreviewed: "미심사",
|
|
held: "보류",
|
|
rejected: "반려",
|
|
approved: "승인",
|
|
corrected: "보정됨",
|
|
};
|
|
|
|
const providerLabels = {
|
|
internal: "내부 분석",
|
|
naver: "네이버 검색",
|
|
naver_blog: "네이버 블로그 검색",
|
|
naver_web: "네이버 웹문서 검색",
|
|
google: "구글 이미지",
|
|
google_search: "구글 근거 검색",
|
|
llm: "내부 요약",
|
|
};
|
|
|
|
const sourceLabels = {
|
|
internal: "내부",
|
|
fingerprint: "이미지 유사도",
|
|
face: "얼굴/인물 감지",
|
|
naver: "네이버",
|
|
google: "구글",
|
|
llm: "내부 요약",
|
|
failure: "실패",
|
|
};
|
|
|
|
const providerStatusLabels = {
|
|
ok: "정상",
|
|
covered: "근거 있음",
|
|
empty: "결과 없음",
|
|
failed: "실패",
|
|
disabled: "중지",
|
|
skipped: "건너뜀",
|
|
pending: "미실행",
|
|
not_run: "미실행",
|
|
};
|
|
|
|
const candidateStatusLabels = {
|
|
candidate: "후보",
|
|
promoted: "반영됨",
|
|
};
|
|
|
|
const evidenceStatusLabels = {
|
|
used_for_judgment: "판단에 사용",
|
|
irrelevant: "무관",
|
|
false_positive: "오탐",
|
|
ignored: "미사용",
|
|
pending: "보류",
|
|
};
|
|
|
|
const knowledgeStatusLabels = {
|
|
confirmed: "확정 DB",
|
|
watchlist: "주의 후보",
|
|
excluded: "제외됨",
|
|
};
|
|
|
|
const provenanceLabels = {
|
|
manual: "수동 등록",
|
|
automatic: "자동 등록",
|
|
external_evidence: "외부 근거",
|
|
};
|
|
|
|
const knowledgeTypeLabels = {
|
|
celebrity: "연예인/유명인",
|
|
public_figure: "연예인/유명인",
|
|
work: "작품",
|
|
character: "캐릭터",
|
|
game: "게임",
|
|
rejected_image: "반려 이미지",
|
|
rejected_reference: "반려 이미지",
|
|
other: "기타",
|
|
};
|
|
|
|
global.OperatorLabels = {
|
|
riskLabels,
|
|
decisionLabels,
|
|
providerLabels,
|
|
sourceLabels,
|
|
providerStatusLabels,
|
|
candidateStatusLabels,
|
|
evidenceStatusLabels,
|
|
knowledgeStatusLabels,
|
|
provenanceLabels,
|
|
knowledgeTypeLabels,
|
|
};
|
|
})(window);
|