Files
hyungi_document_server/CLAUDE.md
T
Hyungi Ahn f6f8f3b9d8 docs(claude): refresh — drop stale model/IP, inventory authoritative
stale 영역 정리:
- Qwen3.5-35B-A3B / nomic-embed-text / Qwen2.5-VL-7B → 역할별 표기 (실제 모델은 inventory)
- Mac mini Tailscale 100.76.254.116 / GPU 100.111.160.84 / NAS 100.101.79.37 → 모두 폐기 (D21 closure 2026-05-12), LAN 표기만 유지
- Mac mini nginx 앞단 프록시 → 폐기 (home-caddy 가 직접 ingress)
- "Mac mini 메인 docker compose" → GPU 가 메인 정정

추가:
- 운영 변경 정책 (inventory → config → deploy → verify)
- 머신 역할 표 / AI 파이프라인 역할 표 / 워커 스케줄 표
- 아침 브리핑 / global digest 진입점 + scheduler timezone
- asyncpg multi-statement 1 파일 1 statement 규칙 (PR-MorningBriefing-1 fix 교훈)
- 디자인 토큰 only 규칙
- 한국어 NFS 경로 NFC/NFD
2026-05-12 15:07:12 +09:00

7.4 KiB
Raw Blame History

hyungi_Document_Server — Claude Code 작업 가이드

Infrastructure Reference 📌

운영 사실 (모델명 / 엔드포인트 / IP / 컨테이너 / 포트 / drift) 의 단일 진실 소스(SSOT):

~/.claude/projects/-Users-hyungiahn/memory/infra_inventory.md

이 파일과 inventory 가 충돌하면 inventory 가 정답. 본 CLAUDE.md 는 코딩 규칙·워크플로우·코드 구조에 집중하고 운영 값은 박지 않는다.

운영 변경 정책 (inventory → config → deploy → verify):

  1. infra_inventory.md 먼저 갱신
  2. config.yaml / credentials.env 갱신
  3. deploy (commit → push → GPU pull → docker compose up -d --build)
  4. verify (smoke endpoint, postgres count, 모니터링)

순서 어기면 drift. 발견 시 inventory Drift Log 등록.

Search experiment soft lock: Phase 2 search refactor / QueryAnalyzer / run_eval 진행 중일 때 GPU 서버의 docker compose restart, config.yaml 수정, Ollama pull 금지. flag = ~/.claude/.search-experiment-active.


프로젝트 개요

Self-hosted PKM(Personal Knowledge Management) + 다국 뉴스 비교 분석 웹 애플리케이션. GPU 서버가 메인 (Docker Compose / DB / 검색 / OCR / 마커), Mac mini = MLX 추론 + Whisper STT, Synology NAS = 파일 원본.

핵심 문서

  1. README.md — 외부 소개 (기술 스택 / 주요 기능 / Quick Start)
  2. docs/architecture.md — 전체 시스템 아키텍처
  3. docs/deploy.md — Docker Compose 배포 가이드
  4. docs/development-stages.md — Phase roadmap (역사적 맥락)

기술 스택

영역 기술
백엔드 FastAPI (Python 3.11+), SQLAlchemy 2.0 async, APScheduler
DB PostgreSQL 16 + pgvector + pg_trgm (단일 pkm DB)
프론트엔드 SvelteKit 5 (runes mode) + Tailwind CSS 4
문서 파싱 kordoc (HWP/HWPX/PDF → MD), LibreOffice headless (오피스), marker (PDF → markdown)
OCR Surya OCR (docker compose ocr-service, GPU)
STT MLX Whisper (Mac mini), GPU faster-whisper 는 legacy profile
리버스 프록시 Caddy (HTTP only, 앞단 home-caddy 가 HTTPS 종료)
인증 JWT (access) + HttpOnly cookie (refresh) + TOTP 2FA
컨테이너 Docker Compose

머신 역할 (자세한 IP / 포트 → inventory)

머신 역할
GPU 서버 Docker Compose 메인: fastapi · frontend · postgres pkm · kordoc · ocr-service · marker-service · reranker (TEI) · caddy. Ollama (embedding / 4B 추론). home-gateway 별 compose (ingress + 나노클로 + searxng)
Mac mini MLX 26B 추론 endpoint + MLX Whisper STT. ingress 역할 0
Synology NAS 파일 원본 (/volume4/Document_Server/PKM/ → GPU /mnt/nas/Document_Server NFS), Synology Office/Drive/Calendar/MailPlus
VPS-2 (OVH) 메일 relay (relay.hyungi.net:587), Gitea bare mirror, Secondary MX

AI 파이프라인 (역할 기준 — 실제 모델 매핑은 inventory)

역할 위치
분류/심층 요약 primary Mac mini MLX 26B
Triage (1차 분류) / Fallback / Chat GPU Ollama 4B
Embedding GPU Ollama (1024d, 다국어)
Reranker GPU TEI 컨테이너
OCR docker compose ocr-service (Surya OCR GPU) — ai.models.vision 미사용
STT Mac mini MLX Whisper large-v3
Premium (수동 trigger) Anthropic API (require_explicit_trigger, 일일 한도)

호출 시 반드시 app/ai/client.pyAIClient 사용 (call_triage / call_primary / call_fallback). 직접 HTTP 호출 금지.

문서 처리 파이프라인

파일 업로드 (드래그 앤 드롭 or file_watcher)
    ↓
extract (텍스트 추출)
  - kordoc:       HWP, HWPX, PDF → Markdown
  - LibreOffice:  xlsx, docx, pptx 등 → txt/csv
  - 직접 읽기:    md, txt, csv, json, xml, html
    ↓                                    ↓
classify_worker (tier triage)        preview / marker
  - 4B Ollama → TriageOutput              - LibreOffice → PDF 변환
  - escalate_to_26b 시 deep_summary       - marker → PDF → markdown
  - ai_tldr / ai_bullets / inconsistencies
    ↓
embed_worker (bge-m3 1024d, doc-level)
chunk_worker (문서 유형별 chunking)

핵심 원칙:

  • 파일은 업로드 위치에 그대로 유지 (물리적 이동 없음)
  • 분류 (ai_domain / ai_sub_group / ai_tags / category / tier) 는 DB 메타데이터로만 관리
  • preview / marker 는 classify 와 병렬

워커 / 스케줄러 (app/main.py 의 scheduler.add_job)

  • queue_consumer (interval 1m), file_watcher (5m), upload_cleanup (10m)
  • study_q_embed (1m), study_q_related_refresh (1m), study_queue (1m), study_session_queue (1m)
  • tier_backfill (30m)
  • law_monitor (07:00 KST), mailplus_archive (07/18:00 KST)
  • daily_digest (20:00 KST)
  • global_digest (04:00 KST) — Phase 4 country×topic 7일 rolling
  • morning_briefing (05:10 KST) — 야간 KST 0~5h 수집 뉴스 topic×country 비교

scheduler timezone = Asia/Seoul.

데이터 계층

  1. 원본 파일 — NAS /volume4/Document_Server/PKM/. 유일한 원본, 위치 변경 없음
  2. 가공 데이터 — PostgreSQL pkm (텍스트, AI 분류, 검색 인덱스, 메모, 태그, briefing, digest, …)
  3. 파생물 — pgvector embedding, PDF preview 캐시 (.preview/), marker 결과 (markdown + extracted_images NAS 저장)

코딩 규칙

  • Python 3.11+, asyncio, type hints
  • SQLAlchemy 2.0+ async 세션
  • Svelte 5 runes mode ($state, $derived, $effect$: 금지)
  • 인증 정보는 credentials.env 에서 로딩 (하드코딩 금지)
  • 로그는 logs/ (Docker 볼륨)
  • AI 호출은 반드시 app/ai/client.pyAIClient 경유
  • 한글 주석 사용
  • Migration: migrations/NNN_*.sql, init_db() 자동 실행 (schema_migrations 추적)
    • SQL 에 BEGIN/COMMIT 금지 (외부 트랜잭션 깨짐)
    • asyncpg prepared statement 가 multi-statement 불허 → 1 statement 1 파일 분리
    • 기존 DB 에서는 schema_migrations 수동 이력 등록 필요할 수 있음
  • 디자인 시스템 토큰 only (bg-surface, text-dim, border-default, text-accent, …). bg-[var(--*)] 금지 (lint:tokens 차단)
  • 커밋 메시지: type(scope): summary (feat / fix / refactor / ops / incident / docs)

개발 / 배포 워크플로우

# 개발 (MacBook Pro)
cd ~/Documents/code/hyungi_Document_Server/
# 코드 작성 → git commit → push (Gitea)

# 배포 (GPU 서버)
ssh gpu
cd ~/Documents/code/hyungi_Document_Server/
git pull
docker compose up -d --build fastapi frontend

PR 머지는 Gitea UI Rebase and merge 기본 (선형 히스토리 + force-push 충돌 회피). 단독 작업 확증 시만 로컬 rebase+FF.

v1 코드 참조

v1 (DEVONthink 기반) 코드는 v1-final 태그로 보존:

git show v1-final:scripts/law_monitor.py
git show v1-final:scripts/pkm_utils.py

주의사항

  • credentials.env 는 git 에 올리지 않음 (.gitignore)
  • NAS NFS 마운트: Docker 컨테이너 내 /documents. FastAPI 시작 시 /documents/PKM 존재 확인
  • 법령 API (LAW_OC) 는 승인 대기 중
  • Ollama 는 127.0.0.1 바인딩 (외부 접근 차단)
  • Caddy 는 auto_https off + http:// only (HTTPS 종료는 앞단 home-caddy 가 처리)
  • Synology Office 편집은 새 탭 열기 방식 (iframe 미사용, edit_url 수동 등록)
  • 한국어 NFS 경로는 NFC↔NFD 비대칭 — 경로 수신 시 NFC→NFD→parent glob fallback 필수