From 94e28203d04248bf727a5c6d27dd67a2bfe7592b Mon Sep 17 00:00:00 2001 From: chengma Date: Wed, 8 Jul 2026 14:42:44 +0800 Subject: [PATCH] =?UTF-8?q?docs(tasks):=20add=20T-559=20update-check=20con?= =?UTF-8?q?tract=20+=20force=5Fupdate=20(=E6=96=B9=E6=A1=88A)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T-553 已被占用(cmhub 超时调优),按防撞号约定改用 T-559。 Co-Authored-By: Claude Opus 4.8 --- docs/tasks/T-559.md | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/tasks/T-559.md diff --git a/docs/tasks/T-559.md b/docs/tasks/T-559.md new file mode 100644 index 0000000..1e301bb --- /dev/null +++ b/docs/tasks/T-559.md @@ -0,0 +1,48 @@ +--- +id: T-559 +title: 版本检查响应契约 + 强制升级约定(force_update)固化进仓库 +phase: 7 +deps: [T-544] +status: TODO +created: 2026-07-08 +--- + +## 问题 / 背景 + +启动时客户端请求 `https://cm.833729.com/api/v1/client/releases/latest?platform=windows` 检查版本(`app/update_check.py`)。实测本地 0.1.0、线上 0.1.1 却**不弹升级窗**。核实原因:服务端响应**没有 `force_update`、也没有 `min_supported_version`**,客户端 `is_forced_update()` 判为"非强制";而当前客户端**只对强制更新弹窗**(`_run_startup_update_gate` 仅处理 `forced` 分支),非强制既不阻断也不提示。 + +采用**方案 A:发新版要强制时,服务端返回 `force_update: true`**。客户端逻辑 T-544 已实现、**无需改码**——本任务把"客户端读哪些字段 + 强制规则 + 发版约定"固化成仓库文档,避免服务端格式漂移、并作为发强制版的操作手册。 + +## 方案 + +新增文档 `docs/update-check.md`(并在 `docs/README.md` 索引里加一行),内容: + +- **接口**:`GET {APP_UPDATE_CHECK_URL}`(当前 `https://cm.833729.com/api/v1/client/releases/latest?platform=windows`,硬编码于 `app/version.py`)。 +- **客户端读取的字段**(`update_check.parse_update_info`,顶层 payload 或 `release` 子对象里都认): + - `version` / `latest_version`(版本号;`release.version` 或顶层 `latest_version`,二选一必须有) + - `force_update`(bool;true/1/yes 系列都识别) + - `min_supported_version`(低于它的一律强制) + - `download_url`、`sha256`(第一版不校验,可空)、`release_notes`/`message`(升级说明) +- **强制规则**(`is_forced_update`):`force_update=true` 且 本地 < `latest_version` → 强制;或 本地 < `min_supported_version` → 强制;两者都不满足 → 非强制(客户端当前不弹)。 +- **发版约定**: + - 强制升到最新 → `release.force_update: true`(方案 A)。 + - 强制淘汰旧版 → `min_supported_version` 设为要淘汰之上的版本(方案 B)。 + - 不想强制 → 都不给(客户端当前不提示;若要温和可跳过提示,另立任务)。 +- **示例响应**(强制版,方案 A):给出带 `"force_update": true` 的完整 JSON 样例。 +- **失败放行**:接口断网/超时/非法 JSON/缺字段 → 客户端记诊断日志放行、不阻断(写明,避免误以为坏了)。 +- **服务端动作(本仓库外)**:`cm.833729.com` 的 releases/latest 返回里加 `force_update: true`。 + +## 验收要点 + +- `docs/update-check.md` 写清接口、客户端字段读取、强制规则、发版约定、强制版示例 JSON、失败放行行为。 +- `docs/README.md` 索引新增该文档链接。 +- 明确客户端无需改代码(T-544 已实现),可选项目在正文标注。 +- 不含真实密钥/内部地址以外的敏感信息(接口 URL 属公开)。 + +## 边界(不改什么) + +只加文档(`docs/update-check.md` + README 索引)。不改 `app/update_check.py`/`app/version.py`/启动流程等客户端代码(T-544 已够);服务端返回 `force_update` 属本仓库外配置。 + +## 执行记录 + +(做完在此记录:改了哪些文件、跑的验证命令与结果、决策)