Record real Playwright ledgers, mark 20 audits and 9 remediations done, and leave management-implementation-plan as plan-only.
3.4 KiB
3.4 KiB
title, status, created, updated
| title | status | created | updated |
|---|---|---|---|
| 权威文档职责 + 打开时基线 ETag | done | 2026-09-13 | 2026-09-22 |
权威文档职责 + 打开时基线 ETag
W3 UI-rerun 关闭(2026-09-22):
status=done。真实 Playwright 账本 PASS:ui-acceptance-results.json(main UI-00..16)+ui-acceptance-results-post-restart.json(UI-15)。任务 tip 已合入本地dev;详见 short-term 与 测试报告。
背景
链到 ../audit/2026-09-13-document-revision-duty-etag-overwrite.md。
陌生人/审核人被抬成编制人可改受控正文;保存时重取最新 ETag 会掩盖 409 并覆盖并发编辑。
目标
- 列表 summary 返回台账 author/reviewer/approver 的 id+name;前端保留权威字段,禁止用当前登录用户伪造 author。
currentDocRole按权威 user id 解析;name 仅兼容旧本地文档;未知身份 fail-closed 为viewer;viewer 无编辑/审核/批准动作。- 受控正文 hydrate 同时取 revision-state ETag 写入 AST/缓存;人工 PATCH 只用该基线;成功后用响应
state.etag更新;冲突保留编辑器与文本。 - 受控 fail-closed:缺打开时 ETag 禁止 PATCH
0:0;hydrate 遇 revision-state 网络/5xx/NOT_FOUND/NEEDS_CONTENT 走正文加载失败屏障。仅 freeform 允许0:0。 - viewer 只读批注:无右键/浮标新增入口,面板不可提交;author/reviewer/approver 语义不变。
- 服务端受控 /
dutiesAuthoritative一律按 id fail-closed;name 回退仅真正旧本地文档。duty id 为 0 不得当成本地旧文档。 - UI-13b:A1 保存前两窗口已加载相同 r/etag,且 A2 编辑器已打开并填入文本。
分波次计划
| 波次 | 内容 | 验收 |
|---|---|---|
| Wave 1 | Go summary 投影职责 + 单测 | B 不是 author;A 仍是 author |
| Wave 2 | 前端 merge / UserRole=viewer / resolveCurrentDocRole |
B/陌生人不成 author;viewer 无动作 |
| Wave 3 | hydrate 基线 ETag + PATCH 不再 GET | stale ETag 单测;不能用最新 ETag 掩盖冲突 |
| Wave 4 | UI-13b 真实竞争脚本 | A2 先开编辑器再 A1/A2 保存 |
| Wave 4b | ETag/viewer/零 id 补强 | controlled 缺基线不可保存;viewer 只读批注;id=0 不按 name 提权 |
| Wave 5 | 占槽真实 UI(本轮不做) | UI-13a/13b 实战 PASS 后才可 done |
验收标准
- Go
ListWorkflowDocumentsIncludesAuthoritativeDuties - 前端 merge +
resolveCurrentDocRole单测 - stale hydrate ETag 用于保存(纯函数 + hydrate 单测)
- UI-13b 脚本不降级(本轮不跑真实 E2E)
- controlled 缺 hydrate ETag / 5xx 不可保存或打开;freeform 可
0:0 - viewer 不能新增批注
- 服务端 duty id=0 不按 name 提权
- 真实 UI 重跑 PASS