diff --git a/CLAUDE.md b/CLAUDE.md index 3eb2660..894bf29 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,127 +2,72 @@ ## Infrastructure Reference πŸ“Œ -**Always refer to** `~/.claude/projects/-Users-hyungiahn/memory/infra_inventory.md` for: -- AI model routing (primary / fallback / embedding / rerank / vision) β€” **the model names below may be stale** -- Machine info, Tailscale IPs, SSH targets -- Docker container topology and compose projects -- Drift log (known Desired vs Actual inconsistencies) -- Verify commands +운영 사싀 (λͺ¨λΈλͺ… / μ—”λ“œν¬μΈνŠΈ / IP / μ»¨ν…Œμ΄λ„ˆ / 포트 / drift) 의 단일 μ§„μ‹€ μ†ŒμŠ€(SSOT): -**If this file and `infra_inventory.md` disagree, `infra_inventory.md` is authoritative.** Do not change `config.yaml` / `credentials.env` without first updating `infra_inventory.md`. +**`~/.claude/projects/-Users-hyungiahn/memory/infra_inventory.md`** -**Search experiment soft lock**: During Phase 2 work (search.py refactor, QueryAnalyzer, run_eval.py execution), do **not** run `docker compose restart`, change `config.yaml`, or pull Ollama models. Violating this invalidates the experiment baseline. +이 파일과 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) μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜. -FastAPI + PostgreSQL(pgvector) + SvelteKit + Docker Compose 기반. -GPU μ„œλ²„λ₯Ό 메인 μ„œλ²„, Mac miniλ₯Ό AI μΆ”λ‘ , Synology NASλ₯Ό 파일 μ €μž₯μ†Œλ‘œ μ‚¬μš©. +Self-hosted PKM(Personal Knowledge Management) + λ‹€κ΅­ λ‰΄μŠ€ 비ꡐ 뢄석 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜. +GPU μ„œλ²„κ°€ 메인 (Docker Compose / DB / 검색 / OCR / 마컀), Mac mini = MLX μΆ”λ‘  + Whisper STT, Synology NAS = 파일 원본. ## 핡심 λ¬Έμ„œ -1. `docs/architecture.md` β€” 전체 μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜ (DB μŠ€ν‚€λ§ˆ, AI μ „λž΅, 인프라, UI 섀계) -2. `docs/deploy.md` β€” Docker Compose 배포 κ°€μ΄λ“œ -3. `docs/development-stages.md` β€” Phase 0~5 개발 단계별 κ°€μ΄λ“œ +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+) | -| λ°μ΄ν„°λ² μ΄μŠ€ | PostgreSQL 16 + pgvector + pg_trgm | +| λ°±μ—”λ“œ | 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 β†’ Markdown) + LibreOffice (μ˜€ν”ΌμŠ€ β†’ ν…μŠ€νŠΈ/PDF) | -| λ¦¬λ²„μŠ€ ν”„λ‘μ‹œ | Caddy (HTTP only, μ•žλ‹¨ ν”„λ‘μ‹œμ—μ„œ HTTPS 처리) | -| 인증 | JWT + TOTP 2FA | +| λ¬Έμ„œ νŒŒμ‹± | 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 μ„œλ²„ (RTX 4070 Ti Super, Ubuntu, 메인 μ„œλ²„): - - Docker Compose: FastAPI(:8000), PostgreSQL(:5432), kordoc(:3100), - Caddy(:8080 HTTP only), Ollama(127.0.0.1:11434), AI Gateway(127.0.0.1:8081), frontend(:3000) - - NFS 마운트: /mnt/nas/Document_Server β†’ NAS /volume4/Document_Server - - μ™ΈλΆ€ μ ‘κ·Ό: document.hyungi.net (Mac mini nginx β†’ Caddy) - - 둜컬 IP: 192.168.1.186 +| λ¨Έμ‹  | μ—­ν•  | +|------|------| +| 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 | -Mac mini M4 Pro (AI μ„œλ²„ + μ•žλ‹¨ ν”„λ‘μ‹œ): - - MLX Server: http://100.76.254.116:8800/v1/chat/completions (Qwen3.5-35B-A3B) - - nginx: HTTPS μ’…λ£Œ β†’ GPU μ„œλ²„ Caddy(:8080)둜 ν”„λ‘μ‹œ - - Tailscale IP: 100.76.254.116 +## AI νŒŒμ΄ν”„λΌμΈ (μ—­ν•  κΈ°μ€€ β€” μ‹€μ œ λͺ¨λΈ 맀핑은 inventory) -Synology NAS (DS1525+): - - LAN IP: 192.168.1.227 - - Tailscale IP: 100.101.79.37 - - 파일 원본: /volume4/Document_Server/PKM/ - - NFS export β†’ GPU μ„œλ²„ - - Synology Drive: https://link.hyungi.net (λ¬Έμ„œ νŽΈμ§‘) - - Synology Calendar: CalDAV νƒœμŠ€ν¬ 관리 - - MailPlus: IMAP(993) + SMTP(465) -``` +| μ—­ν•  | μœ„μΉ˜ | +|------|------| +| λΆ„λ₯˜/심측 μš”μ•½ 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`, 일일 ν•œλ„) | -## 인증 정보 - -- μœ„μΉ˜: `credentials.env` (ν”„λ‘œμ νŠΈ 루트, .gitignore에 포함) -- ν…œν”Œλ¦Ώ: `credentials.env.example` -- μŠ€ν¬λ¦½νŠΈμ—μ„œ python-dotenv λ˜λŠ” Docker env_file둜 λ‘œλ”© - -## AI λͺ¨λΈ ꡬ성 - -``` -Primary (Mac mini MLX, Tailscale 경유, μƒμ‹œ, 무료): - mlx-community/Qwen3.5-35B-A3B-4bit β€” λΆ„λ₯˜, νƒœκ·Έ, μš”μ•½ - β†’ http://100.76.254.116:8800/v1/chat/completions - -Fallback (GPU Ollama, 같은 Docker λ„€νŠΈμ›Œν¬, MLX μž₯μ•  μ‹œ): - qwen3.5:35b-a3b - β†’ http://ollama:11434/v1/chat/completions - -Premium (Claude API, μ’…λŸ‰μ œ, μˆ˜λ™ 트리거만): - claude-sonnet β€” λ³΅μž‘ν•œ 뢄석, μž₯λ¬Έ 처리 - β†’ 일일 ν•œλ„ $5, require_explicit_trigger: true - -Embedding (GPU Ollama, 같은 Docker λ„€νŠΈμ›Œν¬): - nomic-embed-text β†’ 벑터 μž„λ² λ”© - Qwen2.5-VL-7B β†’ 이미지/도면 OCR - bge-reranker-v2-m3 β†’ RAG λ¦¬λž­ν‚Ή -``` - -## ν”„λ‘œμ νŠΈ ꡬ쑰 - -``` -hyungi_Document_Server/ -β”œβ”€β”€ docker-compose.yml -β”œβ”€β”€ Caddyfile ← HTTP only, auto_https off -β”œβ”€β”€ config.yaml ← AI μ—”λ“œν¬μΈνŠΈ, NAS 경둜, μŠ€μΌ€μ€„ -β”œβ”€β”€ credentials.env.example -β”œβ”€β”€ app/ ← FastAPI λ°±μ—”λ“œ -β”‚ β”œβ”€β”€ main.py ← μ—”νŠΈλ¦¬ν¬μΈνŠΈ + APScheduler (watcher/consumer 포함) -β”‚ β”œβ”€β”€ Dockerfile ← LibreOffice headless 포함 -β”‚ β”œβ”€β”€ core/ (config, database, auth, utils) -β”‚ β”œβ”€β”€ models/ (document, task, queue) -β”‚ β”œβ”€β”€ api/ (documents, search, dashboard, auth, setup) -β”‚ β”œβ”€β”€ workers/ (file_watcher, extract, classify, embed, preview, law_monitor, mailplus, digest, queue_consumer) -β”‚ β”œβ”€β”€ prompts/classify.txt -β”‚ └── ai/client.py ← AIClient + parse_json_response (Qwen3.5 thinking 처리) -β”œβ”€β”€ services/kordoc/ ← Node.js λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ (HWP/PDF νŒŒμ‹±) -β”œβ”€β”€ gpu-server/ ← AI Gateway (deprecated, 톡합됨) -β”œβ”€β”€ frontend/ ← SvelteKit 5 -β”‚ └── src/ -β”‚ β”œβ”€β”€ routes/ ← νŽ˜μ΄μ§€ (documents, inbox, settings, login) -β”‚ └── lib/ -β”‚ β”œβ”€β”€ components/ ← Sidebar, DocumentCard, DocumentViewer, PreviewPanel, -β”‚ β”‚ TagPill, FormatIcon, UploadDropzone -β”‚ β”œβ”€β”€ stores/ ← auth, ui -β”‚ └── api.ts ← fetch wrapper (JWT 토큰 관리) -β”œβ”€β”€ migrations/ ← PostgreSQL μŠ€ν‚€λ§ˆ (schema_migrations둜 좔적) -β”œβ”€β”€ scripts/ -β”œβ”€β”€ docs/ -└── tests/ -``` +호좜 μ‹œ λ°˜λ“œμ‹œ `app/ai/client.py` 의 `AIClient` μ‚¬μš© (`call_triage` / `call_primary` / `call_fallback`). 직접 HTTP 호좜 κΈˆμ§€. ## λ¬Έμ„œ 처리 νŒŒμ΄ν”„λΌμΈ @@ -130,82 +75,77 @@ hyungi_Document_Server/ 파일 μ—…λ‘œλ“œ (λ“œλž˜κ·Έ μ•€ λ“œλ‘­ or file_watcher) ↓ extract (ν…μŠ€νŠΈ μΆ”μΆœ) - - kordoc: HWP, HWPX, PDF β†’ Markdown - - LibreOffice: xlsx, docx, pptx, odt λ“± β†’ txt/csv - - 직접 읽기: md, txt, csv, json, xml, html - ↓ ↓ -classify (AI λΆ„λ₯˜) preview (PDF 미리보기 생성) - - Qwen3.5 β†’ domain - LibreOffice β†’ PDF λ³€ν™˜ - - tags, summary - μΊμ‹œ: PKM/.preview/{id}.pdf + - 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 (벑터 μž„λ² λ”©) - - nomic-embed-text (768차원) +embed_worker (bge-m3 1024d, doc-level) +chunk_worker (λ¬Έμ„œ μœ ν˜•λ³„ chunking) ``` -**핡심 원칙:** +핡심 원칙: - νŒŒμΌμ€ μ—…λ‘œλ“œ μœ„μΉ˜μ— κ·ΈλŒ€λ‘œ μœ μ§€ (물리적 이동 μ—†μŒ) -- λΆ„λ₯˜(domain/sub_group/tags)λŠ” DB λ©”νƒ€λ°μ΄ν„°λ‘œλ§Œ 관리 -- previewλŠ” classify와 λ³‘λ ¬λ‘œ μ‹€ν–‰ (AI κ²°κ³Ό λΆˆν•„μš”) +- λΆ„λ₯˜ (`ai_domain` / `ai_sub_group` / `ai_tags` / `category` / `tier`) λŠ” DB λ©”νƒ€λ°μ΄ν„°λ‘œλ§Œ 관리 +- preview / marker λŠ” classify 와 병렬 -## UI ꡬ쑰 +## μ›Œμ»€ / μŠ€μΌ€μ€„λŸ¬ (`app/main.py` 의 scheduler.add_job) -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ [☰ μ‚¬μ΄λ“œλ°”] [PKM / λ¬Έμ„œ] [β„Ή 정보] λ²„νŠΌβ”‚ ← 상단 nav -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ [검색바] [λͺ¨λ“œ] [β„Ή] β”‚ -β”‚ λ¬Έμ„œ λͺ©λ‘ (30%) β€” λ“œλž˜κ·Έ μ—…λ‘œλ“œ 지원 β”‚ ← 상단 μ˜μ—­ -β”‚ β–ˆ λ¬Έμ„œμΉ΄λ“œ (domain 색상 λ°” + 포맷 μ•„μ΄μ½˜) β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ ν•˜λ‹¨ λ·°μ–΄/νŽΈμ§‘ (70%) β€” 전체 λ„ˆλΉ„ β”‚ ← ν•˜λ‹¨ μ˜μ—­ -β”‚ Markdown: split editor (textarea + preview) β”‚ -β”‚ PDF: λΈŒλΌμš°μ € λ‚΄μž₯ λ·°μ–΄ β”‚ -β”‚ μ˜€ν”ΌμŠ€: PDF λ³€ν™˜ 미리보기 + [νŽΈμ§‘] μƒˆ νƒ­ λ²„νŠΌ β”‚ -β”‚ 이미지: img νƒœκ·Έ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +- 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 비ꡐ -μ‚¬μ΄λ“œλ°”: ν‰μ†Œ μ ‘νž˜, ☰둜 μ˜€λ²„λ ˆμ΄ (domain 트리 + 슀마트 κ·Έλ£Ή + Inbox) -정보 νŒ¨λ„: β„Ή λ²„νŠΌ β†’ 우츑 전체 높이 drawer (λ©”λͺ¨/νƒœκ·Έ νŽΈμ§‘/메타/μ²˜λ¦¬μƒνƒœ/νŽΈμ§‘ URL) -``` +scheduler timezone = `Asia/Seoul`. ## 데이터 계측 -1. **원본 파일** (NAS `/volume4/Document_Server/PKM/`) β€” μœ μΌν•œ 원본, μœ„μΉ˜ λ³€κ²½ μ—†μŒ -2. **가곡 데이터** (PostgreSQL) β€” ν…μŠ€νŠΈ μΆ”μΆœ, AI λΆ„λ₯˜, 검색 인덱슀, λ©”λͺ¨, νƒœκ·Έ -3. **νŒŒμƒλ¬Ό** β€” 벑터 μž„λ² λ”© (pgvector), PDF 미리보기 μΊμ‹œ (`.preview/`) +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.py`의 `AIClient`λ₯Ό 톡해 (직접 HTTP 호좜 κΈˆμ§€) +- Svelte 5 runes mode (`$state`, `$derived`, `$effect` β€” `$:` κΈˆμ§€) +- 인증 μ •λ³΄λŠ” `credentials.env` μ—μ„œ λ‘œλ”© (ν•˜λ“œμ½”λ”© κΈˆμ§€) +- λ‘œκ·ΈλŠ” `logs/` (Docker λ³Όλ₯¨) +- AI ν˜ΈμΆœμ€ λ°˜λ“œμ‹œ `app/ai/client.py` 의 `AIClient` 경유 - ν•œκΈ€ 주석 μ‚¬μš© -- Migration: `migrations/*.sql`에 μž‘μ„±, `init_db()`κ°€ μžλ™ μ‹€ν–‰ (schema_migrations 좔적) - - SQL에 BEGIN/COMMIT κΈˆμ§€ (μ™ΈλΆ€ νŠΈλžœμž­μ…˜ 깨짐) - - κΈ°μ‘΄ DBμ—μ„œλŠ” schema_migrations에 μˆ˜λ™ 이λ ₯ 등둝 ν•„μš”ν•  수 있음 +- 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`) -## 개발/배포 μ›Œν¬ν”Œλ‘œμš° +## 개발 / 배포 μ›Œν¬ν”Œλ‘œμš° +```bash +# 개발 (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 ``` -MacBook Pro (개발) β†’ Gitea push β†’ GPU μ„œλ²„μ—μ„œ pull -개발: - cd ~/Documents/code/hyungi_Document_Server/ - # μ½”λ“œ μž‘μ„± β†’ git commit & push - -GPU μ„œλ²„ 배포 (메인): - ssh hyungi@100.111.160.84 - 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` νƒœκ·Έλ‘œ 보쑴: +v1 (DEVONthink 기반) μ½”λ“œλŠ” `v1-final` νƒœκ·Έλ‘œ 보쑴: ```bash git show v1-final:scripts/law_monitor.py git show v1-final:scripts/pkm_utils.py @@ -213,10 +153,10 @@ git show v1-final:scripts/pkm_utils.py ## μ£Όμ˜μ‚¬ν•­ -- credentials.envλŠ” git에 μ˜¬λ¦¬μ§€ μ•ŠμŒ (.gitignore) -- NAS NFS 마운트 경둜: Docker μ»¨ν…Œμ΄λ„ˆ λ‚΄ `/documents` -- FastAPI μ‹œμž‘ μ‹œ `/documents/PKM` 쑴재 확인 (NFS 미마운트 λ°©μ§€) -- 법령 API (LAW_OC)λŠ” 승인 λŒ€κΈ° 쀑 -- Ollama/AI Gateway ν¬νŠΈλŠ” 127.0.0.1 바인딩 (μ™ΈλΆ€ μ ‘κ·Ό 차단) -- CaddyλŠ” `auto_https off` + `http://` only (HTTPSλŠ” Mac mini nginxμ—μ„œ 처리) -- Synology Office νŽΈμ§‘μ€ μƒˆ νƒ­ μ—΄κΈ° 방식 (iframe λ―Έμ‚¬μš©, edit_url μˆ˜λ™ 등둝) +- `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 ν•„μˆ˜