Files

79 lines
5.4 KiB
Markdown

---
id: T-206
title: 单趟状态详情与安全主动作
phase: 2
deps: [T-205]
status: TODO
created: 2026-08-04
vikunja_task_id: 45
context_ref: cd47d0c
work_branch: task/t-206-status-safe-actions
needs_device: false
needs_human_review: false
write_paths:
- docs/tasks/T-206.md
- admin/internal/taskdetail/**
- admin/internal/server/task_detail.go
- admin/internal/server/task_detail_test.go
- admin/internal/transport/webui/webui.go
- admin/internal/transport/webui/templates/task-detail.html
- docs/routes.md
- docs/08-interaction-checklist.md
- docs/current-state.md
---
<!-- BEGIN VIKUNJA EXPORT id=45 synced=2026-08-04T14:41:45Z sha256=357ce372339f0d744849742f5dd2a38e79d6fc3bef0bd4053287f864fb778460 -->
## 问题 / 背景
T-204 已有只读详情底座,T-205 将提供 attempt 事件、执行摘要和围栏前失败事实。当前详情仍不能可靠回答“目前在哪一步、是否已建立围栏、唯一安全下一步是什么”。T-206 只扩展只读详情和安全主动作推导;不实现重置、调和、付款或设备动作。
## 关联需求与交互
- 功能:F-004、F-007、F-011、F-017 的状态展示部分。
- 用户故事:US-002、US-004、US-008。
- 交互:IX-004、IX-009、IX-010、IX-011 的只读状态和下一步提示。
- 依赖:T-205;由其传递 T-204、T-210、T-302 及事件/证据事实。
- 后续消费者:T-207 围栏前人工恢复、T-208 提交围栏与调和。
- 本任务不新增管理或设备写接口。
## 方案
1. 在同一个只读事务中加载任务/版本、当前及历史 authorization、T-302 claim 的非秘密摘要、attempt、T-205 append-only 时间线/执行摘要、三闸门 evidence 摘要和 order_submission/调和摘要。设备只展示非秘密名称、generation 和租约状态,不返回 token、nonce 或 session。
2. 增加纯函数式 SafePrimaryAction 推导。任何 order_submission 的存在都优先于 task.status;其次处理 RECONCILIATION_REQUIRED、WAITING_PAYMENT,再处理围栏前状态。事实互相矛盾时进入 SAFETY_HOLD,不显示写动作。
3. DRAFT 只引导返回列表勾选,不新增逐行开始按钮;PENDING/CLAIMED/ORDERING 只读展示授权、领取和步骤进度;过期授权只提示等待人工关闭,不能表述为可安全重领。
4. NEEDS_MANUAL 且无 submission 时显示固定失败码、最后安全步骤和“查看围栏前恢复条件”,本任务只做页内导航;不提前渲染 T-207 的 POST 表单。
5. 只要存在 submission,即使 task 仍错误地显示 ORDERING/NEEDS_MANUAL,也必须显示围栏锁定和同一 submission;不显示重置、取消、重新授权或再次提交。
6. RECONCILIATION_REQUIRED 只引导查看同一提交;WAITING_PAYMENT 明确“订单已创建,系统尚未付款”并只引导核对证据;标记付款属于 T-402。
7. Gate1/Gate2/Gate3 只按服务端固定 kind 和数据库事实展示,不解析图片、不自行计算或推断闸门通过。未知状态、缺少关联记录和归属冲突均 fail closed。
8. 完整页和抽屉继续共享同一详情模型与模板,保持返回、焦点、滚动、键盘、响应式及 no-store 证据边界。
## 验收要点
- 覆盖 DRAFT、PENDING、CLAIMED、ORDERING、NEEDS_MANUAL、WAITING_PAYMENT、RECONCILIATION_REQUIRED、终态、空态和 SAFETY_HOLD 的完整矩阵。
- ORDERING/NEEDS_MANUAL 与 order_submission 同时存在时必须显示围栏锁定;绝不出现围栏前恢复动作。
- 过期 lease/authorization 只显示事实,不把它推导成手机已停止、可释放或可转领。
- 页面不出现旧两趟、中途确认、自动付款、重新提交或普通重试术语;DRAFT 不增加逐行开始采购。
- 完整页和抽屉内容一致,匿名请求在查询前拒绝;页面不泄露 token、nonce、session、SQL 或路径。
- `go test ./...`、`go test -race ./...`、`go vet ./...`、`go build ./...`、完整 init、上下文、Vikunja export 与 diff-check 通过。
## 执行记录
(暂无)
<!-- END VIKUNJA EXPORT -->
## 边界
- 本任务只读取并展示 T-204/T-205/T-302 已保存的任务、授权、claim、attempt、事件、证据和
submission 事实;不得新增管理或设备写接口,不得在读取详情时隐式续租、关闭、释放或改变状态。
- 任意 `order_submission` 的存在都必须压倒 `task.status` 和围栏前提示。即使任务错误地仍为
`ORDERING` / `NEEDS_MANUAL`,也只能展示同一 submission 的围栏/调和路径,绝不显示重置、取消、
重新授权、重新领取或再次提交。
- 租约或授权过期只是一项只读事实,不证明手机已经停止,不得把它推导成可释放、可转领或可安全
重试。事实缺失、归属不完整或互相冲突时进入 `SAFETY_HOLD`,不猜测、不渲染写动作。
- T-206 的安全主动作只允许返回列表、页内定位或查看既有事实;不得提前实现 T-207 重置/取消、
T-208 围栏/调和或 T-402 标记付款,不得增加逐行“开始采购”按钮或中途确认。
- Gate1/Gate2/Gate3 只按服务端固定 kind、事件和数据库记录展示;不解析图片、不自行认定页面、
不重新计算为可提交许可。截图仍只供内部审计,不替代实时三闸门。
- 不接触真机页面判据、client 代码、`submit_order_once()` 或任何支付、免密支付、先用后付和扣款能力。