修复: IPC update_project/task 实体校验(false→Err 治假成功)+ status 白名单确认(B-260801-01)

This commit is contained in:
lxy
2026-08-01 16:04:31 +08:00
parent 8c0ff80cd4
commit 7193901bc4
2 changed files with 29 additions and 4 deletions
+12 -1
View File
@@ -299,6 +299,13 @@ pub async fn get_project(
}
/// 更新项目单个字段(字段名走 df-storage 白名单校验)
///
/// B-260801-01(P0-1):0 行(id 不存在 / 已软删)→ 返 Err 而非假成功。原实现无视
/// update_field 返回值恒返 Ok(true),前端误以为成功但库无变更(UI/DB 不一致)。
///
/// 返回值保持 bool(成功恒 true):前端 api 包装 `Promise<boolean>` 契约不变零破坏,
/// title 不在 IPC 返回值——IPC 调用点(projects store)不展示带返回值的 toast,
/// title 仅供 AI 工具卡片路径(ai/tools/project.rs),IPC 路径返 title 为冗余。
#[tauri::command]
pub async fn update_project(
state: State<'_, AppState>,
@@ -306,11 +313,15 @@ pub async fn update_project(
field: String,
value: String,
) -> Result<bool, String> {
state
// B-260801-01(P0-1):update_field 返 affected>0;false = id 不存在或已软删(0 行)。
let updated = state
.projects
.update_field(&id, &field, &value)
.await
.map_err(err_str)?;
if !updated {
return Err(format!("项目 ID {id} 不存在或已删除"));
}
// F-260620: path 字段变更后立即 reload 白名单(新绑定/重绑目录即时生效,防 AI 误弹窗)
if field == "path" {
state.reload_allowed_dirs().await;
+17 -3
View File
@@ -330,7 +330,15 @@ pub async fn create_task(
Ok(record)
}
/// 更新任务单个字段(字段名走 df-storage 白名单校验;status 值走枚举校验)
/// 更新任务单个字段(字段名走 df-storage 白名单校验;status 值走枚举校验)
///
/// B-260801-01(P0-1):0 行(id 不存在 / 已软删)→ 返 Err 而非 false,杜绝「假成功」
/// (前端 updateTask 仅 await 不读 bool,但 store.runWithCatch 把 Err 转 toast,用户能感知;
/// 若返 false 则 store 静默忽略,本地状态前端手动改但库无变更,造成 UI 与 DB 不一致)。
///
/// 返回值保持 bool(成功恒 true):前端 api 包装 `Promise<boolean>` 契约不变零破坏,
/// title 不在 IPC 返回值——IPC 唯一调用点(Tasks.vue 优先级改)不展示带返回值的 toast,
/// title 仅供 AI 工具卡片路径(已修见 ai/tools/task.rs),IPC 路径返 title 为冗余。
#[tauri::command]
pub async fn update_task(
state: State<'_, AppState>,
@@ -398,11 +406,17 @@ pub async fn update_task(
}
// 空字符串 = None(解除父),合法放行
}
state
// B-260801-01(P0-1):update_field 返 affected>0;false = id 不存在或已软删(0 行)。
// 不可静默返 false——前端 store.runWithCatch 把 Err 转 toast,而 false 会被忽略致假成功。
let updated = state
.tasks
.update_field(&id, &field, &value)
.await
.map_err(err_str)
.map_err(err_str)?;
if !updated {
return Err(format!("任务 ID {id} 不存在或已删除"));
}
Ok(true)
}
/// 删除任务(软删 → 回收站,可恢复)。对标 delete_project(SET deleted_at=now)。