From 4d9beb37efcff47211385308856f1b821ba89a83 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Tue, 12 May 2026 14:30:42 +0900 Subject: [PATCH 1/2] feat(briefing): swap /news to morning briefing card UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /news/+page.svelte 전면 재작성: article list 폐기, /api/briefing/latest fetch → topic 카드 list - 각 카드: topic_label + headline + country_perspectives (flag + 한국어 + summary + article #id 링크) + divergences/convergences/key_quotes + historical_context - status 4-state UI 분기 (empty/partial/failed/success) - 디자인 시스템 토큰 only, Card 공용 컴포넌트 재사용, Svelte 5 runes + TS - layout 라벨 뉴스 → 브리핑 (라우트 /news 유지) - 백업: git history --- frontend/src/routes/+layout.svelte | 2 +- frontend/src/routes/news/+page.svelte | 527 ++++++++++---------------- 2 files changed, 194 insertions(+), 335 deletions(-) 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}
-- 2.52.0 From 1696926b8c89f749a3108bca3608deae4d8043bd Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Tue, 12 May 2026 14:35:16 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor(briefing):=20nav=20label=20to=20?= =?UTF-8?q?=EC=95=84=EC=B9=A8=20=EB=B8=8C=EB=A6=AC=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/routes/+layout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 2043fff..169b508 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -98,7 +98,7 @@ - +