FR-191 · 定版交付
已上線:正式更新站 80ccaecb(2026-11-10);主系統、前端、手冊已合回 feature/FR-172,客戶升到含本案的主系統版本即可使用
客戶還沒裝 Agent 時,管理員在主系統點「取得安裝包」,拿到原廠 Cloudflare R2 上 Agent 最新相容版安裝包與 .sha256 的預簽下載網址。網址有效時間由原廠在更新站後台設定,客戶畫面沒有這個欄位。
管理員在更新中心 Agent 區按「取得安裝包」,或建完註冊 token 時看對話框下方,就拿到兩條 R2 預簽網址(安裝包、.sha256),直接下載或複製給裝機的人。主系統只向原廠更新站換網址、原樣轉交,不存包、不供檔;網址時限由原廠在更新站後台設定。
| Repo | 內容 | 位置 |
|---|---|---|
| update-center | /v1/download-url 認 artifact=sha256;預簽網址帶下載檔名;有效時間讀 D1 site_settings(預設 900 秒,範圍 300~86400);後台「設定」分頁與 GET/PUT /admin/settings。正式站已部署:版本 80ccaecb(2026-11-10),正式 D1 已套 0007 |
src/settings.ts、src/routes/client.ts、src/routes/admin.ts、migrations/0007_site_settings.sql |
| 主系統 BE | POST /api/1.0/system/product-update/agents/bundle-links:節流 → 查最新相容版(唯讀,不寫 agent_last_check)→ 換兩條網址 → 稽核 6251 |
api/product_update/routes/agent_bundle_link_route.py(32 行)、app/product_update/service/agent_bundle_link_service.py(101 行)、update_site_client.py 的 download_url_info、agent_release_service.py 的 query_latest 與常數 NO_AGENT_BASE |
| 主系統 FE | 共用對話框顯示版號、大小、SHA-256、兩列網址與到期時間;兩個入口;沒有時限欄位 | AgentBundleLinks.vue、AgentBundleButton.vue、useAgentBundleLinks.js |
| 手冊 | 快速版第 3 步與 03 章 3.2 的取包標準句;04 章 token 對話框提示;07/10/11/README 的重新取包句 | docs/user-manual/agent/、FR-189 site/index.html |
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','sequenceNumberColor':'#FFFFFF'}}}%%
sequenceDiagram
autonumber
actor A as 管理員(瀏覽器)
participant B as 主系統 API
participant U as 更新站(Cloudflare Worker)
participant R as Cloudflare R2
actor C as 裝機人員
A->>B: POST agents/bundle-links
B->>B: 每人每分鐘 10 次節流
B->>U: /v1/check product=agent current=1.0.0(主機授權身分)
U-->>B: latest 與簽章清單
B->>B: 驗章、比 min_host_version
B->>U: /v1/download-url 整包+artifact=sha256
U-->>B: 兩條 R2 預簽網址、expires_in
B-->>A: 版號、大小、SHA-256、兩條網址;寫稽核
A->>C: 下載,或複製網址交給裝機人員
C->>R: GET 預簽網址(不需帳號)
R-->>C: 檔案
C->>C: sha256sum -c
第 3 步送 current=1.0.0(常數 NO_AGENT_BASE):更新站 Agent 版本的可直升起始版一律是 <主版>.0.0,送 0.0.0 會把所有版本濾掉、回「沒有新版」。第 6 步任一失敗,或兩條網址只換到一條,整個回失敗,不給半組網址。
1.0.0;更新中心 Agent 區「檢查」與「預先下載」在一台 Agent 都沒有時也送同一個值。最新版要求較新的主系統時回 412(PRODUCT_UPDATE_412014),不給網址。sha256、size 取自驗過章的簽章清單,不取 /v1/download-url 回的未簽欄位。DOWNLOAD_HOSTS 白名單(R2 端點),否則拒絕轉交(503001)。system.product-update.read;每人每分鐘 10 次,超過回 429(PRODUCT_UPDATE_429002)。AGENT_BUNDLE_LINK_ISSUED,欄位 actor、version、expires_in、source=r2。expires_in;不做 HEAD 探測(R2 預簽網址簽的是 GET)。正式更新站實打(2026-11-10,部署 80ccaecb 後,用 190 測試機主機授權身分;190 本身未改動):
| 項目 | 結果 |
|---|---|
| 健康檢查 | {"ok":true} |
| 主系統「檢查更新」(現有功能) | 正常 |
| 主系統升級包下載網址(現有功能) | 正常;expires_in=900;真 R2 下載與續傳(206)成功,檔名正確 |
Agent 線 current=1.0.0 |
latest=1.7.4(current=0.0.0 回 none,見第 2 節) |
Agent 1.7.4 安裝包與 .sha256 網址 |
兩條都拿得到,檔名正確;.sha256 實際下載內容與更新站清單 sha256 一致 |
Agent 線帶 artifact=ops |
400,正確擋下 |
主系統程式(修正後常數+真 update_site_client)打正式站 |
latest=1.7.4,兩條網址正常,sha256 一致 |
自動測試:
| 範圍 | 結果 |
|---|---|
| update-center | typecheck 綠;npm test Worker 187、CLI 101 全綠(含 sha256、content-disposition 簽進章內、設定範圍、CI/GitLab token 403) |
| 主系統 BE | FR-191、更新中心、FR-167/172 相關測試與守衛 test_module_boundaries.py 共 495 條綠 |
| 主系統 FE | vitest 相關 12 檔 145 條綠;全套 86 檔 663 條綠;vite build 過;改動檔無 border-left |
| 手冊 | grep「主系統下載/預先下載/30 分鐘內有效」只剩 07 章 7.8 一句(講 Agent 升級,與取包無關) |
畫面:本機接模擬更新站(用綁本機的 DEV 身分票)時,後端 API 與無頭瀏覽器都打通;對話框顯示版本 1.7.4、1.7 GB、SHA-256、兩列 R2 網址、「連結 15 分鐘內有效」,沒有時限欄位。模擬環境的 R2 金鑰是假的,網址本身下載不到;真實下載已由上方正式站實打涵蓋。
| 事項 | 說明 | 誰接 |
|---|---|---|
| 手冊截圖 | 快速版第 3 步與 03 章 3.2 的畫面截圖。現有兩張是模擬環境畫面,不採用 | 決策者 2026-11-10 裁先不做;有真網址畫面時重截 |
| 客戶主系統升級 | 客戶要升到含 FR-191 v2 與 CM-3819 的主系統版本,才會有新的「取得安裝包」行為。舊版主系統打新版更新站不受影響 | 隨下一次主系統發版 |
| 你想知道 | 看哪份 |
|---|---|
| 要做成什麼樣、為什麼、排除了什麼 | design-v2.1.md(現行);design-v2.0.md(被 v2.1 取代,只差查詢基準版) |
| v1.0 當初怎麼設計(稽核用,已推翻) | design.md |
| 進度、決策者表態、Notion 卡號 | README.md |
| 每一棒做了什麼、v1.0 為什麼被推翻 | handoff/FR-191-LOG.md |
| 現在停在哪 | handoff/FR-191-STATE.md |