Hyungi Ahn
3375a5f1b1
feat(ui): Phase D.3 — multi-select + batch actions (pLimit)
...
- DocumentTable/DocumentCard: selectable/selectedIds/onselectionchange props
* Table: 왼쪽 6px 너비 체크박스 컬럼
* Card: 좌상단 absolute 체크박스 (hover 또는 selected 시 표시)
* 체크박스 onclick stopPropagation으로 행 select와 분리
- documents/+page.svelte:
* selectedIds = $state(new Set()), URL/필터 변경 시 자동 초기화
* sticky 선택 toolbar (selection > 0): N건 / 전체 선택 / 선택 해제 /
일괄 도메인 / 일괄 태그 / 일괄 삭제
* 50건 상한 UI 가드 (초과 시 경고 + 모든 bulk 버튼 disabled)
* Bulk modals:
- 일괄 도메인: Select (Knowledge/* 6종 + Reference)
- 일괄 태그: TextInput (기존 ai_tags에 추가, 중복 skip)
- 일괄 삭제: ConfirmDialog (delete_file=true)
* runBulk 헬퍼: pLimit(5) + Promise.allSettled로 concurrency 제한,
성공/실패 카운트 toast (5대 원칙 #4 )
* TODO(backend): POST /documents/batch-update — 단일 트랜잭션으로 교체
검증:
- npm run build 통과 (새 경고 없음, label → span 교체로 a11y clean)
- npm run lint:tokens 231 유지 (신규 코드 위반 0)
- 기존 pLimit.ts (Phase A 머지) 재사용, 외부 의존성 없음
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-08 12:34:02 +09:00
Hyungi Ahn
ffac4975b9
feat(ui): Phase D.1 — 3-panel layout + DocumentMetaRail + useMedia
...
- 가로 flex 최상위 + 가운데 flex-1 (기존 list/viewer 세로 split 그대로 보존)
- xl+ (≥1280px): 우측 320px persistent rail, 접기 시 40px sliver.
localStorage.metaRailOpen 으로 상태 유지.
- < xl : 기존 수동 drawer 제거하고 ui/Drawer primitive + uiState 사용.
- 리사이즈 시 xl+ 진입하면 drawer 자동 close (rail로 승계).
- handleKeydown → ui.handleEscape() 로 중앙화.
- ℹ 버튼 token 기반 재작성 (isXl 분기로 rail/drawer 토글).
- PreviewPanel.svelte 한 글자도 수정 없음 (Phase E 영역).
신규:
- frontend/src/lib/composables/useMedia.svelte.ts — matchMedia runes 컴포저블
- frontend/src/lib/components/DocumentMetaRail.svelte — PreviewPanel wrapper
검증:
- npm run build 통과
- npm run lint:tokens 241 → 236 (신규 코드 0 위반, 레거시 drawer/ℹ 버튼
제거로 5건 organically 감소)
- PreviewPanel diff 0줄
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-08 12:18:06 +09:00
Hyungi Ahn
b3124928a6
feat(ui): Phase C — 대시보드 위젯 그리드 + dashboardSummary 공유 fetch
...
- dashboardSummary store 구독으로 SystemStatusDot과 fetch 1회 공유 (60초 폴링)
- Svelte 5 runes + Card/EmptyState/Skeleton/FormatIcon 프리미티브
- 12-col 그리드 (sm 1열 / md 2열 / lg 표 그대로):
* 행1: stat 4장 (전체/Inbox/법령/시스템 상태)
* 행2: 파이프라인 가로 막대 차트(8) + 오늘 도메인 누적바(4)
* 행3: 최근 문서(8) + CalDAV stub(4)
- 신규 util: domainSlug.ts — ai_domain → bg-domain-{slug} + 라벨 매핑
- 새 코드에 bg-[var(--*)] 0건 (lint:tokens 통과)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-08 12:13:36 +09:00
Hyungi Ahn
0c63c0b6ab
feat(ui): Phase B — sidebar drawer + SystemStatusDot + 키보드 nav
...
- +layout.svelte: 햄버거 → IconButton, 우측 nav → Button ghost,
sidebar overlay → Drawer (uiState 단일 slot),
Esc 글로벌 핸들러 ui.handleEscape() 위임 (5대 원칙 #2 )
- lib/stores/system.ts (신규): dashboardSummary writable + 60s 폴링,
단일 fetch를 SystemStatusDot(B)와 dashboard(C)가 공유
- SystemStatusDot.svelte (신규): 8px 도트 + tooltip,
failed > 0 → error / pending > 10 → warning / 그 외 → success
- Sidebar.svelte: 트리에 ArrowUp/Down 키보드 nav,
활성 도메인 row에 aria-current="page"
2026-04-07 13:52:24 +09:00
Hyungi Ahn
c294df5987
refactor(tokens): A-8 Batch 3 — PreviewPanel / DocumentViewer / +layout(toast)
...
가장 큰 위험 batch. Phase A 디자인 시스템 정착 마지막 mechanical refactor
(8 파일 8/8 누적 — core components 0 hit 달성).
PreviewPanel (53 hits → 0):
- bg-[var(--sidebar-bg)] → bg-sidebar (메인 aside)
- bg-[var(--bg)] → bg-bg (input 배경)
- bg-[var(--surface)] → bg-surface (hover)
- bg-[var(--accent)] → bg-accent + hover:bg-accent-hover (저장 버튼)
- bg-[var(--error)] → bg-error (삭제 확인)
- text/border 토큰 일괄 swap
- focus:border-accent (input)
- confidence 색상 (green/amber/red palette)은 plan B3 명시 없어 그대로
DocumentViewer (28 hits → 0):
- 뷰어 본체 bg-surface border-default
- 툴바 bg-sidebar
- 마크다운 편집 탭 bg-surface, edit textarea bg-bg
- 상태별 hover 토큰 swap
- 뉴스 article 태그 blue-900/30 그대로 (lint:tokens 미검출)
+layout.svelte (10 hits → 0):
- nav 잔여 var() (햄버거, 로고, 메뉴 링크) 토큰 swap
- 로딩 텍스트 text-dim
- toast 영역 의미 swap (plan B3 명시):
* green-900/200 → bg-success/10 + text-success + border-success/30
* red-900/200 → bg-error/10 + text-error + border-error/30
* yellow-900/200 → bg-warning/10 + text-warning + border-warning/30
* blue-900/200 → bg-accent/10 + text-accent + border-accent/30
- class:* 디렉티브 8개 → script TOAST_CLASS dict + dynamic class binding
(svelte 5에서 슬래시 포함 클래스명을 class: 디렉티브로 못 씀)
검증:
- npm run lint:tokens : 360 → 269 (-91, B3 파일 0 hit)
- 누적 진행: 421 → 269 (-152 / 8 파일 완료, plan 정정 목표 정확 달성)
- npm run build : ✅
- npx svelte-check : ✅ 0 errors
- ⚠ 3-risk grep : hover/border-border/var() 잔여 0건
A-8 종료 시점 상태:
- core components 8 파일: lint:tokens 0 hit ✅
- routes 7 파일 잔존 (~269): news 92, settings 47, documents/[id] 36,
+page 28, documents 26, inbox 25, login 15
- lint:tokens 강제화 (pre-commit hook)는 Phase D + F 완료 후 별도 commit
플랜: ~/.claude/plans/compressed-churning-dragon.md §A.4 Batch 3
2026-04-07 12:14:48 +09:00
Hyungi Ahn
8ec89517ee
refactor(tokens): A-8 Batch 2 — Sidebar / DocumentCard / DocumentTable
...
목록/사이드바 영역의 var() 토큰을 의미 토큰으로 swap. Phase A 디자인
시스템 정착의 두 번째 mechanical refactor batch (8 파일 중 5/8 누적).
Sidebar:
- bg-[var(--sidebar-bg)] → bg-sidebar (이름 변경)
- border-[var(--border)] → border-default
- text-[var(--text)] → text-text
- text-[var(--text-dim)] → text-dim
- bg-[var(--accent)]/15 → bg-accent/15
- hover:bg-[var(--surface)] → hover:bg-surface
- domain 색상 inline style (DOMAIN_COLORS)은 그대로 유지
DocumentCard:
- bg/border/text/hover 토큰 일괄 swap
- DOMAIN_COLORS의 var(--domain-*) 유지 (plan B2 비고)
- blue-400/blue-900/30 (news icon, data_origin work) 그대로
(lint:tokens 미검출 + plan 명시 없음)
DocumentTable:
- 헤더 + 행 + selected 상태 + 컬럼 텍스트 일괄 swap
- border-l-[var(--accent)] → border-l-accent
- border-default/30 opacity suffix (행 구분선) v4 시각 검증 필요
검증:
- npm run lint:tokens : 407 → 360 (-47, B2 파일 0 hit)
- npm run build : ✅
- npx svelte-check : ✅ 0 errors
- ⚠ 3-risk grep : hover/border-border/var() 잔여 0건
플랜: ~/.claude/plans/compressed-churning-dragon.md §A.4 Batch 2
2026-04-07 12:04:37 +09:00
Hyungi Ahn
451c2181a0
refactor(tokens): A-8 Batch 1 — TagPill / UploadDropzone
...
색상 시스템을 의미 토큰으로 swap. Phase A 디자인 시스템 정착의 첫
mechanical refactor batch (8 파일 중 2 파일).
TagPill: 4가지 prefix별 색상을 의미 토큰화
- @상태/ amber → warning
- #주제/ blue → accent
- $유형/ green → success
- !우선순위/ red → error
- fallback bg-[var(--border)] → bg-default,
text-[var(--text-dim)] → text-dim
UploadDropzone: 드래그 오버레이 + 업로드 진행 영역
- bg-[var(--accent)]/10 → bg-accent/10
- bg-[var(--surface)] → bg-surface
- border-[var(--border)] → border-default
- text-[var(--text-dim)] → text-dim
- 상태별 텍스트: text-success / text-error / text-accent / text-dim
검증:
- npm run lint:tokens : 421 → 407 (-14, B1 파일 0 hit)
- npm run build : ✅
- npx svelte-check : ✅ 0 errors
- ⚠ 3-risk grep : hover/border-border/var() 잔여 0건
플랜: ~/.claude/plans/compressed-churning-dragon.md §A.4 Batch 1
참고: 본 plan은 161ff18(search Phase 0.5 commit)에 styleguide 2개 파일이
의도와 다르게 묶여 main에 들어왔음. 기능 영향 0 — Option A 결정으로
commit history 미수정.
2026-04-07 11:44:29 +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
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
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
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
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
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
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
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
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
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
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
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
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
aebfa14984
fix: don't intercept 401 on login/refresh endpoints for token refresh
...
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 >
2026-04-03 06:58:36 +09:00
Hyungi Ahn
cfa95ff031
feat: implement Phase 4 SvelteKit frontend + backend enhancements
...
Backend:
- Add dashboard API (today stats, inbox count, law alerts, pipeline status)
- Add /api/documents/tree endpoint for sidebar domain/sub_group tree
- Migrate auth to HttpOnly cookie for refresh token (XSS defense)
- Add /api/auth/logout endpoint (cookie cleanup)
- Register dashboard router in main.py
Frontend (SvelteKit + Tailwind CSS v4):
- api.ts: fetch wrapper with refresh queue pattern, 401 single retry,
forced logout on refresh failure
- Auth store: login/logout/refresh with memory-based access token
- UI store: toast system, sidebar state
- Login page with TOTP support
- Dashboard with 4 stat widgets + recent documents
- Document list with hybrid search (debounce, URL query state, mode select)
- Document detail with format-aware viewer (markdown/PDF/HWP/Synology/fallback)
- Metadata panel (AI summary, tags, processing history)
- Inbox triage UI (batch select, confirm dialog, domain override)
- Settings page (password change, TOTP status)
Infrastructure:
- Enable frontend service in docker-compose
- Caddy path routing (/api/* → fastapi, / → frontend) + gzip
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-03 06:46:19 +09:00