use crate::context::BridgeContext; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConvexMutationRequest { pub function_name: String, pub deployment_id: Option, pub project_id: Option, pub workspace_id: Option, pub request_id: String, pub trace_id: String, pub idempotency_key: Option, pub actor_id: String, pub payload_json: String, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConvexQueryRequest { pub function_name: String, pub deployment_id: Option, pub project_id: Option, pub workspace_id: Option, pub request_id: String, pub trace_id: String, pub actor_id: String, pub payload_json: String, } pub fn map_command_name_to_convex(command_name: &str) -> &'static str { match command_name { "create_workspace" => "workspaces:create", "create_page" => "pages:create", "kernel.node.create" => "kernel:createNode", "kernel.node.update" => "kernel:updateNode", "kernel.subtree.move" => "kernel:moveSubtree", "kernel.edge.attach" => "kernel:attachEdge", "kernel.edge.detach" => "kernel:detachEdge", "tree.node.create" => "documents:createWithParentReference", "tree.node.rename" => "documents:updateTitle", "tree.node.archive" => "documents:softDelete", "tree.node.restore" => "documents:restore", "tree.node.purge" => "documents:purge", "tree.trash.emptyWorkspace" => "documents:emptyTrashByWorkspace", "tree.subtree.move" => "documents:move", "tree.subtree.copy" => "documents:copyTree", "tree.resource.copy" => "mediaAssets:batchCopy", "tree.resource.move" => "mediaAssets:batchMove", "tree.resource.upload" => "mediaAssets:createWithStorage", "tree.resource.archive" => "mediaAssets:patchById", "tree.resource.restore" => "mediaAssets:patchById", "tree.resource.purge" => "mediaAssets:purgeById", "tree.resource.rename" => "mediaAssets:patchById", "tree.filetree.drop.preflight" => "tree:fileTreeDropPreflight", "tree.filetree.delete.preflight" => "tree:fileTreeDeletePreflight", "tree.filetree.paste.preflight" => "tree:fileTreePastePreflight", "tree.filetree.upload-target.preflight" => "tree:fileTreeUploadTargetPreflight", "tree.node.embed" => "documents:updateContent", "documents.create" => "documents:createWithParentReference", "documents.move" => "documents:move", "documents.delete" => "documents:softDelete", "documents.restore" => "documents:restore", "documents.duplicate" => "documents:duplicateWithMindmaps", "documents.copy_tree" => "documents:copyTree", "documents.template" => "documents:setTemplate", "documents.emptyTrashByWorkspace" => "documents:emptyTrashByWorkspace", "documents.purge" => "documents:purge", "documents.embed" => "documents:updateContent", "blocks.patch" => "documents:updateContent", "documents.save" => "documents:updateContent", "page.body.save" => "documents:updateContent", "documents.title.update" => "documents:updateTitle", "page.head.updateTitle" => "documents:updateTitle", "documents.stats.update" => "documents:updateStats", "documents.options.update" => "documents:updateOptions", "page.layout.updateOptions" => "documents:updateOptions", "mindmaps.put" => "mindmaps:put", "mindmap.command.apply" => "mindmaps:applyCommand", "mindmaps.delete" => "mindmaps:softDelete", "mindmaps.restore" => "mindmaps:restore", "mindmaps.purge" => "mindmaps:purge", "mindmaps.emptyTrashByWorkspace" => "mindmaps:emptyTrashByWorkspace", "insert_block" => "blocks:insert", "update_block" => "blocks:update", "move_block" => "blocks:move", "delete_block" => "blocks:delete", "blocks.move" => "blocks:move", "blocks.embed" => "blocks:insert", "media.assets.replace_storage" => "mediaAssets:replaceStorageFromUpload", _ => "commands:unknown", } } pub fn map_query_name_to_convex(query_name: &str) -> &'static str { match query_name { "kernel.node.get" => "kernel:getNode", "kernel.subtree.get" => "kernel:getSubtree", "kernel.children.list" => "kernel:listChildren", "kernel.edges.list" => "kernel:listEdges", "kernel.graph.traverse" => "kernel:traverseGraph", "kernel.project_view" => "kernel:projectView", "bridge.request.get" => "bridgeLogs:listByRequest", "bridge.trace.get" => "bridgeLogs:listByTrace", "bridge.command.get" => "bridgeLogs:listByCommand", "bridge.workspace.overview" => "bridgeLogs:listWorkspaceOverview", "documents.meta.get" => "documents:getMeta", "documents.content.get" => "documents:getContent", // page aggregate 主读链由 Rust /api/page-aggregate/:id 先取 meta/content 后在 bridge-runtime 组装。 // Convex 没有 documents:getPageAggregate,避免旧映射误触发不存在的生产函数。 "page.aggregate.get" => "queries:unknown", "mindmaps.get" => "mindmaps:get", "mindmap.projection.get" => "mindmaps:getProjection", "mindmap.editor_scene.get" => "mindmaps:getEditorScene", "blocks.get" => "blocks:getById", "sidebar.dataset.list" => "sidebar:datasetList", "search.documents" => "search:documents", "search.documents.query" => "search:documents", "search.recent" => "search:recent", "get_page" => "pages:get", "list_page_blocks" => "blocks:list_by_page", "search_pages" => "search:pages", "search_blocks" => "search:blocks", _ => "queries:unknown", } } fn json_opt(value: &Option) -> String { match value { Some(v) => format!("\"{}\"", v), None => "null".into(), } } pub fn payload_json_for_command(context: &BridgeContext, command_name: &str) -> String { format!( "{{\"kind\":\"command\",\"name\":\"{}\",\"request_id\":\"{}\",\"trace_id\":\"{}\",\"deployment_id\":{},\"project_id\":{},\"workspace_id\":{},\"tenant_id\":{},\"idempotency_key\":{},\"actor\":{{\"type\":\"{}\",\"id\":\"{}\",\"session_id\":{}}},\"source\":{{\"channel\":\"{}\",\"client\":\"{}\"}}}}", command_name, context.request_id, context.trace_id, json_opt(&context.deployment_id), json_opt(&context.project_id), json_opt(&context.workspace_id), json_opt(&context.tenant_id), json_opt(&context.idempotency_key), context.actor_type, context.actor_id, json_opt(&context.session_id), context.source_channel, context.source_client, ) } pub fn payload_json_for_query(context: &BridgeContext, query_name: &str) -> String { format!( "{{\"kind\":\"query\",\"name\":\"{}\",\"request_id\":\"{}\",\"trace_id\":\"{}\",\"deployment_id\":{},\"project_id\":{},\"workspace_id\":{},\"tenant_id\":{},\"actor_id\":\"{}\",\"source\":{{\"channel\":\"{}\",\"client\":\"{}\"}}}}", query_name, context.request_id, context.trace_id, json_opt(&context.deployment_id), json_opt(&context.project_id), json_opt(&context.workspace_id), json_opt(&context.tenant_id), context.actor_id, context.source_channel, context.source_client, ) }