# 刷新流程

本頁說明一次「檢查更新」從觸發、比對新文章、背景萃取全文到產生概要的完整順序。

## 觸發來源

| 來源 | 呼叫 | 狀態列 |
|------|------|--------|
| 啟動 | `Run()` → `getList(false)` | `Loading...` |
| `Ctrl+R` | `getList(true)` | `Checking...` |
| 自動檢查 | 每 5 分鐘 ticker → `getList(true)` | `Refreshing...` → `Checking...` |

自動檢查在 `New()` 建立 ticker 後即啟動，沒有開關可關閉；結束程式時 `stopRefresh()` 停止 ticker。

## 檢查步驟

`getList()` 在背景 goroutine 依序執行：

| 步驟 | 動作 |
|------|------|
| 1 | 若列表為空，先以 `database.Get(72)` 取出 72 小時內的文章顯示 |
| 2 | `Collector.GetNews()` 抓取所有啟用中的訂閱源，回傳 72 小時內的文章 |
| 3 | 逐篇以 `GetFromURL()` 查資料庫：查不到計為新文章；查得到則改用資料庫中的發布時間 |
| 4 | 依發布時間由新到舊排序，更新 News List |
| 5 | 有新文章時另開 goroutine 執行 `loadContent()` |

第 3 步沿用資料庫時間，是因為 RSS 項目沒有可解析的 `pubDate` 時會以當下時間代替，每次檢查都會漂移。

## 背景全文萃取

`loadContent()` 對本次抓到的每篇文章：

| 條件 | 動作 |
|------|------|
| 資料庫已有全文 | 略過 |
| 萃取成功 | 寫入文章與全文，更新進度，等待 500ms 後處理下一篇 |
| 萃取失敗 | 寫入文章（全文為空）並寫 log，立即處理下一篇 |

全文為空的文章下次檢查時會再嘗試萃取。全部處理完後進入 [LLM 新聞概要](/zh/llm-digest)。

## 預覽時的即時萃取

在 News List 移動時，`showPreview()` 另外處理單篇：

| 條件 | 顯示 |
|------|------|
| 資料庫已有全文 | 直接顯示全文 |
| 資料庫沒有全文且即時萃取成功 | 顯示全文，並在背景寫入資料庫 |
| 即時萃取失敗 | 顯示 RSS 描述 |
