- +layout.svelte: 사이드바 + 상단 nav 통합 (로그인/셋업 제외)
- 각 페이지 중복 nav 제거 (dashboard, documents, detail, inbox, settings)
- 모바일 drawer + ESC 닫기 전역 처리
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
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>
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>
Shared session between queue consumer and workers caused
MissingGreenlet errors in APScheduler context. Each worker
call now gets its own session with explicit commit/rollback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- NAS fail-fast: 시작 시 /documents/PKM 존재 확인, NFS 미마운트 방지
- ollama/ai-gateway 포트를 127.0.0.1로 제한 (외부 무인증 접근 차단)
- deploy.md: Caddy HTTPS 자동발급 → 앞단 프록시 HTTPS 종료 구조 반영
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mac mini nginx proxies to GPU server Caddy. localhost-only binding
blocked external connections.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Integrate ollama + ai-gateway into root docker-compose.yml
(NVIDIA GPU runtime, single compose for all services)
- Change NAS mount from SMB (NAS_SMB_PATH) to NFS (NAS_NFS_PATH)
Default: /mnt/nas/Document_Server (fstab registered on GPU server)
- Update config.yaml AI endpoints:
primary → Mac mini MLX via Tailscale (100.76.254.116:8800)
fallback/embedding/vision/rerank → ollama (same Docker network)
gateway → ai-gateway (same Docker network)
- Update credentials.env.example (remove GPU_SERVER_IP, add NFS path)
- Mark gpu-server/docker-compose.yml as deprecated
- Update CLAUDE.md network diagram and AI model config
- Update architecture.md, deploy.md, devlog.md for GPU server as main
- Caddyfile: auto_https off, HTTP only (TLS at upstream proxy)
- Caddy port: 127.0.0.1:8080:80 (localhost only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The $: reactive statement was firing before onMount's tryRefresh()
completed, immediately redirecting to /login on every page refresh.
Added authChecked flag to gate the redirect logic.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Login 401 (TOTP required) was being caught by the refresh interceptor,
masking the actual error detail with "인증이 만료되었습니다".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nginx terminates TLS and forwards HTTP internally. Secure=True cookies
don't get sent when the backend sees HTTP connections.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nginx home-service-proxy terminates TLS and forwards plain HTTP to
Caddy on port 8080. Caddy doesn't need to match the domain name.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HIGH:
- Lock setup TOTP/NAS endpoints behind _require_setup() guard
(prevented unauthenticated admin 2FA takeover after setup)
- Sanitize upload filename with Path().name + resolve() validation
(prevented path traversal writing outside Inbox)
MEDIUM:
- Add score > 0.01 filter to hybrid search via subquery
(prevented returning irrelevant documents with zero score)
- Implement Inbox → Knowledge file move after classification
(classify_worker now moves files based on ai_domain)
- Add Anthropic Messages API support in _request()
(premium/Claude path now sends correct format and parses
content[0].text instead of choices[0].message.content)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Implement kordoc /parse endpoint (HWP/HWPX/PDF via kordoc lib,
text files direct read, images flagged for OCR)
- Add queue consumer with APScheduler (1min interval, stage chaining
extract→classify→embed, stale item recovery, retry logic)
- Add extract worker (kordoc HTTP call + direct text read)
- Add classify worker (Qwen3.5 AI classification with think-tag
stripping and robust JSON extraction from AI responses)
- Add embed worker (GPU server nomic-embed-text, graceful failure)
- Add DEVONthink migration script with folder mapping for 16 DBs,
dry-run mode, batch commits, and idempotent file_path UNIQUE
- Enhance ai/client.py with strip_thinking() and parse_json_response()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Frontend SvelteKit build has dependency conflicts (Svelte 5 + Vite 8).
Phase 0 setup wizard is served by FastAPI/Jinja2, no frontend needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add users table to migration, User ORM model
- Implement JWT+TOTP auth API (login, refresh, me, change-password)
- Add first-run setup wizard with rate-limited admin creation,
TOTP QR enrollment (secret saved only after verification), and
NAS path verification — served as Jinja2 single-page HTML
- Add setup redirect middleware (bypasses /health, /docs, /openapi.json)
- Mount config.yaml, scripts, logs volumes in docker-compose
- Route API vs frontend traffic in Caddyfile
- Include admin seed script as CLI fallback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
remote의 v1 업데이트(GPU 재구성, RAG, 버그 픽스 등 9커밋)를 merge.
v1 파일은 모두 삭제 (v1-final 태그에 보존됨).
v2 문서(CLAUDE.md, README.md, deploy.md, architecture.md)는 우리 버전 유지.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DEVONthink 탈피 후 FastAPI + PostgreSQL + SvelteKit + Docker 기반
자체 PKM 웹앱으로의 전환 설계 문서.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- law_monitor.py: 2-pass 크로스 링크 적용
- Pass 1: 전체 법령 파싱 + 조문-장 매핑 테이블 생성
- Pass 2: 「법령명」 제X조 → [[법명_제N장#제X조]] wiki-link 일괄 적용
- 변경된 법령에만 크로스 링크 적용 후 DEVONthink 임포트
- pkm_api_server.py: RAG 응답에 enable_thinking=false + strip_thinking 적용
- launchd: pkm-api(Flask), law-monitor(07:00), mailplus(07:00+18:00), digest(20:00) plist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
기존: /10_Legislation/{법령명} (Law 폴더 누락)
수정: /10_Legislation/Law/{법령명} (architecture 설계 구조와 일치)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- law_parser.py 신규: XML→MD 장 단위 분할, 조문 앵커 링크, 부칙 분리
- 장/절/편 자동 식별 (<조문여부>=전문), 장 없는 법령 fallback
- DEVONthink wiki-link 크로스 링크 (같은 법률 내 + 다른 법률 간)
- MST 자동 조회 + 7일 TTL 캐시 + 원자적 파일 쓰기
- 법령 약칭 매핑 (산안법→산업안전보건법 등)
- law_monitor.py 리팩터링:
- MONITORED_LAWS → Tier 1(15개 필수) / Tier 2(8개 참고, 비활성)
- law_id → MST 방식 (현행 법령 자동 조회)
- XML 통짜 저장 → 장별 Markdown 분할 저장
- DEVONthink 3단계 교체 (이동→생성→삭제, wiki-link 보존)
- 에러 핸들링: 재시도 3회/백오프 + 부분 실패 허용 + 법령명 검증
- 실행 결과 law_last_run.json 기록
테스트: 15개 법령 전체 성공 (148개 MD 파일 생성)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- pkm_utils.py: strip_thinking() 추가 + llm_generate() no_think 옵션
- <think> 태그 제거 + thinking 패턴("Wait,", "Let me" 등) 필터링
- enable_thinking: false 파라미터 지원
- law_monitor.py: JP 번역 호출에 no_think=True 적용
- pkm_api_server.py: /devonthink/stats 최적화 (children 순회 → count 사용)
+ /devonthink/search 한글 쿼리 이스케이프 수정
- auto_classify.scpt: baseDir property로 경로 변수화
- omnifocus_sync.scpt: 로그 경로 변수화
인프라: MailPlus IMAP HOST → LAN IP(192.168.1.227)로 변경
참고: 한국 법령 API IP(122.153.226.74) open.law.go.kr 등록 필요
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>