# v4.1 Bug 修复与代码清理 — 设计文档

**日期**: 2026-05-26
**分支**: v4.1
**状态**: 已确认

## 概述

修复代码审查中发现的 3 个 bug 和 7 个代码质量问题。

---

## Bug 修复

### B1. 非连续删除 undo 位置错误

**问题**: `deletePaths([0, 3])` 后 undo 将路径恢复到位置 0、1，而非 0、3。

**修复**: `OpRecord` 新增 `indices: number[]` 字段。DELETE 操作存储已排序的原始 indices。undo 时按 indices 逐个 `splice` 恢复。redo 时按 indices 从后往前删除。

边角情况：原有连续删除的逻辑不变，indices 为 `[1,2,3]` 时效果与 `index=1, count=3` 一致。

### B2. 备份时机错误

**问题**: `backup_registry` 接收前端传来的新值（即将写入的值）做备份，而非当前注册表中的真实值。且 backup 和 save 并发执行无顺序保证。

**修复**: `backup_registry` 不再接收 paths 参数，改为内部调用 `load_paths()` 读取注册表当前值后写入备份。前端调用简化为 `invoke('backup_registry')`。`split_path`/`join_path` 改为 `pub(crate)` 供 backup 模块复用。

### B3. 验证异常返回"有效"

**问题**: `PathTable.tsx` 中 IPC 调用 `validate_path` 失败时 catch 返回 `[p, true]`，不存在的路径被标为绿色。

**修复**: 验证缓存类型从 `Map<string, boolean>` 改为 `Map<string, 'valid' | 'invalid' | 'unknown'>`。IPC 异常时存 `'unknown'`，UI 渲染为默认色（不标绿也不标红）。

---

## 代码清理

### C1. 删除 AppError 死代码

删除 `src-tauri/src/error.rs`，移除 `lib.rs` 中的 `mod error`。

理由：全部 IPC 命令使用 `Result<T, String>`，`AppError` 从未被使用且被 `#[allow(dead_code)]` 压制。

### C2. importPaths 重命名为 replacePaths

函数行为是全量替换列表而非追加，名字应诚实。

### C3. detectExportFormat 修正

返回类型从 `'json' | 'csv'` 改为 `'json' | 'csv' | 'txt'`。TXT 文件不再被归类为 JSON。

### C4. _markDirty 收窄可见性

从 AppState 接口移除 `_markDirty`，改为 store 闭包内的模块级私有函数。CRUD 方法通过闭包直接调用。

### C5. PATH 长度阈值统一

`default.json` 中的 `maxSystemLength`/`maxUserLength` 从 2048 改为 32767，与 Rust 端 `MAX_PATH_LEN` 一致。

---

## 优化

### O1. BOM 只在首行检查

`importFromCsv` 和 `importFromTxt` 中 BOM 检查移到循环外，仅处理第一行。

### O2. split_path 重复提醒

在 Rust `registry.rs` 和 TS `validation.ts` 的 `split_path` 函数处各加一行注释，提醒修改时同步两端。
