# 容器内 App 手动排序专题讨论纪要 ## 用户目标 - 用户希望在容器中,每个 App 的位置可以拖动,改变默认显示顺序。 - 本轮要求拉 2 个架构师、1 个代码审核员、1 个 QA 做专题讨论,评估可行性、开发风险和最优方案。 ## 参与视角 - 架构师 A:数据模型、分类方案、导入导出、SmartStart 影响。 - 架构师 B:App Grid / 容器视图 / 拖拽交互。 - 代码审核员:风险、必须避免的实现方式、代码切分。 - QA:验收矩阵、自动化与人工验证边界。 ## 关键结论 - 功能可做,但不能只做 UI 数组重排;必须把容器内 App 顺序持久化到 `TagDatabase.Store`。 - 当前 App 默认顺序来自扫描后名称排序,`AppIndexer.group()` 只负责分组,组内顺序没有用户字段。 - 推荐新增 `containerAppOrder: [String: [String]]`,按稳定容器 ID 保存每个容器内的 app path 顺序。 - 容器 ID 不能使用本地化显示名;建议使用 `tag:`、`system:`、`__container.uncategorized`、`__container.appleBuiltIn` 等稳定 key。 - 新字段必须纳入分类方案快照、导出、导入、恢复、SmartStart 回滚;否则“分类与布局”导出会丢布局。 - 第一版只支持同一容器内拖动排序;跨容器移动/复制标签、拖到空白移除标签、Apple 内置保护等旧行为保持不变。 - 不建议使用 SwiftUI `onDrag/onDrop`。当前 App Grid 是 AppKit `NSViewRepresentable` + 自定义拖拽,拖拽排序应在 `AppGridCollectionView` / `AppGridGroupCardView` / `AppGridIconNSView` 链路扩展。 ## 推荐开发切分 1. 数据层: - `Store` 增加 `containerAppOrder`,兼容旧 JSON。 - 增加容器 ID helper 和排序 helper。 - `CategorySchemeFingerprint` 纳入顺序字段。 - 导入、导出、恢复、未分类重置、SmartStart replace、tag rename/delete/relocalize 清理或迁移顺序。 2. UI hit-test: - `AppGridCollectionView` 增加同容器插入位置计算。 - 排序拖拽与现有跨 tag 移动/复制拖拽隔离。 - 先做本地预览,不落盘,不改跨容器行为。 3. 集成: - `ContentView` 增加 reorder callback。 - drop/end 时保存该容器完整顺序。 - 刷新 `displayGroups` 后顺序保持。 4. QA: - 旧 JSON 兼容、新 JSON roundtrip、导入导出、恢复、重置、SmartStart 数据断言。 - macOS 14 typecheck/build metadata/window logic/Quick Search/SmartStart 现有回归。 - 真实鼠标拖拽、滚动拖拽、显示模式、标签位置、编辑模式必须人工 smoke。 ## 风险评估 - 最小方案风险:中等。 - 若一次性支持跨容器插入、跨机器稳定匹配、复杂拖拽 payload、所有显示模式完整预览,风险升为高。 - 最大风险点: - 刷新/重启后顺序丢失。 - 导入导出/恢复/SmartStart 漏掉顺序。 - 同容器排序误触发跨容器移动、复制、移除标签确认。 - 用本地化显示名做 key 导致语言切换后顺序错位。 - 编辑模式、tag 拖拽排序、hover bubble、滚动抑制互相冲突。 ## 建议决策 - 先做低风险 spike:只做同容器排序,path-based 顺序持久化,所有 display mode 读取排序,但第一版优先在容器/网格容器拖拽入口验证。 - 暂不改 Quick Search 排名,不改 `appTags` 语义,不存像素坐标/IndexPath,不把顺序放 UserDefaults。