# 4-43 Local Folder Sort Order Persistence Checklist v1

> 状态：done
>
> 归档说明（2026-05-21）：local folder sort order 持久化、projection 消费与浏览器 smoke 均已完成。
>
> 日期：2026-05-20
>
> Owner：local folder tree command / file tree projection ordering

## 1. 目标

补齐 P1：`local_folder` 的 `move` 当前只把 `sortOrder` 回显到 `_unsupportedFields`，不能形成拖拽排序后的持久顺序语义。目标是在不引入第二套 UI 真相的前提下，让本地文件夹排序通过本地 metadata 持久化，并被 file tree / page tree projection 消费。

## 2. 允许修改范围

- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
- `rust/crates/mnote-web/src/routes/tree.rs` 中仅限合同测试或调用透传
- 可新增聚焦 smoke：`scripts/task47*-local-folder-sort-order-*.js`

## 3. 禁止事项

- 不通过重命名文件前缀实现排序。
- 不把排序真相放到前端 DOM 或 localStorage。
- 不改变 Markdown 页面正文事实源。
- 不改变垃圾箱、restore、purge 的既有路径语义。

## 4. Checklist

- [x] 本地 metadata 增加可持久化排序记录，按 parent/container 维度表达子项顺序。
- [x] `move` 带 `sortOrder` 时写入排序记录，不再返回 `_unsupportedFields.sortOrder`。
- [x] projection 读取排序记录并稳定排序，未记录项继续按现有自然排序兜底。
- [x] rename / move / archive / restore 后排序记录不会留下明显悬挂项或破坏 projection。
- [x] Rust 合同测试覆盖 move sortOrder 持久化、重新加载 snapshot 后顺序保持。
- [x] 如涉及可见行为，补 browser/API smoke 验证排序后重新加载 projection 不回退。

## 5. 验收

- [x] `cargo test -p mnote-web local_tree_command_move_with_sort_order -- --test-threads=1`
- [x] `cargo test -p mnote-web tree_command_local_folder -- --test-threads=1`
- [x] 如新增 smoke：`node scripts/task472-local-folder-sort-order-persistence-smoke.js`

## 5.1 本轮执行记录

- 已合入：`.mnote/file-order.json` 按 parent relative path 记录子项相对路径顺序，projection 扫描时消费该顺序。
- 已退役：`_unsupportedFields.sortOrder` 合同测试，改为持久化顺序和 snapshot 顺序断言。
- 已合入：rename / archive / purge 对 file-order path 做 rewrite / remove，restore 回到文件系统自然排序或原 parent 现有顺序。
- 本轮补齐：`scripts/task472-local-folder-sort-order-persistence-smoke.js` 使用隔离 tmp root，经 `/api/tree/commands` 执行 local_folder `move sortOrder`，再通过 `/api/tree/projections/file` 重拉 projection，验证刷新/重新加载后顺序不回退。
- 执行记录：`node --check scripts/task472-local-folder-sort-order-persistence-smoke.js` 通过；`node scripts/task472-local-folder-sort-order-persistence-smoke.js` 在本地 `http://127.0.0.1:3000` 服务可用时通过。

## 6. 非目标

- 不实现跨设备 sync 的排序冲突合并。
- 不实现完整 VSCode Explorer sort comparator 配置。
