T-618 require release checksum metadata in admin
This commit is contained in:
@@ -224,7 +224,7 @@ CREATE TABLE import_template (
|
||||
);
|
||||
```
|
||||
|
||||
T-102 已实现 `AiModel` / `ModelAlias` 的 Django models、admin、迁移与别名解析。T-103 已补 `AiConfigAuditLog`,admin 里保存/删除模型配置或能力别名时自动写审计日志。T-202 已实现 `PricingRule` / `ExchangeRate` 与 `apps.billing.pricing` 计算函数:定价按 `operation_type + alias + resolution` 查 active 规则,优先 exact resolution,再回退到空 resolution 默认价;缺规则抛 `NoPricingRuleError(code="no_pricing_rule")`。T-203 已实现 `apps.billing.services`:`precharge_call()` 锁 `UserWallet` 行预扣并写 pending 调用与 consume 流水;`mark_call_success()` 确认成功不再改余额;`refund_call_points()` 锁调用记录并幂等退点,写 refund 流水。T-401 已在同一计费层新增 `adjust_wallet_points()`,供 admin 手工调点使用。T-606/T-609/T-617 已实现 `DownloadRelease`,admin 可上传安装包或填写 `external_url`、标记当前版本、配置是否强制更新和文件大小字节数;`external_url` 优先于 `file.url`,每平台仅一个当前版本由模型 `save()` 在事务内把同平台旧 current 置为 false。T-610 已新增 `ImportTemplate`,admin 可上传导入模板或填写 `external_url` 并标记当前模板;`external_url` 优先于 `file.url`,当前模板互斥同样由应用层事务处理,不使用 MySQL 不支持的条件唯一约束。T-607/T-609/T-617 版本检查接口只读取 `DownloadRelease(platform, is_current=True)`;响应 URL 是外部可访问 URL,不暴露本地 `MEDIA_ROOT`,并把 `force_update` 和 `size_bytes` 作为公开发布元数据返回。导入模板下载不新增对外 JSON API,首页直接渲染当前模板下载链接。默认别名唯一性由 model validation、admin 与导入器保证;MySQL 不支持通用 partial unique index,若后续要强制数据库层默认别名唯一,可另评估触发器或约束表。
|
||||
T-102 已实现 `AiModel` / `ModelAlias` 的 Django models、admin、迁移与别名解析。T-103 已补 `AiConfigAuditLog`,admin 里保存/删除模型配置或能力别名时自动写审计日志。T-202 已实现 `PricingRule` / `ExchangeRate` 与 `apps.billing.pricing` 计算函数:定价按 `operation_type + alias + resolution` 查 active 规则,优先 exact resolution,再回退到空 resolution 默认价;缺规则抛 `NoPricingRuleError(code="no_pricing_rule")`。T-203 已实现 `apps.billing.services`:`precharge_call()` 锁 `UserWallet` 行预扣并写 pending 调用与 consume 流水;`mark_call_success()` 确认成功不再改余额;`refund_call_points()` 锁调用记录并幂等退点,写 refund 流水。T-401 已在同一计费层新增 `adjust_wallet_points()`,供 admin 手工调点使用。T-606/T-609/T-617/T-618 已实现 `DownloadRelease`,admin 可上传安装包或填写 `external_url`、标记当前版本、配置是否强制更新和文件大小字节数;T-618 起 admin 新增 / 编辑发布版本时 `sha256` 与 `size_bytes` 必填,但数据库仍保留空值兼容历史记录;`external_url` 优先于 `file.url`,每平台仅一个当前版本由模型 `save()` 在事务内把同平台旧 current 置为 false。T-610 已新增 `ImportTemplate`,admin 可上传导入模板或填写 `external_url` 并标记当前模板;`external_url` 优先于 `file.url`,当前模板互斥同样由应用层事务处理,不使用 MySQL 不支持的条件唯一约束。T-607/T-609/T-617 版本检查接口只读取 `DownloadRelease(platform, is_current=True)`;响应 URL 是外部可访问 URL,不暴露本地 `MEDIA_ROOT`,并把 `force_update` 和 `size_bytes` 作为公开发布元数据返回。导入模板下载不新增对外 JSON API,首页直接渲染当前模板下载链接。默认别名唯一性由 model validation、admin 与导入器保证;MySQL 不支持通用 partial unique index,若后续要强制数据库层默认别名唯一,可另评估触发器或约束表。
|
||||
|
||||
> 可选增强(接口预留、MVP 不实现):`account_alias_permission`(按账号授权可用别名,防止调用方点用未授权/昂贵模型);别名按比例分流到多个模型(灰度/AB/故障转移)。适配器接口需为此留口子。
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
| T-616 | 生图失败自动重试 2 次 | T-614, T-615, T-203 | 给异步生图 worker 增加临时性上游失败自动重试,降低 `api.vectorengine.ai` 偶发 `Read timed out` 对用户的失败率。**业务口径**:“2 次重试”定义为第 1 次正常执行 + 失败后最多再重试 2 次,即最多 3 次上游调用;提交阶段仍只预扣一次。**只重试临时性错误**:`upstream_timeout`、网络连接错误、上游 502/503/504 等;不重试 `content_blocked`、`insufficient_points`、`no_pricing_rule`、模型/别名配置不可用、参数错误、Provider 配置错误等确定性错误。**数据结构**:复用现有 `attempt_count` 表示已开始执行次数;新增 `next_attempt_at`(允许下次抢占时间)和必要的 metadata-only admin 展示;如需记录最后一次错误,继续使用 `error_code` / `error_message`,不得保存 provider raw。**状态机**:`queued -> running(attempt_count+1)`;若成功则 `succeeded` 并确认已预扣调用;若可重试失败且 `attempt_count < 3`,任务回到 `queued`、设置 `next_attempt_at=now+backoff`、保留 `CallRecord.pending`、不退点;若不可重试或已到最终次数,才 `failed` 并调用计费层幂等退点。**worker 抢任务**:只抢 `status=queued` 且 `next_attempt_at IS NULL OR next_attempt_at <= now` 的任务;避免 66 worker 立即反复打爆上游。**配置**:新增 `IMAGE_TASK_MAX_RETRIES=2`、`IMAGE_TASK_RETRY_BACKOFF_SECONDS=10,30`(或等价配置),同步 `.env.example`、`env.md`、`deployment.md`;生产要提醒最坏耗时约 `上游硬截止 * 3 + backoff`,桌面端轮询超时需覆盖。**接口兼容**:轮询响应可新增可选字段 `attempt_count`、`max_attempts`、`next_attempt_at`,但不得删除既有字段;旧客户端忽略新字段仍可工作。**日志**:扩展 `event=image_task_processed`,包含 `attempt`、`max_attempts`、`retrying`、`next_attempt_at`、`duration_ms`、`error_code`,不得记录 prompt、base64、provider raw 或密钥。**账务验收**:第 1/2 次 `upstream_timeout` 回到 queued 且不退点;第 3 次成功只扣一次并成功确认;连续 3 次失败只退一次;非重试错误立即失败并只退一次;幂等提交仍返回同一 task,不重复预扣;reaper 与迟到 worker 不得把已最终失败/已退款任务改回成功。**测试**:覆盖上述账务、状态机、backoff 抢占、轮询新增字段兼容、worker 日志字段和敏感信息不泄露;`makemigrations` / `migrate` / `check` / 目标测试 / `init` 通过并在 `../progress.md` 留证据 | DONE |
|
||||
|
||||
| T-617 | 桌面端版本检查接口增加文件大小字段 | T-607, T-609 | 在 `GET /api/v1/client/releases/latest?platform=windows` 的当前版本响应中,为 `release` 对象新增 `size_bytes` 字段,用于桌面端下载后比对文件大小。**接口兼容**:只新增字段,不删除既有 `version` / `download_url` / `sha256` / `release_notes` / `force_update` / `published_at`;无当前版本或无下载地址时仍返回 `release:null`,不返回顶层 `size_bytes`。**数据来源**:`DownloadRelease` 新增 `size_bytes` 可空正整数字段,单位字节,django-admin 可填写并在列表展示;老数据为空时接口返回 `null`,客户端只在值为正整数时做大小校验。**安全**:接口仍公开匿名只读,不读取用户、不扣点、不暴露后台 ID、本地文件路径或内部状态。**文档**:同步 `api.md`、`routes.md`、`04-architecture.md`、`02-requirements.md`、`current-state.md`。**测试**:覆盖有值返回整数、未配置返回 `null`、未发布响应不返回顶层字段、响应字段白名单更新、admin 字段可见;`makemigrations --check` / `check` / 目标测试通过并在 `../progress.md` 留证据 | DONE |
|
||||
| T-618 | 客户端发布版本后台必填文件校验元数据 | T-617 | 把 django-admin 里 `DownloadRelease` 的 `sha256` 和 `size_bytes` 改为必填,避免运营发布客户端安装包时漏填校验元数据,导致桌面端无法完整校验下载文件。**范围**:本任务只要求 admin 后台保存时必填;为兼容历史数据和现有 API 合约,第一步不直接把数据库字段改成 `NOT NULL`,`size_bytes` 仍允许旧记录为空,API 暂保持可返回 `null`;若后续要数据库级强约束,需先单独回填全量历史发布记录再做迁移。**实现**:`DownloadReleaseAdmin` 已挂专用 `ModelForm`,将 `sha256`、`size_bytes` 设为 required,并保留 `sha256` 64 位十六进制校验、`size_bytes >= 1` 校验;admin 新增 / 编辑保存时未填会显示字段级错误,不写库。**生产数据**:上线后必须补齐当前 `windows` 发布版本的 `size_bytes`,再验证 `/api/v1/client/releases/latest?platform=windows` 返回正整数 `release.size_bytes`;已有 `sha256` 继续保留并核对。**兼容性**:不删除既有 API 字段,不改变无当前版本时的 `release:null`;非 admin 的历史数据、迁移和只读接口不应因空值直接 500。**文档**:同步 `api.md`、`04-architecture.md`、`routes.md`、`current-state.md` 和 `progress.md` 的发布校验口径。**测试**:已覆盖 admin 表单缺 `sha256` / 缺 `size_bytes` 拒绝保存、合法 `sha256 + size_bytes` 可保存、API 仍能读取历史空值记录、当前版本补齐后接口返回正整数;`check` / `makemigrations --check` / 目标测试通过并在 `../progress.md` 留证据 | DONE |
|
||||
|
||||
## 里程碑
|
||||
|
||||
@@ -113,6 +114,7 @@
|
||||
- M11:生图异步任务化(先止血、后共享 core、再新老接口共存并观察旧路用量,T-612~T-615)。
|
||||
- M12:生图失败自动重试(T-616)。
|
||||
- M13:桌面端版本文件大小校验元数据(T-617)。
|
||||
- M14:客户端发布版本后台必填校验元数据(T-618)。
|
||||
|
||||
## 待办池(Backlog)
|
||||
|
||||
|
||||
+2
-2
@@ -138,9 +138,9 @@ GET /api/v1/client/releases/latest?platform=windows
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:`force_update` 为布尔值,表示桌面端是否必须升级到该版本;未勾选时返回 `false`。`size_bytes` 为整数或 `null`,单位字节;后台未填写时返回 `null`,客户端应只在该值为正整数时校验下载后的本地文件大小。客户端可先做版本号比较,再按 `force_update=true` 阻止继续使用旧版本或进入强制升级流程,下载完成后同时校验 `size_bytes` 和 `sha256`。
|
||||
字段说明:`force_update` 为布尔值,表示桌面端是否必须升级到该版本;未勾选时返回 `false`。`size_bytes` 为整数或 `null`,单位字节;T-618 起 django-admin 新增 / 编辑客户端发布版本时要求填写 `sha256` 和 `size_bytes`,但历史记录或非 admin 导入数据仍可能为空,客户端应只在该值为正整数时校验下载后的本地文件大小。客户端可先做版本号比较,再按 `force_update=true` 阻止继续使用旧版本或进入强制升级流程,下载完成后同时校验 `size_bytes` 和 `sha256`。
|
||||
|
||||
要点:接口只查 `DownloadRelease(platform, is_current=True)`;`download_url` 优先使用 `external_url`,否则用 `file.url` 生成绝对 HTTPS URL;`published_at` MVP 可使用 `DownloadRelease.updated_at`;`force_update` 使用后台发布版本上的布尔配置,默认 `false`;`size_bytes` 使用后台填写的安装包字节数,可为空。响应不得包含本地 `MEDIA_ROOT`、文件系统路径、后台 ID、`is_current`、用户信息、API Key、模型配置或任何密钥字段。成功和“暂未发布”均返回 HTTP 200,方便桌面端静默检查;非法平台返回 `400 bad_request`。无当前版本或当前版本没有下载地址时返回 `release:null`,不返回独立的 `force_update` / `size_bytes` 顶层字段。
|
||||
要点:接口只查 `DownloadRelease(platform, is_current=True)`;`download_url` 优先使用 `external_url`,否则用 `file.url` 生成绝对 HTTPS URL;`published_at` MVP 可使用 `DownloadRelease.updated_at`;`force_update` 使用后台发布版本上的布尔配置,默认 `false`;`size_bytes` 使用后台填写的安装包字节数,可为空以兼容历史记录。响应不得包含本地 `MEDIA_ROOT`、文件系统路径、后台 ID、`is_current`、用户信息、API Key、模型配置或任何密钥字段。成功和“暂未发布”均返回 HTTP 200,方便桌面端静默检查;非法平台返回 `400 bad_request`。无当前版本或当前版本没有下载地址时返回 `release:null`,不返回独立的 `force_update` / `size_bytes` 顶层字段。
|
||||
|
||||
### `POST /api/v1/generate/title`
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -57,7 +57,7 @@ T-614 已落地 `/api/v1/generate/image/tasks` 与 `/api/v1/generate/image/tasks
|
||||
| 模型配置 | AiModel | 维护上游模型(url/model/api_key[加密脱敏]/api_type/capabilities/timeout) |
|
||||
| 能力别名 | ModelAlias | 维护对外别名 → 具体模型的映射;换供应商在此改指向 |
|
||||
| 配置审计 | AiConfigAuditLog | 只读查看 AiModel / ModelAlias / 密钥变更:谁、何时、改了什么 |
|
||||
| 客户端下载版本 | DownloadRelease | 上传安装包或填写外部下载地址,标记每个平台当前版本、是否强制更新和文件大小字节数;展示版本、SHA256、强制更新标记与发布说明 |
|
||||
| 客户端下载版本 | DownloadRelease | 上传安装包或填写外部下载地址,标记每个平台当前版本、是否强制更新和文件大小字节数;新增 / 编辑时必须填写 SHA256 与文件大小字节数;展示版本、SHA256、强制更新标记与发布说明 |
|
||||
| 导入模板 | ImportTemplate | 上传导入模板或填写外部下载地址,标记当前模板;展示模板名称、SHA256 与说明 |
|
||||
|
||||
## 后台职责约定
|
||||
|
||||
Reference in New Issue
Block a user