Hyungi Ahn
1af94d1004
fix(search): timing 로그를 setup_logger로 출력
...
logging.getLogger("search")만 사용하면 uvicorn 기본 설정에서 INFO가
stdout에 안 나옴. 기존 core.utils.setup_logger 패턴 사용:
- logs/search.log 파일 핸들러
- stdout 콘솔 핸들러
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:43:26 +09:00
Hyungi Ahn
473e7e2e6d
feat(search): Phase 0.4 debug 응답 옵션 + timing 로그
...
?debug=true로 호출 시 단계별 candidates + timing을 응답에 포함.
디버그 옵션과 별개로 모든 검색에 timing 라인을 구조화 로그로 출력
(사용자 feedback: 운영 관찰엔 debug 응답만으론 부족).
신규 응답 필드 (debug=true 시):
- timing_ms: text_ms / vector_ms / merge_ms / total_ms
- text_candidates / vector_candidates / fused_candidates (top 20)
- confidence (telemetry와 동일 휴리스틱)
- notes (예: vector 검색 실패 시 fallback 표시)
- query_analysis / reranker_scores: Phase 1/2용 placeholder
기본 응답(debug=false)은 변화 없음 (results, total, query, mode).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:41:33 +09:00
Hyungi Ahn
e104d1b47c
feat: Layer 프리미티브 (Drawer / Modal / ConfirmDialog / Tabs)
...
UX/UI 개편 Phase A-7. uiState와 결합한 layer/dialog 컴포넌트.
신규 컴포넌트 (lib/components/ui/)
- Drawer.svelte: 단일 slot drawer (id: 'sidebar' | 'meta').
ui.isDrawerOpen(id)로 표시 여부 결정. 새 drawer 열면 이전 drawer 자동 close.
side(left/right) + width(sidebar/rail). backdrop 클릭으로 close.
z-drawer 사용. 8대 원칙 #2 .
- Modal.svelte: stack 지원 modal (5대 원칙 #2 — confirm 위에 nested 가능).
native <dialog> 대신 div 기반 — top-layer가 단일이라 <dialog>로는 stack 불가.
z-index = z-modal + (stackIndex * 2): backdrop과 panel을 별개의 stacking
context로 두기 위해 *2. 최상단 modal만 focus trap + 키보드 nav 활성,
아래는 inert 처리. 수동 Tab/Shift+Tab cycling.
closable + IconButton(X) 헤더, footer snippet 지원.
- ConfirmDialog.svelte: Modal 위 얇은 wrapper. 삭제/되돌릴 수 없는 작업에
사용. tone(danger/primary), confirmLabel/cancelLabel, onconfirm 콜백.
ui.openModal(id)로 호출.
- Tabs.svelte: ARIA tablist + tab + tabpanel.
좌우 화살표 / Home / End 키 nav, \$props.id() 기반 SSR-safe ID.
tabs: { id, label, disabled? }[], value \$bindable.
children snippet은 (activeId) => UI 시그니처 — DocumentViewer 편집/미리보기
토글 등 단일 컨테이너 레이아웃에 쓰기 좋게 설계.
이로써 Phase A 프리미티브 13종 완비:
Button, IconButton, Card, Badge, Skeleton, EmptyState,
TextInput, Textarea, Select,
Drawer, Modal, ConfirmDialog, Tabs.
모든 컴포넌트는 Svelte 5 runes mode strict, @theme 토큰만 사용,
focus-visible ring 통일, slot은 {@render children?.()}로 작성.
svelte-check: 0 errors / 8 warnings (전부 기존 latent, 새 코드 무관)
build: 2.07s 무경고
남은 Phase A:
- A-8 토큰 swap (Sidebar/TagPill/UploadDropzone/PreviewPanel/DocumentCard/
DocumentTable/+layout toast — baseline 421건 → 0건)
- A-9 __styleguide 라우트 (전체 시각 검증 + Modal stack 데모)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:40:08 +09:00
Hyungi Ahn
ad23925ed5
feat: 입력 프리미티브 (TextInput / Textarea / Select) + tsconfig 보정
...
UX/UI 개편 Phase A-6.
신규 컴포넌트 (lib/components/ui/)
- TextInput.svelte: \$bindable value, label/error/hint, leading/trailing icon,
\$props.id() 기반 SSR-safe 자동 id, aria-describedby 자동 연결.
- Textarea.svelte: TextInput과 동일 구조 + autoGrow 옵션
(\$effect로 scrollHeight 동기화, maxRows 지원).
- Select.svelte: 네이티브 <select> 래퍼, ChevronDown 표시.
options: { value, label, disabled? }[]
빌드 환경 보정
- frontend/tsconfig.json 신규: svelte-kit 자동 생성 .svelte-kit/tsconfig.json을
extends. 이게 없으면 svelte-check가 \$lib path mapping과 .svelte.ts 모듈
resolution을 못 잡아 "Cannot find module" 에러 발생. SvelteKit 표준 패턴.
strict는 false로 시작 (기존 코드 implicit any 다수 — 점진적 정리 예정).
- Button/IconButton/EmptyState/TextInput의 icon prop 타입을 IconComponent(any)로
완화. lucide-svelte v0.400은 legacy SvelteComponentTyped 기반이라 Svelte 5의
Component<P, E, B> 시그니처와 호환 안 됨. v0.469+ 업그레이드 후 좁힐 예정.
svelte-check: 0 errors / 8 warnings (전부 기존 latent, 새 코드 무관)
build: 2.07s 무경고
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:39:44 +09:00
Hyungi Ahn
70b27d4a51
fix(search): confidence 임계값 완화 + hybrid +vector boost 가산
...
baseline 평가셋 실행 시 'summary+vector' top_score 2.39가 임계값 2.5에
미달해 정답 쿼리(산업안전보건법 제6장)가 low_confidence로 잘못 잡힘.
- 텍스트 매치 임계값 0.5씩 완화 (실측 분포 반영)
- '+vector' 접미사가 있으면 hybrid 합성 매치이므로 confidence +0.10 가산
- 정답률 5/5 → 4/5 false-positive 1건 제거 기대
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:37:13 +09:00
Hyungi Ahn
50e6b5ad90
fix(search): confidence 휴리스틱 vector-only amplify 버그 수정
...
vector-only 매치(match_reason == 'vector')에서 raw 코사인 0.43이
0.6으로 잘못 amplify되어 low_confidence threshold(0.5)를 못 넘기던 문제.
- vector-only 분기: amplify 제거, _cosine_to_confidence로 일관 환산
- _cosine_to_confidence: bge-m3 코사인 분포 (무관 텍스트 ~0.4) 반영
- 코사인 0.55 = threshold 경계(0.50), 0.45 미만은 명확히 low
smoke test 결과 zzzqxywvkpqxnj1234 같은 무의미 쿼리(top cosine 0.43)가
low_confidence로 잡히지 않던 문제 해결.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:33:25 +09:00
Hyungi Ahn
f005922483
feat(search): Phase 0.3 검색 실패 자동 로깅
...
검색 실패 케이스를 자동 수집해 gold dataset 시드로 활용.
wiggly-weaving-puppy 플랜 Phase 0.3 산출물.
자동 수집 트리거 (3가지):
- result_count == 0 → no_result
- confidence < 0.5 → low_confidence
- 60초 내 동일 사용자 재쿼리 → user_reformulated (이전 쿼리 기록)
confidence는 Phase 0.3 휴리스틱 (top score + match_reason).
Phase 2 QueryAnalyzer 도입 후 LLM 기반으로 교체 예정.
구현:
- migrations/015_search_failure_logs.sql: 테이블 + 3개 인덱스
- app/models/search_failure.py: ORM
- app/services/search_telemetry.py: confidence 계산 + recent 트래커 + INSERT
- app/api/search.py: BackgroundTasks로 dispatch (응답 latency 영향 X)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:29:12 +09:00
Hyungi Ahn
7fa7dc1510
feat: 디자인 시스템 기반 — 유틸 헬퍼 + CI rule + 첫 6개 프리미티브
...
UX/UI 개편 Phase A-3 / A-4 / A-5. 후속 phase가 곧바로 소비할 수 있도록
디자인 시스템의 코어 자산을 한꺼번에 도입한다.
A-3 — 유틸 헬퍼 (lib/utils/)
- pLimit.ts: 동시 실행 N개 제한 (5대 원칙 #4 — 일괄 PATCH/DELETE에서
GPU 서버/SSE 부하 방지). 외부 의존성 없음.
- mergeDoc.ts: PATCH/SSE 응답을 로컬 cache에 머지할 때 updated_at으로
stale 갱신 차단 (5대 원칙 #6 — optimistic update conflict resolution).
dropDoc 헬퍼 포함.
A-4 — CI 토큰 차단 (5대 원칙 #1 )
- scripts/check-tokens.sh: bg-[var(--*)] 등 임의값 토큰 우회 grep 차단.
- npm run lint:tokens 등록.
- 현재 baseline 421건 — A-8 토큰 swap에서 0으로 떨어진 후 pre-commit 강제화.
A-5 — 첫 6개 프리미티브 (lib/components/ui/)
- Button.svelte: variant(primary/secondary/ghost/danger) × size(sm/md),
loading/disabled, icon 슬롯, href 자동 a 변환, focus-visible ring.
- IconButton.svelte: 정사각형, aria-label 필수, Button과 동일 variant 체계.
- Card.svelte: bg-surface + rounded-card + border-default 패턴 1군데화.
padded/interactive 옵션, interactive면 button 시맨틱.
- Badge.svelte: 의미적 tone(neutral/success/warning/error/accent) 표시.
TagPill과 별개 (TagPill은 도메인 prefix 코드 전용).
- Skeleton.svelte: ad-hoc animate-pulse div 통합. w/h/rounded prop.
- EmptyState.svelte: icon + title + description + action slot.
모든 프리미티브는 Svelte 5 runes mode strict (\$props/\$derived/\$bindable),
@theme 토큰만 사용 (bg-surface, text-dim, border-default 등 — bg-[var(--*)] 미사용),
focus-visible ring 통일, slot은 {@render children?.()}로 작성.
svelte-check: 0 errors, 8 warnings (모두 기존 latent 이슈, 새 코드 무관).
build: 1.95s 무경고.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:26:35 +09:00
Hyungi Ahn
8742367bc2
refactor: stores 분리 — toast / uiState 단일 책임화
...
UX/UI 개편 Phase A-2. lib/stores/ui.ts에 섞여 있던 toast 시스템과
UI layer 상태(미사용 dead export 포함)를 의미 단위로 분리한다.
한 파일이 비대해지는 시나리오를 처음부터 차단(plan 8대 원칙 #7 ).
- lib/stores/toast.ts 신규 — toasts/addToast/removeToast (Toast interface export)
- lib/stores/uiState.svelte.ts 신규 — drawer 단일 slot + modal stack 클래스 (5대 원칙 #2 )
· openDrawer/closeDrawer/isDrawerOpen
· openModal/closeTopModal/isModalOpen/modalIndex/topModal
· handleEscape (modal stack 우선 → drawer)
- lib/stores/ui.ts 삭제 — sidebarOpen/selectedDocId는 어디서도 import되지 않은 dead export였음
- 11개 파일 import 경로 갱신: \$lib/stores/ui → \$lib/stores/toast
uiState는 아직 어디서도 사용 안 함 — Phase B에서 sidebar/meta drawer가 전환될 때
ui.openDrawer('sidebar') 형태로 채택. 동작 변경 0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:26:11 +09:00
Hyungi Ahn
ec36ea3d6d
test(search): Phase 0.2 baseline 측정 결과
...
23개 쿼리에 대한 현재 검색(FTS+ILIKE+Vector hybrid) baseline.
Phase 1+ 개선 비교 기준점으로 보존.
전체: Recall@10 0.788 / NDCG@10 0.705 / Top-3 0.95 / p95 1695ms
핵심 약점 (Phase 1+ 타겟):
- news_crosslingual catastrophic (Recall 0.14) → domain-aware 필수
- failure-case precision 0/3 → confidence threshold 부재
- p95 1695ms (목표 500ms의 3배) → trigram/parallel retrieval
- nl 쿼리 top-3 ordering 약함 → chunk-level + reranker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:22:53 +09:00
Hyungi Ahn
8490cfed10
test(search): Phase 0.2 평가셋 + 평가 스크립트
...
22개 쿼리(6개 카테고리)와 Recall/MRR/NDCG@10 + latency p50/p95
측정 스크립트 추가. wiggly-weaving-puppy 플랜 Phase 0.2 산출물.
- queries.yaml: 정확키워드/한국어자연어/crosslingual/뉴스/실패 케이스
실제 코퍼스(2026-04-07, 753 docs) 기반 정답 doc_id 매핑
- run_eval.py: 단일 평가 + A/B 비교 모드, CSV 저장
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:19:38 +09:00
Hyungi Ahn
f523752971
feat: Tailwind v4 @theme 토큰 도입 — 디자인 시스템 기반 마련
...
UX/UI 개편 Phase A-1. CSS 변수를 Tailwind 유틸리티로 노출해서
이후 컴포넌트가 bg-surface / text-dim / border-default 형태로 작성될
수 있도록 한다. bg-[var(--*)] 임의값 패턴은 후속 lint 규칙으로 차단 예정.
- app.css에 @theme 블록 추가 (color/radius/z/spacing/domain 토큰)
- 기존 :root 변수는 .markdown-body 호환 위해 공존 유지
- +layout.svelte nav 한 줄 swap으로 v4 빌드/HMR 인식 검증 (동일 색상값)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-07 08:15:33 +09:00
Hyungi Ahn
fc50008843
feat: 뉴스 페이지 모바일 최적화 — 데스크톱/모바일 공존
...
데스크톱: 사이드바 필터 + 하단 미리보기 (기존 유지)
모바일: 드롭다운 필터 + 전체화면 미리보기 + 하단 원문 버튼
- body scroll lock (모바일 전체화면 시)
- 스크롤 위치 복원
- active 터치 피드백
- 안읽음 건수 표시
- 페이지네이션 10개 제한
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:56:33 +09:00
Hyungi Ahn
db34a06243
feat: 뉴스 미리보기 — AI 요약 상단 + 본문/메모 분리
...
- AI 요약: 파란 박스로 상단에 별도 표시
- 본문 입력: extracted_text에 추가 (기사 전문 붙여넣기)
- 메모: user_note에 저장 (개인 메모)
- 기사 선택 시 편집 상태 초기화
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:42:33 +09:00
Hyungi Ahn
e10b0f2883
fix: 뉴스 분야 필터 — file_path 폴더명 기반 매칭
...
경향신문/문화 → file_path LIKE 'news/경향신문 문화/%'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:27:01 +09:00
Hyungi Ahn
8bb2ea4f29
fix: 뉴스 필터 트리 — 신문사명 정확 추출 + API datetime 수정
...
- PAPER_NAMES 매핑으로 'Le Monde', 'Der Spiegel' 등 정확 분리
- NewsSourceResponse datetime 타입 수정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:18:50 +09:00
Hyungi Ahn
3cd65e4c26
fix: 사이드바 트리에서 News 제외 + 뉴스 페이지 ☰ 숨김
...
- tree API: ai_domain != 'News' 필터
- +layout: /news 경로에서 사이드바 토글 버튼 숨김
- DB: 뉴스 ai_sub_group을 신문사명으로 재설정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:15:15 +09:00
Hyungi Ahn
557165db11
feat: 뉴스 필터 트리 (신문사 → 분야) + ai_summary 우선 표시
...
- 좌측 필터: 신문사 펼침 → 분야별 필터 (News/경향신문/문화)
- API: source 파라미터 '신문사' 또는 '신문사/분야' 지원
- 리스트: ai_summary 있으면 우선, 없으면 extracted_text fallback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:08:50 +09:00
Hyungi Ahn
2eeed41f5c
fix: @const 위치 에러 수정
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:06:29 +09:00
Hyungi Ahn
be20edd0cd
fix: 뉴스 리스트 — ai_summary 우선 표시 (없으면 extracted_text fallback)
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:05:46 +09:00
Hyungi Ahn
49cc86db80
feat: summarize 전용 stage — 뉴스 AI 요약 (classify 없이)
...
- summarize_worker: 요약만 생성 (분류 안 함)
- queue_consumer: summarize stage 추가 (batch 3)
- news_collector: summarize + embed 큐 등록
- process_stage enum에 'summarize' 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 15:00:14 +09:00
Hyungi Ahn
4f7cd437f5
feat: 뉴스 리스트에 RSS 요약 1줄 표시 + 상세 링크 현재 탭
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 14:52:57 +09:00
Hyungi Ahn
7d6b5b92c0
fix: 뉴스 페이지네이션 리셋 버그 + 상세 링크 새 탭
...
- $effect에서 필터 변경 시에만 page 리셋 (페이지 클릭과 충돌 방지)
- 상세 링크 → 새 탭으로 열기
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 14:47:27 +09:00
Hyungi Ahn
ef6f857a6d
fix: 뉴스 페이지 — 닫기 버튼 + 페이지네이션 + 상세 링크 + 본문 입력
...
- 미리보기 닫기 버튼 추가
- 페이지네이션 (30건 단위)
- "상세" 링크 → /documents/{id}
- "본문/메모 입력" → user_note 저장
- DocumentUpdate에 is_read 필드 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 14:38:42 +09:00
Hyungi Ahn
7ca3abf17c
feat: 뉴스 전용 페이지 + 분류 격리 + 읽음 상태
...
- /news 전용 페이지: 신문사 필터, 읽지않음 필터, 시간순 리스트, 미리보기
- 뉴스 분류 격리: ai_domain='News', classify 제거, embed만 등록
- is_read: 클릭 시 자동 읽음, 전체 읽음 API
- documents 목록에서 뉴스 제외 (source_channel != 'news')
- nav에 뉴스 링크 추가
- GET /api/news/articles, POST /api/news/mark-all-read
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 14:16:00 +09:00
Hyungi Ahn
cd5f1c526d
fix: 상세 페이지에도 뉴스 전용 뷰어 적용 (source_channel=news → article)
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 14:01:39 +09:00
Hyungi Ahn
2b457a8305
feat: 뉴스 전용 뷰어 + 카드 구분 + 설정 UI
...
- DocumentViewer: source_channel=news → article 전용 뷰어
(제목/소스/날짜/요약/원문 링크 rel=noopener)
- DocumentCard: 뉴스 카드에 📰 아이콘
- settings: 뉴스 소스 관리 (목록/추가/삭제/토글/수집/마지막 시간)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 13:55:49 +09:00
Hyungi Ahn
d03fa0df37
fix: source_channel enum에 'news' 추가 (ORM 누락)
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 13:41:20 +09:00
Hyungi Ahn
a6c19ef76c
feat: 뉴스 자동 수집 시스템 — 6개국 신문 RSS/API
...
- news_sources 테이블 (소스 관리, UI 동적 제어)
- news_collector 워커: RSS(feedparser) + NYT API
- 중복 체크: hash(title+date+source) + URL normalize
- category 표준화, summary HTML 정제, timezone UTC
- 30일 이내만 embed, source별 try/catch
- News API: 소스 CRUD + 수동 수집 트리거
- APScheduler: 6시간 간격 자동 수집
- 대상: 경향/아사히/NYT/르몽드/신화/슈피겔
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 13:38:07 +09:00
Hyungi Ahn
bf8efd1cd3
feat: 임베딩 모델 변경 — nomic-embed-text → bge-m3 (1024차원, 다국어)
...
- config.yaml: embedding model → bge-m3
- document.py: Vector(768) → Vector(1024)
- embed_worker.py: 모델 버전 업데이트
- migration 011: 벡터 컬럼 재생성 (기존 임베딩 초기화)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 12:49:45 +09:00
Hyungi Ahn
204c5ca99f
fix: AI 요약 마크다운 렌더링 — 상세페이지는 렌더링, 카드는 기호 제거
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 12:36:29 +09:00
Hyungi Ahn
c885b5be27
fix: 3+4단계 — 반응형/에러분기/a11y/Synology URL
...
- DocumentCard: window.innerWidth → matchMedia (반응형 정확)
- documents/[id]: 로딩 상태 3분기 (loading/not_found/network)
- documents/[id]: Synology URL 하드코딩 → edit_url fallback
- DocumentCard: aria-label 추가
- Toast: aria-live 이미 적용 (1단계)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 12:24:32 +09:00
Hyungi Ahn
1b21d9bb53
feat: 2단계 — DEVONthink 스타일 테이블 뷰 + 카드/테이블 토글
...
- DocumentTable.svelte: 컬럼 정렬(stable sort), domain 색상 바, 포맷 아이콘
- 뷰 모드 토글 버튼 (카드 ↔ 테이블)
- localStorage로 뷰 모드 + 정렬 상태 기억
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 12:16:45 +09:00
Hyungi Ahn
3374eebfc6
fix: 프론트엔드 1단계 — XSS 수정 + Svelte 5 변환 + 필터/아이콘/a11y
...
- [critical] DOMPurify 적용 (FORBID_TAGS/ATTR, ALLOW_UNKNOWN_PROTOCOLS)
- [high] $: → $derived 변환 (documents/[id])
- [high] 태그/소스 필터 구현 (filterTag, filterSource)
- FormatIcon: docx/xlsx/pptx/odt/ods/odp/dwg/dxf 추가
- editTab 선언 순서 수정
- debounceTimer 미사용 변수 제거
- Toast role="status" aria-live 추가
- marked 옵션: mangle/headerIds false
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 12:15:02 +09:00
Hyungi Ahn
24142ea605
fix: Codex 리뷰 5건 수정 (critical 1 + high 4)
...
1. [critical] config.yaml → settings 객체에서 taxonomy 로드 (import crash 방지)
2. [high] ODF 변환: file_path 유지, derived_path 별도 필드 (무한 중복 방지)
3. [high] 법령 분할: 첫 장 이전 조문을 "서문"으로 보존
4. [high] Inbox: review_status 필드 분리 (pending/approved/rejected)
5. [high] 삭제: soft-delete (deleted_at) + worker 방어 + active_documents 뷰
- 모든 조회에 deleted_at IS NULL 일관 적용
- queue_consumer: row 없으면 gracefully skip
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-06 07:15:13 +09:00
Hyungi Ahn
6c92e375c2
feat: Markdown 뷰어/편집기 개선
...
- startEdit(): extracted_text || rawMarkdown fallback
- split editor → 편집/미리보기 탭 전환 방식
- GitHub Dark 스타일 markdown-body CSS (테이블/코드/인용/리스트)
- prose 클래스 → markdown-body로 교체
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 15:48:41 +09:00
Hyungi Ahn
06da098eab
fix: 법령 분할 — 조문키 000 기반 장(章) 단위 분할로 변경
...
국가법령 XML은 <편>/<장> 태그가 아닌 <조문단위 조문키="xxxx000">에
"제X장 ..." 형태로 장 구분자가 포함됨. 이를 파싱하여 분할.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 15:05:48 +09:00
Hyungi Ahn
749ed51dd7
fix: Markdown 뷰어 — extracted_text 없으면 원본 파일 직접 렌더링
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:55:51 +09:00
Hyungi Ahn
1668be0a75
fix: 법령 저장 후 즉시 commit — 알림 실패가 DB 롤백하지 않도록
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:50:39 +09:00
Hyungi Ahn
93c5805060
feat: 법령 API 전면 개편 — 26개 법령, 분할 저장, 변경 이력 추적
...
- 모니터링 법령 12개 → 26개 (산업안전/건설/위험물/소방/전기/가스/근로/환경)
- lawSearch.do로 검색, lawService.do로 본문 조회
- 대형 법령 편/장 단위 분할 저장 (fallback: 편→장→전체)
- 저장 경로: PKM/Inbox/ (AI 자동 분류 연계)
- 변경 감지 시 user_note에 이력 자동 기록
- CalDAV + SMTP 알림
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:47:08 +09:00
Hyungi Ahn
b4ca918125
fix: 벡터 검색 asyncpg 캐스트 — ::vector → cast(:embedding AS vector)
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:35:14 +09:00
Hyungi Ahn
e23c4feaa0
feat: 검색 전면 개편 — 필드별 가중치 + 벡터 합산 + match reason
...
검색 대상: title > ai_tags > user_note > ai_summary > extracted_text
- 필드별 가중치: title(3.0), tags(2.5), note(2.0), summary(1.5), text(1.0)
- 벡터 검색: 별도 쿼리로 분리, 결과 합산 (asyncpg 충돌 방지)
- match_reason: 어떤 필드에서 매칭됐는지 반환
- 중복 제거 + 점수 합산
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:33:34 +09:00
Hyungi Ahn
e7cd710e69
fix: hybrid 검색 단순화 — FTS + ILIKE (vector/trgm 복잡 쿼리 제거)
...
asyncpg 파라미터 바인딩 충돌 문제 근본 해결.
한국어 검색: ILIKE fallback으로 안정 동작.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:16:36 +09:00
Hyungi Ahn
3236b8d812
fix: 검색 500 에러 (ILIKE % 이스케이프) + 한글 조합 중 Enter 방지
...
- ILIKE '%' → '%%' (SQLAlchemy text() 파라미터 충돌 해결)
- e.isComposing 체크로 한글 조합 완료 전 Enter 무시
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:14:07 +09:00
Hyungi Ahn
4d205b67c2
fix: 검색 UX 개선 — Enter 키 기반 + 한국어 검색 ILIKE fallback
...
- 프론트: debounce 자동검색 제거 → Enter 키로만 검색 (한글 조합 문제 해결)
- 백엔드: trgm threshold 0.1로 낮춤 + ILIKE '%검색어%' fallback 추가
- hybrid 검색 score threshold 0.01 → 0.001로 낮춤
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:10:47 +09:00
Hyungi Ahn
b54cc25650
fix: 미분류 판단 기준 변경 — file_path 기반 → ai_domain 없음 기준
...
파일을 물리적으로 이동하지 않으므로 file_path로 미분류 판단 불가.
ai_domain이 NULL 또는 빈 문자열인 문서를 미분류로 취급.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:05:41 +09:00
Hyungi Ahn
d63a6b85e1
feat: 사이드바 3단계 재귀 트리 + 너비 확장 (320px)
...
- tree API: domain 경로를 파싱하여 계층 구조로 반환
(Industrial_Safety → Practice → Patrol_Inspection)
- Sidebar: 재귀 snippet으로 N단계 트리 렌더링
- domain 필터: prefix 매칭 (상위 클릭 시 하위 전부 포함)
- 사이드바 너비: 260px → 320px
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 14:03:36 +09:00
Hyungi Ahn
bf0506023c
feat: 정보 패널 — taxonomy 기반 분류 표시 (breadcrumb + type/confidence 배지)
...
- domain 경로를 breadcrumb으로 표시 (Industrial_Safety › Practice › Patrol_Inspection)
- document_type 배지 (파란색)
- confidence 배지 (85%+ 초록, 60~85% 주황, <60% 빨강)
- importance 배지 (high만 표시)
- 원본 포맷 표시
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 13:56:37 +09:00
Hyungi Ahn
7f5e09096a
fix: 문서 삭제 시 processing_queue FK 제약 해결 + 변환본/preview 함께 삭제
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 13:51:35 +09:00
Hyungi Ahn
5153169d5d
fix: 검색바 상단 고정 — 문서 목록만 스크롤
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 13:49:42 +09:00