优化: 清理无意义注释(走查编号前缀/过时历史标注/死代码注释)
This commit is contained in:
@@ -152,7 +152,7 @@ where
|
||||
let resp = dispatch(ctx, config.read_only, req.id.clone(), method).await;
|
||||
write_response(&mut writer, &resp).await?;
|
||||
if let Some(name) = tool_name {
|
||||
// MC-5(MCP-6):仅业务成功才触发写回调——防业务失败(如 update_project 非法 status、
|
||||
// MC-5仅业务成功才触发写回调——防业务失败(如 update_project 非法 status、
|
||||
// create_project 空名等 result.isError=true)仍假触发 df-data-changed。
|
||||
if is_success_tool_call(&resp) {
|
||||
fire_write_hook(config, &name);
|
||||
@@ -169,7 +169,7 @@ where
|
||||
/// - `result` 内 `isError=true`(MCP 业务错,handler 返 `CallToolResult::error`)→ 失败
|
||||
/// - 其余(正常 result / initialize/ping 等非 tools/call)→ 成功
|
||||
///
|
||||
/// MC-5(MCP-6):stdio(main_loop)与 HTTP(server_http on_tool_call)共用此判定,
|
||||
/// stdio(main_loop)与 HTTP(server_http on_tool_call)共用此判定,
|
||||
/// 保证两 transport 对「业务失败不触发写回调」语义一致。
|
||||
pub(crate) fn is_success_tool_call(resp: &Response) -> bool {
|
||||
if resp.error.is_some() {
|
||||
@@ -651,7 +651,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn main_loop_no_write_callback_on_business_failure() {
|
||||
// MC-5(MCP-6):业务失败(handler 返 isError=true)不得触发写回调(防假 df-data-changed)。
|
||||
// MC-5业务失败(handler 返 isError=true)不得触发写回调(防假 df-data-changed)。
|
||||
// create_project 空名(name 为纯空白)→ MC-6 拒空 → isError=true。
|
||||
let ctx = test_ctx().await;
|
||||
let calls: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
@@ -163,7 +163,7 @@ async fn handle_body(state: &McpHttpState, body: &[u8]) -> Outcome {
|
||||
let resp = dispatch(&state.ctx, state.read_only, req.id.clone(), method).await;
|
||||
|
||||
// ⑥ 成功 tools/call(JSON-RPC 无 error 且 result.isError≠true)→ on_tool_call 回调
|
||||
// (桌面端据此刷新 GUI)。MC-5/MCP-6:业务失败(handler 返 isError=true)不触发,
|
||||
// (桌面端据此刷新 GUI)。MC-5/业务失败(handler 返 isError=true)不触发,
|
||||
// 防假 df-data-changed;与 stdio fire_write_hook 共用 is_success_tool_call,两 transport 统一。
|
||||
if crate::server::is_success_tool_call(&resp) {
|
||||
if let (Some(name), Some(cb)) = (tool_name, &state.on_tool_call) {
|
||||
|
||||
+10
-10
@@ -247,7 +247,7 @@ fn check_expected_updated_at(args: &Value, db_updated_at: &str) -> Result<(), Ca
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 跨实体校验(防 B-260801-01:跨实体误操作)
|
||||
// 跨实体校验(防 跨实体误操作)
|
||||
// ============================================================
|
||||
//
|
||||
// 各实体表(projects / tasks / ideas)独立存储,Repo::get_by_id 只查本表。
|
||||
@@ -352,7 +352,7 @@ fn create_project(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
Ok(v) => v,
|
||||
Err(r) => return Box::pin(std::future::ready(r)),
|
||||
};
|
||||
// MC-6(MCP-4):name trim + 拒空(对齐 GUI create_with_binding / ProjectManager::create,
|
||||
// name trim + 拒空(对齐 GUI create_with_binding / ProjectManager::create,
|
||||
// 防空白项目名进库——required 只保证传参,不保证非空白)。
|
||||
let name = name.trim().to_string();
|
||||
if name.is_empty() {
|
||||
@@ -406,7 +406,7 @@ fn update_project(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
let existing = match repo.get_by_id(&id).await {
|
||||
Ok(Some(p)) => p,
|
||||
Ok(None) => {
|
||||
// 跨实体校验(B-260801-01):id 可能属于 task/idea,给精确错误防误操作
|
||||
// 跨实体校验id 可能属于 task/idea,给精确错误防误操作
|
||||
if let Some(msg) = cross_entity_err(&db, &id, "project").await {
|
||||
return CallToolResult::error(msg);
|
||||
}
|
||||
@@ -421,7 +421,7 @@ fn update_project(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
// 部分更新:name/description 缺省回退 existing,避免空默认清空数据
|
||||
let name = arg_str(&args, "name").unwrap_or_else(|_| existing.name.clone());
|
||||
let description = arg_str(&args, "description").unwrap_or_else(|_| existing.description.clone());
|
||||
// MC-1(MCP-1):status 不再写入——移除 status 参数对 DB 的影响,保留原值(对齐 update_task
|
||||
// status 不再写入——移除 status 参数对 DB 的影响,保留原值(对齐 update_task
|
||||
// 收口思路:status 是生命周期状态,不经 update_project 旁路改写,防制造 GUI 不可能的非法跳态)。
|
||||
// 客户端传 status 参数被静默忽略(保留原值);项目状态变更走专用流转路径。
|
||||
let status = existing.status;
|
||||
@@ -517,7 +517,7 @@ fn bind_directory(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult>
|
||||
Ok(false) => return CallToolResult::error(format!("项目不存在: {id}")),
|
||||
Err(e) => return err_str(e),
|
||||
}
|
||||
// MC-6(MCP-2):两步写降级——stack 写失败不中断绑定(path 已落库,核心目标达成)。
|
||||
// MC-6两步写降级——stack 写失败不中断绑定(path 已落库,核心目标达成)。
|
||||
// tracing::warn 记录,仍返回已绑定结果(path 已更新);GUI 侧可后续经 relocate 重探测。
|
||||
if let Err(e) = repo.update_field(&id, "stack", &stack_json).await {
|
||||
tracing::warn!(
|
||||
@@ -578,7 +578,7 @@ fn create_task(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
||||
Ok(v) => v,
|
||||
Err(r) => return Box::pin(std::future::ready(r)),
|
||||
};
|
||||
// MC-6(MCP-4):title trim + 拒空(对齐 GUI create_task BE-CMD-1,防空白标题进库)。
|
||||
// title trim + 拒空(对齐 GUI create_task BE-CMD-1,防空白标题进库)。
|
||||
let title = title.trim().to_string();
|
||||
if title.is_empty() {
|
||||
return Box::pin(std::future::ready(CallToolResult::error(
|
||||
@@ -669,7 +669,7 @@ fn update_task(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
||||
let existing = match repo.get_by_id(&id).await {
|
||||
Ok(Some(t)) => t,
|
||||
Ok(None) => {
|
||||
// 跨实体校验(B-260801-01):id 可能属于 project/idea,给精确错误防误操作
|
||||
// 跨实体校验id 可能属于 project/idea,给精确错误防误操作
|
||||
if let Some(msg) = cross_entity_err(&db, &id, "task").await {
|
||||
return CallToolResult::error(msg);
|
||||
}
|
||||
@@ -795,7 +795,7 @@ fn create_idea(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
||||
Err(r) => return Box::pin(std::future::ready(r)),
|
||||
};
|
||||
let description = arg_str_or(&args, "description", "");
|
||||
// MC-6(MCP-3):priority 值域校验(复用 df-storage normalize_priority 与 GUI/AI 工具同源,
|
||||
// priority 值域校验(复用 df-storage normalize_priority 与 GUI/AI 工具同源,
|
||||
// 拦截 99 等越界值——原 arg_int_or 直落 99 被静默吞为前端 Critical,IPC 拒/MCP 放行漂移)。
|
||||
let priority = match df_storage::crud::normalize_priority(
|
||||
args.get("priority").and_then(|v| v.as_i64()),
|
||||
@@ -845,7 +845,7 @@ fn update_idea(ctx: &Ctx, args: Value) -> BoxFuture<'static, CallToolResult> {
|
||||
let existing = match repo.get_by_id(&id).await {
|
||||
Ok(Some(i)) => i,
|
||||
Ok(None) => {
|
||||
// 跨实体校验(B-260801-01):id 可能属于 project/task,给精确错误防误操作
|
||||
// 跨实体校验id 可能属于 project/task,给精确错误防误操作
|
||||
if let Some(msg) = cross_entity_err(&db, &id, "idea").await {
|
||||
return CallToolResult::error(msg);
|
||||
}
|
||||
@@ -1451,7 +1451,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// ── 跨实体校验(B-260801-01):update_* 检测 id 属于其他实体时报精确错误 ──
|
||||
// ── 跨实体校验update_* 检测 id 属于其他实体时报精确错误 ──
|
||||
//
|
||||
// 各实体表独立,Repo::get_by_id 只查本表。当 id 实属另一实体时,
|
||||
// 旧实现只报「任务/项目/想法不存在」(误导),改后报「id 属于 X,不能用 update_Y 修改」。
|
||||
|
||||
Reference in New Issue
Block a user