diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index be42bc1..2043fff 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -98,7 +98,7 @@ - +
+ -
- - - - -
- -
-
- - - - - - - {total}건 - {#if unreadCount > 0} - ● {unreadCount} 안읽음 - {/if} -
- -
- - - {#if filterOpen} -
- - {#each Object.entries(sourceTree) as [paper, categories]} - - {#each categories as cat} - - {/each} - {/each} -
- {/if} - - -
- {#if loading} -
- {#each Array(5) as _} -
- {/each} -
- {:else if articles.length === 0} -

뉴스가 없습니다

+
+
+

야간 뉴스 브리핑

+

+ {#if briefing} + {briefing.briefing_date} 새벽 수집 · 총 {briefing.total_articles}건 / {briefing.total_countries}개국 / {briefing.total_topics}개 토픽 {:else} - {#each articles as article} - -

selectArticle(article)} role="button" tabindex="0" - onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); selectArticle(article); } }} - class="w-full text-left px-3 py-2 lg:px-4 lg:py-3 border-b border-[var(--border)]/30 hover:bg-[var(--surface)] active:bg-[var(--surface)] transition-colors cursor-pointer - {selectedArticle?.id === article.id ? 'bg-[var(--accent)]/5 border-l-2 border-l-[var(--accent)]' : ''}"> -
- {article.is_read ? '○' : '●'} -
-

{article.title}

-

{(article.ai_summary?.replace(/[*#_`~]/g, '') || article.extracted_text?.split('\n').filter(l => l.trim() && l !== article.title)[0] || '').slice(0, 120)}

-
- {article.ai_sub_group || ''} - {#if article.ai_tags?.length}{article.ai_tags[0]?.split('/').pop()}{/if} - {timeAgo(article.created_at)} -
-
- -
-
- {/each} + 매일 KST 자정~05:00 누적 뉴스를 주제별로 다국 비교 분석합니다. {/if} -
+

+ - - {#if total > 30 && !selectedArticle} -
- {#each Array(Math.min(Math.ceil(total / 30), 10)) as _, i} - - {/each} -
- {/if} - - - {#if selectedArticle} -
-
-
- {selectedArticle.ai_sub_group}·{timeAgo(selectedArticle.created_at)} -
-
- - {#if selectedArticle.edit_url}원문 →{/if} - -
+ {#if loading} + +

불러오는 중…

+
+ {:else if errorMsg} + +

{errorMsg}

+
+ {:else if briefing} + {#if briefing.status === 'empty'} + +

+ 오늘 새벽({briefing.briefing_date}) 다국 비교 가능한 토픽이 없습니다. +

+

+ (수집 뉴스 0건 또는 2개국 이상 다룬 주제 없음) +

+
+ {:else} + {#if briefing.status === 'failed'} +
+ ⚠ LLM 분석 실패율이 높습니다 ({briefing.llm_failures}/{briefing.llm_calls}, {fallbackPct}%). 일부 토픽이 원문 묶음으로 표시됩니다.
-
-

{selectedArticle.title}

- {#if selectedArticle.ai_summary} -
-

AI 요약

-
{@html renderMd(selectedArticle.ai_summary)}
+ {:else if briefing.status === 'partial'} +
+ 일부 토픽 LLM 실패 ({briefing.llm_failures}/{briefing.llm_calls}). 다른 토픽은 정상 분석되었습니다. +
+ {/if} + + {#each briefing.topics as topic (topic.topic_rank)} + +
+
+ #{topic.topic_rank} +
+

+ {topic.topic_label} + {#if topic.llm_fallback_used} + (원문 묶음) + {/if} +

+

{topic.headline}

+

+ {topic.country_count}개국 · {topic.article_count}건 +

+
- {/if} -
{@html renderMd(selectedArticle.extracted_text || '')}
-
-

본문 입력

- {#if contentEditing} - -
- {:else}{/if} -
-
-

메모

- {#if noteEditing} - -
- {:else} - - {#if selectedArticle.user_note}
{selectedArticle.user_note}
{/if} + + {#if topic.country_perspectives.length > 0} +
+ {#each topic.country_perspectives as cp} +
+ {countryLabel(cp.country)} + · + {cp.summary} + {#if cp.article_ids.length > 0} + + {#each cp.article_ids as id, i} + {#if i > 0}·{/if}#{id} + {/each} + + {/if} +
+ {/each} +
+ {/if} + + {#if topic.divergences.length > 0} +
+ 차이 + {topic.divergences.join(' · ')} +
+ {/if} + + {#if topic.convergences.length > 0} +
+ 공통 + {topic.convergences.join(' · ')} +
+ {/if} + + {#if topic.key_quotes.length > 0} +
    + {#each topic.key_quotes as q} +
  • + {countryLabel(q.country)} · {q.source} + "{q.quote}" +
  • + {/each} +
+ {/if} + + {#if topic.historical_context} +

+ ↩ 지난 흐름 · {topic.historical_context} +

{/if}
-
-
+ + {/each} {/if} -
+ {/if}