diff --git a/src-tauri/src/commands/ai/audit/data_change.rs b/src-tauri/src/commands/ai/audit/data_change.rs new file mode 100644 index 0000000..92ee7ff --- /dev/null +++ b/src-tauri/src/commands/ai/audit/data_change.rs @@ -0,0 +1,50 @@ +//! AR-11(方案A):数据变更联动刷新。 +//! +//! 工具执行成功后按映射 emit "df-data-changed" { entity, action }, +//! 前端 store listen 该事件按 entity 调 loadProjects/loadTasks/loadIdeas 刷新列表, +//! 取代工具执行后需手动刷新。 +//! +//! 第四批从 audit/mod.rs 抽离,行为零变更。 + +use tauri::{AppHandle, Emitter}; + +/// AR-11(方案A):工具名 → (entity, action) 映射,用于数据变更联动刷新。 +/// +/// 仅数据变更类工具返回 Some,其余工具返回 None(不 emit df-data-changed)。 +/// 映射规则: +/// - create_project/create_idea/create_task → (project/idea/task, create) +/// - update_project/update_task/update_idea → (..., update) +/// - delete_project/delete_task/delete_idea/purge_project → (..., delete) +/// - restore_project → (project, update)(恢复等同状态变更,前端走 update 刷新) +/// - bind_directory → (project, update)(绑定目录属项目字段更新) +pub(super) fn data_change_for_tool(name: &str) -> Option<(&'static str, &'static str)> { + let (entity, action) = match name { + "create_project" => ("project", "create"), + "create_task" => ("task", "create"), + "create_idea" => ("idea", "create"), + "update_project" => ("project", "update"), + "update_task" => ("task", "update"), + "update_idea" => ("idea", "update"), + "delete_project" | "purge_project" => ("project", "delete"), + "delete_task" => ("task", "delete"), + "delete_idea" => ("idea", "delete"), + "restore_project" => ("project", "update"), + "bind_directory" => ("project", "update"), + _ => return None, + }; + Some((entity, action)) +} + +/// AR-11(方案A):工具执行成功后按映射 emit "df-data-changed" { entity, action }。 +/// +/// 前端 store listen 该事件,按 entity 调 loadProjects/loadTasks/loadIdeas 刷新列表, +/// 取代工具执行后需手动刷新。仅工具名命中 data_change_for_tool 映射才 emit, +/// 其余工具(run_workflow/list_tasks 等)不 emit。emit 失败不阻断(let _ =)。 +pub(crate) fn emit_data_changed(app_handle: &AppHandle, tool_name: &str) { + if let Some((entity, action)) = data_change_for_tool(tool_name) { + let _ = app_handle.emit( + "df-data-changed", + serde_json::json!({ "entity": entity, "action": action }), + ); + } +} diff --git a/src-tauri/src/commands/ai/audit/mod.rs b/src-tauri/src/commands/ai/audit/mod.rs index f67cbaa..653074a 100644 --- a/src-tauri/src/commands/ai/audit/mod.rs +++ b/src-tauri/src/commands/ai/audit/mod.rs @@ -129,53 +129,18 @@ pub use restore::restore_pending_approvals; mod finalize; pub(crate) use finalize::{audit_finalize, audit_tool_call}; -/// AR-11(方案A):工具名 → (entity, action) 映射,用于数据变更联动刷新。 -/// -/// 仅数据变更类工具返回 Some,其余工具返回 None(不 emit df-data-changed)。 -/// 映射规则: -/// - create_project/create_idea/create_task → (project/idea/task, create) -/// - update_project/update_task/update_idea → (..., update) -/// - delete_project/delete_task/delete_idea/purge_project → (..., delete) -/// - restore_project → (project, update)(恢复等同状态变更,前端走 update 刷新) -/// - bind_directory → (project, update)(绑定目录属项目字段更新) -fn data_change_for_tool(name: &str) -> Option<(&'static str, &'static str)> { - let (entity, action) = match name { - "create_project" => ("project", "create"), - "create_task" => ("task", "create"), - "create_idea" => ("idea", "create"), - "update_project" => ("project", "update"), - "update_task" => ("task", "update"), - "update_idea" => ("idea", "update"), - "delete_project" | "purge_project" => ("project", "delete"), - "delete_task" => ("task", "delete"), - "delete_idea" => ("idea", "delete"), - "restore_project" => ("project", "update"), - "bind_directory" => ("project", "update"), - _ => return None, - }; - Some((entity, action)) -} - -/// AR-11(方案A):工具执行成功后按映射 emit "df-data-changed" { entity, action }。 -/// -/// 前端 store listen 该事件,按 entity 调 loadProjects/loadTasks/loadIdeas 刷新列表, -/// 取代工具执行后需手动刷新。仅工具名命中 data_change_for_tool 映射才 emit, -/// 其余工具(run_workflow/list_tasks 等)不 emit。emit 失败不阻断(let _ =)。 -pub(crate) fn emit_data_changed(app_handle: &AppHandle, tool_name: &str) { - if let Some((entity, action)) = data_change_for_tool(tool_name) { - let _ = app_handle.emit( - "df-data-changed", - serde_json::json!({ "entity": entity, "action": action }), - ); - } -} - // cache(audit/cache.rs):F-260616-05 高危工具去重缓存。 // 第三批从本文件抽离,行为零变更。pub(super) use 供本文件 process_tool_calls 裸名调用 // (find_cached_high_risk_result),PENDING_APPROVAL_PLACEHOLDER 供 process_tool_calls 占位回填共享。 mod cache; pub(super) use cache::{find_cached_high_risk_result, PENDING_APPROVAL_PLACEHOLDER}; +// data_change(audit/data_change.rs):AR-11 数据变更联动刷新。 +// 第四批从本文件抽离,行为零变更。pub(crate) use 保持 emit_data_changed 对 crate 内可见 +// (chat.rs 通过 commands::ai::audit::emit_data_changed 引入并调用),data_change_for_tool 私有。 +mod data_change; +pub(crate) use data_change::emit_data_changed; + /// AE-2025-03(路径 B):write_file 审批预览 diff 生成。 /// /// 从 write_file args 取 path(旧文件路径)+ content(新内容),