Files
cmbuyer/docs/tasks/T-306.md
T

79 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-306
title: 规格面板原始截图与可靠证据上传
phase: 3
deps: [T-104, T-303]
status: TODO
created: 2026-08-04
vikunja_task_id: 38
context_ref: 41e54e3
work_branch: task/t-306-evidence-upload
needs_device: false
needs_human_review: false
write_paths:
- docs/tasks/T-306.md
- client/src/cmbuyer_client/evidence/**
- client/tests/evidence/**
---
<!-- BEGIN VIKUNJA EXPORT id=38 synced=2026-08-04T13:48:05Z sha256=5bcea505093335085e44e062064d01d95e5c64a70d0d8faf85e1ea10852d7fbb -->
## 问题 / 背景
T-104 将在规格选择、闸门一读价、原始截图和严格安全退出全部成功后返回显式 PNG 产物;T-303 提供受设备认证的 HttpEvidenceSink 与可崩溃恢复的唯一上传槽。T-306 只把这张规格面板原始截图可靠上传为内部审计证据,不连接 UI/轮询、不扩展页面能力或服务端证据类型。
## 关联需求与交互
- 功能:F-007、F-013。
- 用户故事:US-004、US-005。
- 依赖:T-104、T-303;T-103 由 T-104 传递,T-204/T-302 由 T-303 传递。
- 后续消费者:T-305 围栏前 dry-run。
- 本任务可与 T-304、T-205 并行,不修改 app/polling/ui、remote/localstate 或 admin。
## 方案
1. 定义窄 EvidencePublisher,只接受 T-104 成功结果中的显式 screenshot_path 与 UTC captured_at,以及当前 T-303 active claim;不得接收目录、manifest 或任意文件选择。
2. 上传元数据固定为 kind=SKU_PANEL_GATE_1、privacy_tier=INTERNAL_RAW;task/attempt 只来自 active claim。post-exit 商品详情截图没有获批 kind,不上传。
3. 调用 T-303 的 prepare-or-resume evidence 原子槽:按 (attempt_id, kind) 唯一,首次 HTTP 前已保存 upload_key、完整元数据、文件 identity/大小/SHA-256;本任务不得另建 SQLite。
4. 每次调用最多发送一次 HTTP。网络错误、超时、503、截断或非法响应只保留同一槽;进程重启后仅重放同一 key、相同字节和元数据,不在内部循环重试。
5. 201 首次成功和 200 稳定重放都必须严格核对 AssetRef。成功后槽继续保存 AssetRef;重复调用只返回原结果,不能清 pending 后生成新 key 或上传第二张。
6. 原文件缺失或 identity/大小/hash 变化时零 HTTP、保留恢复事实并转人工;不得改用别的截图、重新截图或枚举目录找替代品。
7. 首次上传前 active claim 的 task/attempt/device/session/generation 必须一致;pending 永远绑定原 claim。关闭 claim 后只允许原 key 的可能成功重放,不允许新上传槽。
8. 停止轮询只阻止下一领取,不取消在途上传、不清 pending、不删除原图、不 release/abandon。强制退出后只恢复 HTTP,不恢复任何真机动作。
9. 原始 PNG 可以包含页面已显示的地址和手机号,不遮罩、不裁剪、不 OCR,也不把它们解析为字段、日志或错误;完整 XML、manifest、本机路径、原文件名、外部支付页和支付凭据永不上传。
10. multipart 使用固定安全文件名,只发 T-204 已冻结字段,不增加 claim token/session/path,不扩展 SKU_PANEL_GATE_2 或确认页 kind。
## 验收要点
- T-104 成功产物只调用一次 sink;安全退出失败、claim 不一致、无 active claim或文件变化均零 HTTP。
- 首次传输前幂等槽已持久化;结果不明和重启后 key/bytes/metadata 原样重放;重复成功返回同一 AssetRef。
- 停止/关闭不取消在途请求、不清 pending、不触发 ADB;拒绝目录、XML、manifest、JPEG、post-exit 截图和未批准 kind。
- 原始 PNG 字节保持不变,含地址/手机号不触发遮罩;日志/异常不含 token、页面正文、路径或原文件名。
- 静态检查没有目录枚举、uiautomator2、PDD 点击、数量、确认页、围栏、提交订单或付款能力。
- client 全量 unittest、compileall、wheel metadata、完整 init、Vikunja 导出、上下文校验与 diff-check 通过。
## 执行记录
### 2026-08-04T13:47:38Z · ila
2026-08-04 预研定值:T-306 收窄为 T-104 gate1 单张原始 PNG 到 T-303 唯一持久上传槽的可靠适配,因此可与 T-304/T-205 并行;不扩展服务端 kind、不另建 SQLite、不连接真机或 UI。
<!-- END VIKUNJA EXPORT -->
## 边界
- 唯一输入是 T-104 在规格选择、闸门一读价、规格面板原始截图和严格安全退出全部成功后返回的
显式 `screenshot_path` 与 UTC `captured_at`。不得枚举目录、读取 manifest、使用文件选择器,
也不得把 post-exit 商品详情截图或其他文件冒充规格面板证据。
- 只发布一个 `kind=SKU_PANEL_GATE_1`、`privacy_tier=INTERNAL_RAW` 的原始 PNG;task/attempt 只来自
当前 active claim。不得增加 gate2/确认页 kind,不得修改 admin schema/API,也不得自行向 multipart
增加 claim token、session、路径、原文件名或其他字段。
- 上传幂等与恢复只使用 T-303 的 `(attempt_id, evidence_kind)` 唯一原子槽。本任务不得另建 SQLite、
生成第二套 upload key 或清除成功 AssetRef;结果不明只能以原 key、原字节、原元数据恢复。
- 每次调用最多一次 HTTP,不在内部循环重试。文件缺失或 identity/大小/hash 变化时必须零 HTTP 并
转人工;不得重新截图、替换文件或在目录中寻找“相似”截图。
- 停止轮询、Esc、关闭窗口和进程退出不取消在途上传、不清 pending、不删除原图、不 release/abandon
claim,也不触发任何 ADB/PDD 动作。重启只可恢复同一 HTTP 请求,不自动恢复设备页面操作。
- 原始 PNG 可包含页面已显示的地址和手机号,不遮罩、不裁剪、不 OCR;不得把地址或手机号解析为
业务字段、日志或异常文本。完整 XML、manifest、本机路径、页面全文、外部支付页和支付凭据不上传。
- 不导入或实现 uiautomator2、PDD 页面判据、通用 click、规格/数量/确认页动作、事件、失败上报、
提交围栏或结果接口;不编写或引用点击“提交订单”的代码,不编写支付或任何扣款能力。