Close workbench P0 resource lifecycle gaps

This commit is contained in:
lix-2026
2026-05-20 20:48:18 +08:00
parent e0b0e70fb8
commit fe13444dbc
14 changed files with 610 additions and 7 deletions
@@ -0,0 +1,52 @@
# 4-41 FileTree Bulk Resource Command Cutover Checklist v1
> 状态:process
>
> 日期:2026-05-20
>
> OwnerFile Tree bulk delete / `layout.rs`
## 1. 目标
补齐 P0-5 剩余项:前端本地文件夹 bulk delete 对 file asset、mindmap、table、raw local file 等资源优先走 `/api/tree/commands``tree.resource.*` 语义,旧 route 仅保留云端或兼容 fallback。
## 2. 允许修改范围
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- `scripts/task464-local-folder-resource-trash-ui-smoke.js`
- 可新增聚焦 bulk delete smoke
## 3. 禁止事项
- 不删除旧 `/api/mindmap``/api/media``/api/tables` 兼容 route。
- 不改变 Convex 云端 asset lifecycle。
- 不把 bulk delete 改成永久删除;默认仍是 archive/trash。
## 4. Checklist
- [x] local file asset bulk delete 使用 `dispatchTreeCommand({ action: 'archive', documentId })`
- [x] local mindmap bulk delete 使用同一 tree command,不再走 `/api/mindmap`
- [x] local table bulk delete 使用同一 tree command,不再走 `/api/tables`
- [x] bulk delete 成功后刷新本地 file tree snapshot / trash index 可见。
- [x] 失败项保留可见错误,不清空未成功项。
- [x] smoke 覆盖至少两个不同 resource kind 的批量删除进入垃圾箱。
## 5. 验收
- [x] `node --check scripts/task464-local-folder-resource-trash-ui-smoke.js`
- [x] `node scripts/task464-local-folder-resource-trash-ui-smoke.js`
- [x] `node --check scripts/task471-local-folder-bulk-resource-trash-smoke.js`
- [x] `node scripts/task471-local-folder-bulk-resource-trash-smoke.js`
- [x] 新增 bulk delete 合同测试通过:`cargo test -p mnote-web sidebar_filetree_local_table_bulk_delete_uses_tree_command -- --test-threads=1`
- [x] `cargo test -p mnote-web tree_command_local_folder -- --test-threads=1`
## 5.1 本轮执行记录
- 已合入:local table bulk delete 分支切到 `/api/tree/commands` archivefile asset / mindmap 原先已经走同一命令。
- 已保留:云端 table 仍走 `/api/tables/` fallback,旧 route 未删除。
- 已新增:`scripts/task471-local-folder-bulk-resource-trash-smoke.js`,覆盖 local folder 两个资源行多选 Delete、两个 archive tree command、文件移入垃圾箱和 trash index。
## 6. 非目标
- 不实现 undo。
- 不实现云端 bulk lifecycle parity。
@@ -0,0 +1,49 @@
# 4-42 FileTree Open Target RootUri Contract Checklist v1
> 状态:process
>
> 日期:2026-05-20
>
> OwnerFileTree runtime open target / `filetree_runtime.rs`
## 1. 目标
补齐 P0-4 的剩余合同问题:`FileTreeOpenTarget::LocalFile` / `Directory` 已存在,但 `rootUri` 仍为空字符串占位。需要让 runtime 环境携带本地 root,并让 open target 输出真实 `rootUri`
## 2. 允许修改范围
- `rust/crates/mnote-web/src/tree_shell/filetree_runtime.rs`
- `rust/crates/mnote-web/src/tree_shell/runtime_api.rs`
- `rust/crates/mnote-web/src/routes/tree.rs`
- 相关 Rust 单测
## 3. 禁止事项
- 不改变 File Tree row 的长期资源真相。
- 不改前端打开行为。
- 不删除旧 `Asset` JSON 兼容字段。
## 4. Checklist
- [x] `FileTreeRuntimeEnvironment` 携带可选 `rootUri`
- [x] `resolve_open_target``LocalFile` / `Directory` 使用环境中的 `rootUri`
- [x] tree shell SSR app state / runtime reduce 请求填入 local folder `rootUri`
- [x] runtime API 反序列化对缺失 `rootUri` 保持兼容。
- [x] Rust 单测覆盖 local file / directory open target 输出真实 `rootUri`
## 5. 验收
- [x] `cargo test -p mnote-web filetree_runtime -- --test-threads=1`
- [x] `cargo test -p mnote-web runtime_api -- --test-threads=1`
- [x] `cargo test -p mnote-web tree_shell_filetree_mode_embeds_asset_state -- --test-threads=1`
## 5.1 本轮执行记录
- 已合入:`FileTreeRuntimeEnvironment.rootUri`,并在 filetree runtime open target 中用于 local file / directory。
- 已补充:tree shell 前端 runtime 环境构造会在 local folder 模式传入 `rootUri`
- 已验证:缺失 `rootUri` 的旧 runtime API JSON 仍可反序列化。
## 6. 非目标
- 不处理 resource lifecycle。
- 不处理 tab URL 同步。
@@ -0,0 +1,50 @@
# 5-20 Resource Tab Close Confirm Checklist v1
> 状态:process
>
> 日期:2026-05-20
>
> Owner:主编辑区 resource tab close guard / `web_shell.rs`
## 1. 目标
补齐 P0-2 的可见关闭防护:resource tab 已能检测 `dirty/saving/hasExternalConflict`,但当前只是 `console.warn` 并阻止关闭。需要补上用户可见的最小确认/提示 UI,避免“点击无反应”。
## 2. 允许修改范围
- `rust/crates/mnote-web/src/routes/web_shell.rs`
- `rust/crates/mnote-web/src/ssr/styles.rs`
- `scripts/task460-resource-tab-close-dirty-smoke.js`
- 可新增一个聚焦 smoke
## 3. 禁止事项
- 不引入完整 VSCode working copy service。
- 不改变 resource markdown / text / code 的保存事实源。
- 不实现完整 discard/undo 体系;本轮只做可见提示和明确阻止。
## 4. Checklist
- [x] `dirty` 关闭时显示明确提示,说明资源有未保存更改。
- [x] `saving` 关闭时显示明确提示,说明正在保存。
- [x] `hasExternalConflict` 关闭时显示明确提示,说明存在外部冲突。
- [x] tab 上保留 `data-mnote-resource-close-guard` 与可测试状态。
- [x] 提示 UI 可被后续关闭尝试更新,不堆积多个弹层。
- [x] 新增或更新 smoke 覆盖点击关闭后出现提示,而不是静默无响应。
## 5. 验收
- [x] `node --check scripts/task460-resource-tab-close-dirty-smoke.js`
- [x] `node scripts/task460-resource-tab-close-dirty-smoke.js`
- [x] `cargo test -p mnote-web web_shell -- --test-threads=1`
## 5.1 本轮执行记录
- 已合入:`showResourceTabCloseGuardNotice`,对 `dirty` / `saving` / `hasExternalConflict` 输出可见提示。
- 已验证:`task460` 断言可见提示存在且重复点击不堆叠。
- 保留约束:仍只阻止关闭,不实现 discard/undo。
## 6. 非目标
- 不做真正丢弃更改按钮。
- 不做保存队列或 retry 策略。
@@ -0,0 +1,49 @@
# 5-21 Editor Tab URL / Active Row / Canonical Identity Checklist v1
> 状态:process
>
> 日期:2026-05-20
>
> Owner:主编辑区 tab runtime / sidebar active state / resource identity
## 1. 目标
在 P0 清零后推进相邻 P1:resource tab 激活目前主要改 DOM 状态,不稳定同步 URL、sidebar active row 与 canonical identity。先做轻量收口,让用户在 resource tab / page tab 之间切换时有可测试的 active resource 状态。
## 2. 允许修改范围
- `rust/crates/mnote-web/src/routes/web_shell.rs`
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- `scripts/task457-main-editor-resource-tab-smoke.js`
- 可新增聚焦 smoke
## 3. 禁止事项
- 不实现 tab 持久化恢复。
- 不改变 Page Aggregate / local Markdown 事实源。
- 不实现完整 side group。
## 4. Checklist
- [x] resource tab 使用统一 canonical identity,优先 `resource:file:<rootUri>:<path>`
- [x] 激活 resource tab 时写入可测试 URL state 或 history state,不触发整页导航。
- [x] 切回 page tab 时清除 active resource state。
- [x] sidebar file tree 对应 resource row 能显示 active 状态或至少暴露稳定 DOM 标记。
- [x] page tab / resource tab 切换后不会卡死在 resource tab`task457` 继续覆盖。
## 5. 验收
- [x] `node --check scripts/task457-main-editor-resource-tab-smoke.js`
- [x] `node scripts/task457-main-editor-resource-tab-smoke.js`
- [x] `cargo test -p mnote-web web_shell -- --test-threads=1`
## 5.1 本轮执行记录
- 已合入:resource tab 激活时写入 `resourceTab=<canonical identity>` URL state,切回 page tab 或关闭全部资源 tab 时清除。
- 已合入:对应 filetree row 已渲染时只设置 `data-active=true`,不污染 `data-selected` 多选状态。
- 已验证:`task457` 覆盖 resource tab、Office tab、new-window、关闭回退和 URL state 清理。
## 6. 非目标
- 不做跨刷新恢复。
- 不做多 editor group。
@@ -106,3 +106,10 @@ local office 可进入主编辑区 tabConvex office 仍可能新窗口;mind
- `design/05-editor-mainline/process/5-19-resource-open-resolver-and-onlyoffice-checklist-v1.md`
- `design/04-tree-domain/process/4-39-filetree-open-target-resource-identity-checklist-v1.md`
- `design/04-tree-domain/process/4-40-resource-lifecycle-command-cutover-smoke-checklist-v1.md`
第三轮继续收口剩余 P0,并在 P0 清零后推进相邻 P1:
- `design/05-editor-mainline/process/5-20-resource-tab-close-confirm-checklist-v1.md`
- `design/04-tree-domain/process/4-41-filetree-bulk-resource-command-cutover-v1.md`
- `design/04-tree-domain/process/4-42-filetree-open-target-rooturi-contract-v1.md`
- `design/05-editor-mainline/process/5-21-editor-tab-url-active-identity-checklist-v1.md`