From c1555fd6abd53e789d2eff9cc558edae5e11a288 Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 13 Jun 2026 15:41:59 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat(docpage):=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=20=EB=AA=A9=EB=A1=9D=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9D=B8=EB=9D=BC=EC=9D=B8=20=EB=AF=B8=EB=A6=AC?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0=20=EB=8C=80=EC=8B=A0=20D3=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 결정 "개선된 페이지가 앞으로 표시되야지" — /documents 브라우저에서 문서를 열면 인라인 DocumentViewer(구) 대신 개선된 /documents/[id](D3 절 구조 탐색기)로 이동. /documents = 브라우즈/검색/필터/일괄 목록(풀폭 중앙) 역할로 정리: - selectDoc → goto(/documents/[id]) (행 클릭·키보드 enter 공통) - 인라인 리더(DocumentViewer)·인스펙터 패널 제거, 목록 max-w-5xl 중앙 - AI 답변 카드(질문형 검색)는 목록 상단 고정으로 이동(보존) - 검색·필터칩·일괄작업·업로드·페이지네이션 전부 유지 Co-Authored-By: Claude Fable 5 --- frontend/src/routes/documents/+page.svelte | 76 +++++++--------------- 1 file changed, 22 insertions(+), 54 deletions(-) diff --git a/frontend/src/routes/documents/+page.svelte b/frontend/src/routes/documents/+page.svelte index 1f2d96d..606df39 100644 --- a/frontend/src/routes/documents/+page.svelte +++ b/frontend/src/routes/documents/+page.svelte @@ -8,8 +8,7 @@ import { goto } from '$app/navigation'; import { api } from '$lib/api'; import { addToast } from '$lib/stores/toast'; - import { Info, X, Plus, Trash2, Tag, FolderTree, Sparkles, ChevronLeft, ArrowUpDown } from 'lucide-svelte'; - import DocumentViewer from '$lib/components/DocumentViewer.svelte'; + import { X, Plus, Trash2, Tag, FolderTree, Sparkles, ArrowUpDown } from 'lucide-svelte'; import MarkdownStatusBadge from '$lib/components/MarkdownStatusBadge.svelte'; import { isMdStatusVisible } from '$lib/utils/mdStatus'; import UploadDropzone from '$lib/components/UploadDropzone.svelte'; @@ -233,15 +232,12 @@ goto(`/documents${qs ? '?' + qs : ''}`, { noScroll: true }); } - async function selectDoc(doc) { - if (selectedDoc?.id === doc.id) { selectedDoc = null; return; } - selectedDoc = doc; // 즉시 표시(리더 + 기본 인스펙터) - // 인스펙터 풀 메타 하이드레이션 — 검색 결과(SearchResult)는 메타가 빈약(태그/크기/하위/md상태/읽음 없음). - // 풀 문서를 조회해 채운다(기존 GET /documents/{id}, 백엔드 무변). 리스트 모드도 md상태 등 보강. - try { - const full = await api(`/documents/${doc.id}`); - if (selectedDoc?.id === doc.id) selectedDoc = { ...doc, ...full }; - } catch { /* 실패 시 기본 정보 유지 */ } + // 문서 열기 = 개선된 상세 페이지(D3 절 구조 탐색기)로 이동. + // 사용자 결정: "개선된 페이지가 앞으로 표시되야지" — 인라인 미리보기 폐기. + // /documents = 브라우즈/검색/필터/일괄 목록, 문서 열기 = /documents/[id] D3 리더. + function selectDoc(doc) { + if (!doc) return; + goto(`/documents/${doc.id}`); } // bulk 선택 @@ -386,8 +382,8 @@
- -
+ +
@@ -487,6 +483,19 @@ {/if}
+ + {#if showAskCard} +
+ goto(`/documents/${docId}`)} + onDismiss={() => { askDismissed = true; }} + /> +
+ {/if} + {#if selectionCount > 0}
@@ -587,47 +596,6 @@
- -
- {#if selectedDoc} - -
- -
- -
-
- -
- {:else if showAskCard} -
- goto(`/documents/${docId}`)} - onDismiss={() => { askDismissed = true; }} - /> -
- {:else} - - {/if} -
- - - {#if selectedDoc && inspectorOpen} - - {/if}
From 74e29e510ee2ea7af825695ccc7edcec5b097d4a Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 13 Jun 2026 15:53:34 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat(docpage):=20D3=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A5=BC=20=ED=99=95=EC=A0=95=20?= =?UTF-8?q?=EC=8B=9C=EC=95=88=20=EA=B7=B8=EB=8C=80=EB=A1=9C=20=EC=9E=AC?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 컴포넌트 재사용/배치변경(불충실)을 폐기하고 deepened 시안을 충실히 구현: - 좌 절 트리: 유형 색칩(정의/절차/요건)·신뢰도 dot·저신뢰 경고·레벨 들여쓰기·클릭=절 선택 - 중 절 집중 뷰: breadcrumb + 제목 + 유형 배지 + 신뢰도 막대 + 절 요약 인용 + 절 본문 (md_content 를 char_start 로 슬라이스) + 이전/다음 절 - 우 슬림 레일: TL;DR · 핵심점 · 심층(DEEP) · 불일치 · 분류 · 태그 (읽기) + 정보/관리 접이(편집 보존) - 절 없음 fallback: 전체 본문/뷰어 + 레일 (D3 빈 절 graceful) - 모바일: 본문(절 집중) 메인 + 절구조/인사이트 접이 svelte-check 0. 시안=comparisons/2026-06-13-ds-docpage-d3-deepened.html. Co-Authored-By: Claude Fable 5 --- .../src/routes/documents/[id]/+page.svelte | 781 +++++++++--------- 1 file changed, 369 insertions(+), 412 deletions(-) diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index 1016377..e6f8746 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -1,19 +1,17 @@ -
+ +{#snippet treeNav()} +
+
+ 절 구조 + {sections.length}절 +
+ +
+ 정의 + 절차 + 요건 +
+
    + {#each sections as s (s.chunk_id)} + {@const tm = typeMeta(s.section_type)} + {@const active = s.chunk_id === selectedSection?.chunk_id} + {@const low = isLowConf(s.confidence)} +
  • + +
  • + {/each} +
+ {#if quality} +
+ 추출 품질 + {#if quality.headings != null}· 제목 {quality.headings}{/if} + {#if quality.tables != null}· 표 {quality.tables}{/if} + {#if quality.images != null}· 이미지 {quality.images}{/if} +
+ {/if} +
+{/snippet} + + +{#snippet rail()} +
+ + {#if doc.ai_tldr || doc.ai_summary} +
+
TL;DR
+

{doc.ai_tldr || doc.ai_summary}

+
+ {/if} + + {#if doc.ai_bullets && doc.ai_bullets.length} +
+
핵심점
+
    + {#each doc.ai_bullets as b} +
  • ·{b}
  • + {/each} +
+
+ {/if} + + {#if doc.ai_detail_summary} +
+
+ 심층 + {#if doc.ai_analysis_tier === 'deep'}DEEP{/if} +
+

{doc.ai_detail_summary}

+
+ {/if} + + {#if doc.ai_inconsistencies && doc.ai_inconsistencies.length} +
+
불일치 {doc.ai_inconsistencies.length}
+
    + {#each doc.ai_inconsistencies as inc} +
  • · {typeof inc === 'string' ? inc : inc.desc || inc.kind}
  • + {/each} +
+
+ {/if} + + {#if doc.ai_domain} +
+
분류
+
+ {domainLabel(doc.ai_domain)}{#if doc.ai_sub_group} · {doc.ai_sub_group}{/if} +
+ {#if doc.ai_confidence != null}신뢰도 {doc.ai_confidence.toFixed(2)}{/if} + {#if doc.ai_analysis_tier}{doc.ai_analysis_tier}{/if} +
+
+
+ {/if} + + {#if doc.ai_tags && doc.ai_tags.length} +
+
태그
+
+ {#each doc.ai_tags as t}{t}{/each} +
+
+ {/if} + +
+
관련 문서
+

벡터 유사도 기반 — 준비 중

+
+ +
+ + 문서 정보 + +
+ {#if doc.category === 'library'}{/if} + + +
+
+ +
+ + 관리 · 분류 편집 + +
+ + + + + +
+
+
+
+{/snippet} + +
문서 @@ -244,320 +330,191 @@
{#if loading} -
- -
+ {:else if error === 'not_found'} - + {:else if error === 'network'} - + {:else if doc} -
- {#if hasSections} - - - {/if} - - -
- {#if hasSections} - -
- 절 목차 ({sections.length}) - -
- {/if} - -
- {#if doc.edit_url} - - {/if} - - {#if doc.preview_status === 'ready'} - - {/if} - + +
+
+
+
+ {#if doc.ai_domain} + + {domainLabel(doc.ai_domain)} + + {/if} + {#if doc.ai_sub_group}{doc.ai_sub_group}{/if} + {doc.file_format}{#if canShowMarkdown}→MD{/if} + {#if doc.ai_analysis_tier === 'deep'}tier DEEP{/if} + {#if doc.ai_confidence != null}신뢰도 {doc.ai_confidence.toFixed(2)}{/if} +
+

{doc.title}

+
+
+ {#if doc.edit_url}{/if} + + {#if doc.category === 'library'} - + + {/if} +
+
+
+ + {#if useSectionView} + + +
+ 절 구조 ({sections.length}절) +
{@render treeNav()}
+
+ +
+ + + + +
+ {#if selectedSection} + {@const tm = typeMeta(selectedSection.section_type)} + +
+ {doc.title} + {#each pathSegments(selectedSection.heading_path) as seg}/{seg}{/each} +
+ +
+

{secTitle(selectedSection)}

+ {#if tm.label}{tm.label}{/if} +
+ + {#if selectedSection.confidence != null} +
+ 신뢰도 + + + + {selectedSection.confidence.toFixed(2)} +
+ {/if} + + {#if isLowConf(selectedSection.confidence)} +
+ ! + 저신뢰 절 — 표·수식 추출이 불완전할 수 있습니다. 정확한 내용은 원본을 확인하세요. +
+ {/if} + + {#if selectedSection.summary} +
+
절 요약
+

{selectedSection.summary}

+
+ {/if} + + {#if selectedBodyHtml} +
{@html selectedBodyHtml}
+ {:else} +

이 절의 본문은 추출되지 않았습니다. 헤더의 '원본'에서 확인하세요.

+ {/if} + +
+ + {selIdx + 1} / {sections.length} + +
{/if}
- - + + +
+ {:else} + +
+
+ {#if !hasSections && canShowMarkdown} +

이 문서는 절 분석이 없습니다 (짧은 문서이거나 분석 전) — 전체 본문으로 표시합니다.

+ {/if} {#if viewerType === 'markdown' || viewerType === 'hwp-markdown'} - + {:else if viewerType === 'pdf'}
- + {#if canShowMarkdown} - - + + {/if}
{#if pdfViewMode === 'markdown' && canShowMarkdown} - + {:else} - + {/if} {:else if viewerType === 'image'} - {doc.title} + {doc.title} {:else if viewerType === 'synology'} - - + + {:else if viewerType === 'article'} -
-

{doc.title}

-
- 출처: {doc.source_channel} - · - - {new Date(doc.created_at).toLocaleDateString('ko-KR', { - year: 'numeric', - month: 'short', - day: 'numeric', - })} - -
- {#if doc.md_content || doc.extracted_text} - - - {/if} - {#if doc.edit_url} - - {/if} -
+ {#if doc.md_content || doc.extracted_text} + + {/if} + {#if doc.edit_url}
{/if} {:else} - + {/if} - - - - {#if noteOpen && doc.category === 'library' && noteLoaded} - -
- saveNote(strokes)} - /> -
-
- {/if} +
+
+ {/if} - - -
- - + {#if doc.category === 'library'}
- - - + - - +
-
{/if} {/if} From 0a82a5b1bc3e1847f192b2ac7a611dec79355dae Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 13 Jun 2026 16:03:59 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat(docpage):=20=EB=AA=A8=EB=B0=94?= =?UTF-8?q?=EC=9D=BC=EC=9D=84=20=EC=8B=9C=EC=95=88=EB=8C=80=EB=A1=9C=20?= =?UTF-8?q?=E2=80=94=20=EB=B3=B8=EB=AC=B8=20=EC=97=B0=EC=86=8D=20=EC=A0=88?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20+=20=EC=A0=91=EC=9D=B4=20+=20=ED=83=AD?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 모바일(데스크탑 focus 단일절)이 시안 모바일과 불일치(사용자 "모바일은 변한게 없잖아") → 시안 모바일 충실 구현: - 모바일( --- .../src/routes/documents/[id]/+page.svelte | 193 ++++++++++-------- 1 file changed, 105 insertions(+), 88 deletions(-) diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index e6f8746..c367ea8 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -178,8 +178,8 @@ function handleDocDelete() { addToast('success', '문서가 삭제되어 목록으로 이동합니다.'); goto('/documents'); } - -{#snippet treeNav()} + +{#snippet treeNav(jumpMode = false)}
절 구조 @@ -197,19 +197,28 @@ {@const active = s.chunk_id === selectedSection?.chunk_id} {@const low = isLowConf(s.confidence)}
  • - + {#if jumpMode} + + + {secTitle(s)} + {#if low}!{:else}{/if} + + {:else} + + {/if}
  • {/each} @@ -321,6 +330,63 @@
    {/snippet} + +{#snippet focusView()} + {#if selectedSection} + {@const tm = typeMeta(selectedSection.section_type)} +
    + {doc.title} + {#each pathSegments(selectedSection.heading_path) as seg}/{seg}{/each} +
    +
    +

    {secTitle(selectedSection)}

    + {#if tm.label}{tm.label}{/if} +
    + {#if selectedSection.confidence != null} +
    + 신뢰도 + + {selectedSection.confidence.toFixed(2)} +
    + {/if} + {#if isLowConf(selectedSection.confidence)} +
    !저신뢰 절 — 표·수식 추출이 불완전할 수 있습니다. 정확한 내용은 원본을 확인하세요.
    + {/if} + {#if selectedSection.summary} +
    절 요약

    {selectedSection.summary}

    + {/if} + {#if selectedBodyHtml} +
    {@html selectedBodyHtml}
    + {:else} +

    이 절의 본문은 추출되지 않았습니다. 헤더의 '원본'에서 확인하세요.

    + {/if} +
    + + {selIdx + 1} / {sections.length} + +
    + {/if} +{/snippet} + + +{#snippet sectionCard(s)} + {@const tm = typeMeta(s.section_type)} + {@const body = sectionBodyHtml(s)} +
    +
    +

    {secTitle(s)}

    + {#if tm.label}{tm.label}{/if} +
    + {#if isLowConf(s.confidence)} +
    !저신뢰 — 표·수식 추출 불완전, 원본 확인 권장
    + {/if} + {#if s.summary} +
    절 요약

    {s.summary}

    + {/if} + {#if body}
    {@html body}
    {/if} +
    +{/snippet} +
    @@ -369,83 +435,34 @@
    {#if useSectionView} - - -
    - 절 구조 ({sections.length}절) -
    {@render treeNav()}
    -
    - -
    - -
    - -
    -
    - - 절 구조 ({sections.length}절) · 탭하면 본문으로 이동 - -
    {@render treeNav(true)}
    -
    -
    - - 인사이트 (요약 · 심층 · 분류) - -
    {@render rail()}
    -
    - {#each sections as s (s.chunk_id)} - {@render sectionCard(s)} - {/each} + +
    + +
    + + +
    + + + {#if mTree} +
    +
    + 정의 + 절차 + 요건 + 탭 → 본문 이동 +
    + {#each sections as s (s.chunk_id)} + {@const tm = typeMeta(s.section_type)} + + {#if secDepth(s) === 0}{/if} + {secTitle(s)} + {#if isLowConf(s.confidence)} + 저신뢰! + {:else} + + {/if} + + {/each} +
    + {/if} + + + {#if mIns} +
    + {#if doc.ai_tldr || doc.ai_summary} +
    TL;DR
    +

    {doc.ai_tldr || doc.ai_summary}

    + {/if} + {#if doc.ai_bullets && doc.ai_bullets.length} +
    핵심점
    +
      {#each doc.ai_bullets as b}
    • ·{b}
    • {/each}
    + {/if} + {#if doc.ai_detail_summary} +
    심층{#if doc.ai_analysis_tier === 'deep'}DEEP{/if}
    +

    {doc.ai_detail_summary}

    + {/if} + {#if doc.ai_inconsistencies && doc.ai_inconsistencies.length} +
    불일치 {doc.ai_inconsistencies.length}
    +
      {#each doc.ai_inconsistencies as inc}
    • · {typeof inc === 'string' ? inc : inc.desc || inc.kind}
    • {/each}
    + {/if} + {#if doc.ai_domain} +
    분류
    +

    {domainLabel(doc.ai_domain)}{#if doc.ai_sub_group} · {doc.ai_sub_group}{/if}{#if doc.ai_confidence != null} · {doc.ai_confidence.toFixed(2)}{/if}

    + {/if} + {#if doc.ai_tags && doc.ai_tags.length} +
    {#each doc.ai_tags as t}{t}{/each}
    + {/if} +
    + {/if} + + +
    + {#each sections as s (s.chunk_id)}{@render sectionCard(s)}{/each} +
    {:else} From 9b9790f05d438dfbc9492311a5ab2adf9a161791 Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 13 Jun 2026 16:29:04 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix(docpage):=20D3=20=EC=8B=9C=EC=95=88=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EA=B7=B8=EB=8C=80=EB=A1=9C=20?= =?UTF-8?q?=ED=8F=AC=ED=8C=85=20+=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=EA=B8=B8=EC=9D=B4/=EC=A0=91=EA=B7=BC=EC=84=B1=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사용자 "시안대로 안했다" → 앱 토큰 재해석을 폐기하고 d3-deepened 시안의 inline 스타일을 그대로 포팅(데이터만 바인딩): 트리 좌측 색바(3×16)+연결선(ㄴ자)+활성+ 저신뢰 맥동배지, 절차색 #7a8b3f, 헤더 PDF아이콘+pill칩+분류/원본/링크/관리, 절 집중 뷰(요건 requirement 배지·신뢰도 바·절요약 인용박스), 슬림 레일 카드(시안 동일). 모바일: 절구조/인사이트 안보임+무한길이("쭉 아래까지") → pill sticky + 절 본문 카드마다 접기('본문 보기', 기본 요약만)로 컴팩트화. svelte-check 0. Co-Authored-By: Claude Fable 5 --- .../src/routes/documents/[id]/+page.svelte | 649 +++++++----------- 1 file changed, 250 insertions(+), 399 deletions(-) diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index 68bafef..201b9c9 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -1,7 +1,7 @@ - -{#snippet treeNav(jumpMode = false)} -
    -
    - 절 구조 - {sections.length}절 + +{#snippet treeNav(jumpMode)} +
    +
    +
    절 구조
    + {sections.length}절
    - -
    - 정의 - 절차 - 요건 +
    + 정의 + 절차 + 요건
    -
      - {#each sections as s (s.chunk_id)} - {@const tm = typeMeta(s.section_type)} - {@const active = s.chunk_id === selectedSection?.chunk_id} - {@const low = isLowConf(s.confidence)} -
    • - {#if jumpMode} - - - {secTitle(s)} - {#if low}!{:else}{/if} - - {:else} - + {#each sections as s (s.chunk_id)} + {@const tm = typeMeta(s.section_type)} + {@const active = !jumpMode && s.chunk_id === selectedSection?.chunk_id} + {@const child = secDepth(s) > 0} + {@const low = isMidLow(s.confidence)} + !jumpMode && (selectedSectionId = s.chunk_id)} + onkeydown={(e) => { if (!jumpMode && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); selectedSectionId = s.chunk_id; } }} + class="d3node {child ? 'd3child' : ''} {active ? 'd3active' : ''}" + style="display:block;border:1px solid {active ? '#4f8a6b' : low ? '#e7d49a' : 'transparent'};border-radius:9px;padding:{child ? '6px 8px' : '7px 8px'};margin-bottom:2px;{low ? 'background:#fbf6e6;' : ''}text-decoration:none;cursor:pointer;"> +
      + + {secTitle(s)} + {#if low} + ! + {:else if !child} + {/if} -
    • - {/each} -
    +
    + + {/each} {#if quality} -
    - 추출 품질 - {#if quality.headings != null}· 제목 {quality.headings}{/if} - {#if quality.tables != null}· 표 {quality.tables}{/if} - {#if quality.images != null}· 이미지 {quality.images}{/if} -
    - {/if} -
    -{/snippet} - - -{#snippet rail()} -
    - - {#if doc.ai_tldr || doc.ai_summary} -
    -
    TL;DR
    -

    {doc.ai_tldr || doc.ai_summary}

    -
    - {/if} - - {#if doc.ai_bullets && doc.ai_bullets.length} -
    -
    핵심점
    -
      - {#each doc.ai_bullets as b} -
    • ·{b}
    • - {/each} -
    -
    - {/if} - - {#if doc.ai_detail_summary} -
    -
    - 심층 - {#if doc.ai_analysis_tier === 'deep'}DEEP{/if} -
    -

    {doc.ai_detail_summary}

    -
    - {/if} - - {#if doc.ai_inconsistencies && doc.ai_inconsistencies.length} -
    -
    불일치 {doc.ai_inconsistencies.length}
    -
      - {#each doc.ai_inconsistencies as inc} -
    • · {typeof inc === 'string' ? inc : inc.desc || inc.kind}
    • - {/each} -
    -
    - {/if} - - {#if doc.ai_domain} -
    -
    분류
    -
    - {domainLabel(doc.ai_domain)}{#if doc.ai_sub_group} · {doc.ai_sub_group}{/if} -
    - {#if doc.ai_confidence != null}신뢰도 {doc.ai_confidence.toFixed(2)}{/if} - {#if doc.ai_analysis_tier}{doc.ai_analysis_tier}{/if} -
    +
    +
    추출 품질
    +
    + {#if quality.headings != null}headings {quality.headings}{/if} + {#if quality.tables != null}tables {quality.tables}{/if} + {#if quality.images != null}images {quality.images}{/if}
    {/if} - - {#if doc.ai_tags && doc.ai_tags.length} -
    -
    태그
    -
    - {#each doc.ai_tags as t}{t}{/each} -
    -
    - {/if} - -
    -
    관련 문서
    -

    벡터 유사도 기반 — 준비 중

    -
    - -
    - - 문서 정보 - -
    - {#if doc.category === 'library'}{/if} - - -
    -
    - -
    - - 관리 · 분류 편집 - -
    - - - - - -
    -
    -
    {/snippet} @@ -337,262 +200,250 @@ {#snippet focusView()} {#if selectedSection} {@const tm = typeMeta(selectedSection.section_type)} -
    - {doc.title} - {#each pathSegments(selectedSection.heading_path) as seg}/{seg}{/each} +
    + {doc.title} + {#each pathSegments(selectedSection.heading_path) as seg}/{seg}{/each}
    -
    -

    {secTitle(selectedSection)}

    - {#if tm.label}{tm.label}{/if} +
    +

    {secTitle(selectedSection)}

    + {#if tm.label}{tm.label} {tm.en}{/if}
    {#if selectedSection.confidence != null} -
    - 신뢰도 - - {selectedSection.confidence.toFixed(2)} +
    + 신뢰도 +
    + {selectedSection.confidence.toFixed(2)}
    {/if} {#if isLowConf(selectedSection.confidence)} -
    !저신뢰 절 — 표·수식 추출이 불완전할 수 있습니다. 정확한 내용은 원본을 확인하세요.
    +
    !저신뢰 절 — 표·수식 추출이 불완전할 수 있습니다. 정확한 내용은 원본을 확인하세요.
    {/if} {#if selectedSection.summary} -
    절 요약

    {selectedSection.summary}

    +
    +
    절 요약
    +
    {selectedSection.summary}
    +
    {/if} {#if selectedBodyHtml}
    {@html selectedBodyHtml}
    {:else} -

    이 절의 본문은 추출되지 않았습니다. 헤더의 '원본'에서 확인하세요.

    +

    이 절의 본문은 추출되지 않았습니다. 헤더의 '원본'에서 확인하세요.

    {/if} -
    - - {selIdx + 1} / {sections.length} - +
    + {#if selIdx > 0} + + {:else}{/if} + {#if selIdx < sections.length - 1} + {@const nx = sections[selIdx + 1]} + + {:else}{/if}
    {/if} {/snippet} - + +{#snippet rail()} +
    + {#if doc.ai_tldr || doc.ai_summary} +
    +
    TL;DR
    +
    {doc.ai_tldr || doc.ai_summary}
    +
    + {/if} + {#if doc.ai_bullets && doc.ai_bullets.length} +
    +
    핵심점
    +
      + {#each doc.ai_bullets as b}
    • ·{b}
    • {/each} +
    +
    + {/if} + {#if doc.ai_detail_summary} +
    +
    + 심층 + {#if doc.ai_analysis_tier === 'deep'}DEEP{/if} +
    +
    {doc.ai_detail_summary}
    +
    + {/if} + {#if doc.ai_inconsistencies && doc.ai_inconsistencies.length} +
    +
    불일치 {doc.ai_inconsistencies.length}
    +
      {#each doc.ai_inconsistencies as inc}
    • · {typeof inc === 'string' ? inc : inc.desc || inc.kind}
    • {/each}
    +
    + {/if} + {#if doc.ai_domain} +
    +
    분류
    +
    +
    도메인{domainLabel(doc.ai_domain)}
    + {#if doc.ai_sub_group}
    하위{doc.ai_sub_group}
    {/if} + {#if doc.ai_analysis_tier}
    tier{doc.ai_analysis_tier}
    {/if} + {#if doc.ai_confidence != null}
    신뢰도{doc.ai_confidence.toFixed(2)}
    {/if} +
    +
    + {/if} + {#if doc.ai_tags && doc.ai_tags.length} +
    +
    태그
    +
    {#each doc.ai_tags as t}{t}{/each}
    +
    + {/if} +
    +
    관련 문서
    +
    벡터 유사도 기반 — 준비 중
    +
    +
    +{/snippet} + + {#snippet sectionCard(s)} {@const tm = typeMeta(s.section_type)} {@const body = sectionBodyHtml(s)} -
    -
    -

    {secTitle(s)}

    - {#if tm.label}{tm.label}{/if} +
    +
    +

    {secTitle(s)}

    + {#if tm.label}{tm.label}{/if}
    {#if isLowConf(s.confidence)} -
    !저신뢰 — 표·수식 추출 불완전, 원본 확인 권장
    +
    !저신뢰 — 표·수식 추출 불완전, 원본 확인 권장
    {/if} {#if s.summary} -
    절 요약

    {s.summary}

    +
    절 요약
    {s.summary}
    {/if} - {#if body}
    {@html body}
    {/if} -
    + {#if body} +
    + 본문 보기 +
    {@html body}
    +
    + {/if} +
    {/snippet} -
    +
    +
    -
    - 문서 - / +
    + 문서/ {doc?.title || '로딩...'}
    {#if loading} {:else if error === 'not_found'} - - - + {:else if error === 'network'} - - - + {:else if doc} - -
    -
    -
    -
    - {#if doc.ai_domain} - - {domainLabel(doc.ai_domain)} - - {/if} - {#if doc.ai_sub_group}{doc.ai_sub_group}{/if} - {doc.file_format}{#if canShowMarkdown}→MD{/if} - {#if doc.ai_analysis_tier === 'deep'}tier DEEP{/if} - {#if doc.ai_confidence != null}신뢰도 {doc.ai_confidence.toFixed(2)}{/if} + +
    +
    +
    {doc.file_format}
    +
    +
    {doc.title}
    +
    + {#if doc.ai_domain}{domainLabel(doc.ai_domain)}{/if} + {#if doc.ai_sub_group}{doc.ai_sub_group}{/if} + {#if doc.ai_analysis_tier === 'deep'}tier DEEP{/if} + {#if doc.ai_confidence != null}신뢰도 {doc.ai_confidence.toFixed(2)}{/if} + {#if canShowMarkdown}PDF→MD success{/if}
    -

    {doc.title}

    -
    - {#if doc.edit_url}{/if} - - - {#if doc.category === 'library'} - - {/if} +
    + {#if doc.edit_url}{/if} + + + {#if doc.category === 'library'}{/if} +
    {#if useSectionView} - -