Commit Graph

109 Commits

Author SHA1 Message Date
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
Hyungi Ahn
9b0705b79f config: fallback 모델 qwen3.5:35b → qwen3.5:9b-q8_0 (GPU VRAM 제한)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:40:25 +09:00
Hyungi Ahn
63f75de89d fix: Qwen3.5 thinking 모드 비활성화 (enable_thinking: false)
JSON 응답에 Thinking Process 텍스트가 섞이는 문제 해결.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:38:10 +09:00
Hyungi Ahn
6d73e7ee12 feat: 분류 체계 전면 개편 — taxonomy + document_type + confidence
- config.yaml: 6개 domain × 3단계 taxonomy + 13개 document_types 정의
- classify.txt: 영문 프롬프트, taxonomy 경로 기반 분류 + 분류 규칙 주입
- classify_worker: taxonomy 검증, confidence 기반 분류, document_type 저장
- migration 008: document_type, importance, ai_confidence 컬럼
- API: DocumentResponse에 document_type, importance, ai_confidence 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:32:20 +09:00
Hyungi Ahn
770d38b72c feat: 문서 삭제 기능 — 정보 패널에서 확인 후 삭제 (파일+DB)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:14:20 +09:00
Hyungi Ahn
1b5fa95a9f feat: 오피스 → ODF 변환 + 원본/편집본 분리 아키텍처
- original_path/format/hash + conversion_status 필드 추가 (migration 007)
- extract_worker: 텍스트 추출 후 xlsx→ods, docx→odt 등 ODF 변환
  - 변환본은 .derived/{doc_id}.ods 에 저장
  - 원본 메타 보존 (original_path/format/hash)
- file_watcher: .derived/ .preview/ 디렉토리 제외
- DocumentViewer: ODF 포맷이면 편집 버튼 자동 표시
  - edit_url 있으면 "편집", 없으면 "Synology Drive에서 열기"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:11:43 +09:00
Hyungi Ahn
b937eb948b feat: Noto 다국어 폰트 추가 (fonts-noto-core/extra — 라틴/아랍/태국 등)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:45:02 +09:00
Hyungi Ahn
1030bffc82 fix: LibreOffice 한글/CJK 폰트 추가 (fonts-noto-cjk, fonts-nanum)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:43:13 +09:00
Hyungi Ahn
733f730e16 fix: preview enum 누락 + AI summary thinking 제거 + CLAUDE.md 전면 갱신
- queue.py: process_stage enum에 'preview' 추가
- classify_worker: ai_summary에 strip_thinking() 적용
- CLAUDE.md: 현재 아키텍처 전면 반영 (파이프라인, UI, 인프라, 코딩규칙)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:38:59 +09:00
Hyungi Ahn
6893ea132d refactor: preview 병렬 트리거 + 파일 이동 제거 + domain 색상 바
- queue_consumer: extract 완료 시 classify + preview 동시 등록
- classify_worker: _move_to_knowledge() 제거, 파일 원본 위치 유지
- DocumentCard: 좌측 domain별 색상 바 (4px) 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:31:57 +09:00
Hyungi Ahn
47e9981660 fix: Qwen3.5 Thinking Process 텍스트 제거 — JSON 파싱 개선
첫 번째 { 이전의 모든 비-JSON 텍스트를 제거하여
thinking/reasoning preamble이 있어도 JSON 추출 가능.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:44:21 +09:00
Hyungi Ahn
03b0612aa2 fix: extract_worker OFFICE_FORMATS 블록에 return 누락 수정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:28:09 +09:00
Hyungi Ahn
a5186bf4aa fix: 스프레드시트 텍스트 추출 — csv 필터 사용 (txt:Text는 Calc 미지원)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:21:29 +09:00
Hyungi Ahn
b37043d651 fix: LibreOffice 한글 파일명 호환 — 영문 임시파일로 복사 후 변환
extract_worker, preview_worker 모두 적용.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:18:06 +09:00
Hyungi Ahn
45448b4036 feat: extract_worker에 LibreOffice 텍스트 추출 추가 (오피스 포맷)
- xlsx, docx, pptx, odt, ods, odp, odoc, osheet 지원
- LibreOffice --convert-to txt로 텍스트 추출 (60s timeout)
- 추가 의존성 없음 (Docker에 이미 설치된 LibreOffice 사용)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:12:19 +09:00
Hyungi Ahn
9fd44ab268 fix: 드래그 앤 드롭 — window 이벤트로 브라우저 기본 동작 차단
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:06:18 +09:00
Hyungi Ahn
87bdd8003c feat: 드래그 앤 드롭 업로드 (UploadDropzone)
- 파일 드래그 시 전체 페이지 오버레이
- 순차 업로드 + 파일별 진행 상태
- 성공/실패 토스트 + 목록 자동 새로고침
- documents 페이지에 통합

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:02:42 +09:00
Hyungi Ahn
41072a2e6d feat: 수동 편집 URL — 정보 패널에서 Synology Drive 링크 입력/관리
- edit_url 컬럼 추가 (migration 006)
- PreviewPanel: 편집 링크 입력/수정/표시 UI
- DocumentViewer: edit_url 있으면 편집 버튼에서 해당 URL로 새 탭
- API: DocumentResponse/DocumentUpdate에 edit_url 필드

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:37:44 +09:00
Hyungi Ahn
4bea408bbd feat: Markdown 편집기 + PDF 변환 파이프라인 + 뷰어 포맷 분기
- Markdown split editor: textarea + marked preview, Ctrl+S 저장
- PUT /api/documents/{id}/content: 원본 파일 저장 + extracted_text 갱신
- GET /api/documents/{id}/preview: PDF 미리보기 캐시 서빙
- preview_worker: LibreOffice headless → PDF 변환 (timeout 60s, retry 1회)
- queue_consumer: preview stage 추가 (embed 후 자동 트리거)
- DocumentViewer: 포맷별 분기 (markdown/pdf/preview-pdf/image/text/cad)
- 오피스/CAD 문서: 새 탭 편집 버튼
- Dockerfile: LibreOffice headless 설치
- migration 005: preview_status, preview_hash, preview_at 컬럼

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:10:03 +09:00
Hyungi Ahn
3546c8cefb refactor: 레이아웃 개선 — 30:70 비율, 사이드바 접힘, 정보 패널 drawer
- 사이드바: 데스크톱도 기본 접힘, ☰로 오버레이, localStorage 상태 기억
- 상단 30%: 문서 목록 + 검색 (문서 미선택 시 100%)
- 하단 70%: 뷰어 전체 너비 (우측 패널 제거)
- 정보 패널: ℹ 버튼 → 우측 전체 높이 drawer (ESC/외부 클릭 닫기)
- nav 높이 축소, 폰트 크기 최적화

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 10:05:47 +09:00
Hyungi Ahn
17d41a8526 feat: Phase 1D+2 — 모바일 대응, 스마트 그룹, 메모, 태그 편집
- 모바일: 카드 클릭 시 detail 페이지로 이동 (뷰어 패널 미표시)
- 스마트 그룹: 사이드바에 최근 7일/법령 알림/이메일 프리셋 필터
- 메모: user_note 컬럼 추가 (migration 004), PATCH API, PreviewPanel 인라인 편집
- 태그 편집: PreviewPanel에서 태그 추가(+)/삭제(×) 기능
- DB 모델 + API 스키마 user_note 필드 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:27:18 +09:00
Hyungi Ahn
47abf40bf1 feat: 하단 문서 뷰어 + 우측 정보 패널 (DEVONthink 레이아웃)
- DocumentViewer: 문서 선택 시 하단에 본문 미리보기/편집
  (Markdown 렌더링, PDF iframe, 이미지, Synology Office iframe)
- 레이아웃 변경: 상단(목록 45%) + 하단(뷰어+정보 55%)
- 우측 패널은 문서 정보/태그/처리상태 (메모/태그 편집은 Phase 2)
- 문서 선택 해제 시 목록 전체 표시로 복원

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:17:45 +09:00
Hyungi Ahn
9239e9c1d5 fix: DocumentCard svelte:element → button (Svelte 5 호환)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:12:08 +09:00
Hyungi Ahn
a15208f0cf feat: Phase 1C — 프리뷰 패널 (문서 선택 시 우측 표시)
- PreviewPanel: AI 요약, 태그, 메타 정보, 처리 상태 표시
- DocumentCard: 선택 모드 지원 (클릭→프리뷰, 더블클릭 불필요)
- 3-pane 완성: sidebar | document list | preview panel
- 필터 변경 시 선택 자동 해제
- 데스크톱만 표시 (모바일은 detail 페이지로 이동)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:11:13 +09:00
Hyungi Ahn
f4a0229f15 fix: detail 페이지 태그를 TagPill 컴포넌트로 교체 (클릭→필터)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:07:51 +09:00
Hyungi Ahn
cb8a846773 feat: Phase 1B — DocumentCard/TagPill/FormatIcon 컴포넌트
- DocumentCard: 포맷 아이콘, 제목+요약, domain 경로, 태그 pill,
  data_origin 배지, 날짜, 파일 크기
- TagPill: 계층별 색상 (@amber, #blue, $green, !red), 클릭→필터
- FormatIcon: 파일 포맷별 lucide 아이콘 매핑
- documents 페이지에서 DocumentCard 컴포넌트 사용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:05:40 +09:00
Hyungi Ahn
1a207be261 fix: authChecked를 $state로 변경 (반응성 복원)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:03:06 +09:00
Hyungi Ahn
b04e1de8a6 fix: Svelte 5 runes mode 호환 ($: → $derived/$effect)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:01:00 +09:00
Hyungi Ahn
1a2b3b49af refactor: 사이드바를 전역 레이아웃으로 이동
- +layout.svelte: 사이드바 + 상단 nav 통합 (로그인/셋업 제외)
- 각 페이지 중복 nav 제거 (dashboard, documents, detail, inbox, settings)
- 모바일 drawer + ESC 닫기 전역 처리

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 09:00:20 +09:00
Hyungi Ahn
87747866b6 feat: Phase 1A — 사이드바 트리 네비게이션 + domain/sub_group 필터
- Sidebar.svelte: /api/documents/tree 기반 domain→sub_group 트리,
  접기/펼치기, active highlight, 모바일 drawer
- documents/+page.svelte: 2-pane 레이아웃, URL params 기반 필터,
  빈 상태 개선, 카드 정보 밀도 향상 (domain 경로, 태그, origin 배지)
- documents.py: sub_group 필터 파라미터 추가
- app.css: domain 7색 + sidebar CSS 변수

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:54:09 +09:00
Hyungi Ahn
faf9bda77a fix: set correct Content-Type and inline disposition for file serving
PDF was downloading instead of displaying because media_type was None
(defaulting to octet-stream). Now maps file extensions to proper MIME
types and sets Content-Disposition: inline for in-browser viewing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:38:10 +09:00
Hyungi Ahn
1affcb1afd fix: add query param token auth for file serving (iframe compat)
iframe/img tags can't send Bearer headers. File endpoint now accepts
?token= query parameter for authentication. Frontend passes access
token in URL for PDF/image viewers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:34:45 +09:00
Hyungi Ahn
e14084d5cd feat: add file serving endpoint GET /api/documents/{id}/file
Returns original document file from NAS. Fixes 404 on PDF/image
viewer in frontend. Updated frontend iframe/img src to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:32:51 +09:00