20260513 mindmap优化01
This commit is contained in:
@@ -8,6 +8,7 @@ use bridge_runtime::{
|
||||
};
|
||||
use serde_json::{json, Value};
|
||||
use std::fs;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
|
||||
|
||||
@@ -19,6 +20,32 @@ const HEADER_SOURCE_CLIENT: &str = "x-mnote-source-client";
|
||||
const HEADER_IDEMPOTENCY_KEY: &str = "x-idempotency-key";
|
||||
const COOKIE_MNOTE_WEB_CONVEX_TOKEN: &str = "mnote_web_convex_token";
|
||||
const COOKIE_CONVEX_AUTH_JWT: &str = "__convexAuthJWT";
|
||||
static CONVEX_HTTP_CLIENT: OnceLock<reqwest::Client> = OnceLock::new();
|
||||
|
||||
fn convex_http_client(context: &RequestContext) -> Result<&'static reqwest::Client, WebError> {
|
||||
if let Some(client) = CONVEX_HTTP_CLIENT.get() {
|
||||
return Ok(client);
|
||||
}
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(20))
|
||||
.pool_max_idle_per_host(16)
|
||||
.pool_idle_timeout(Duration::from_secs(30))
|
||||
.build()
|
||||
.map_err(|error| {
|
||||
WebError::internal(format!("Convex HTTP 客户端创建失败: {error}"))
|
||||
.with_context(context)
|
||||
.with_header("x-error-phase", "client_build")
|
||||
.with_header("x-upstream-service", "convex")
|
||||
})?;
|
||||
let _ = CONVEX_HTTP_CLIENT.set(client);
|
||||
CONVEX_HTTP_CLIENT.get().ok_or_else(|| {
|
||||
WebError::internal("Convex HTTP 客户端初始化失败")
|
||||
.with_context(context)
|
||||
.with_header("x-error-phase", "client_build")
|
||||
.with_header("x-upstream-service", "convex")
|
||||
})
|
||||
}
|
||||
|
||||
fn read_env_or_dotenv(key: &str) -> Option<String> {
|
||||
if let Ok(value) = std::env::var(key) {
|
||||
@@ -232,15 +259,7 @@ pub async fn execute_convex_query_plan(
|
||||
"args": plan.args_json,
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(20))
|
||||
.build()
|
||||
.map_err(|error| {
|
||||
WebError::internal(format!("Convex HTTP 客户端创建失败: {error}"))
|
||||
.with_context(context)
|
||||
.with_header("x-error-phase", "client_build")
|
||||
.with_header("x-upstream-service", "convex")
|
||||
})?;
|
||||
let client = convex_http_client(context)?;
|
||||
|
||||
let mut request = client
|
||||
.post(format!("{}/api/query", convex_url(config, context)?))
|
||||
@@ -357,6 +376,18 @@ pub async fn execute_convex_query_by_name(
|
||||
|
||||
fn convex_command_args_for_plan(plan: &RuntimeCommandExecutionPlan) -> Value {
|
||||
let mut args = plan.args_json.clone();
|
||||
if matches!(plan.command_name.as_str(), "mindmaps.put")
|
||||
|| matches!(plan.function_name.as_str(), "mindmaps:put")
|
||||
{
|
||||
if let Value::Object(map) = &mut args {
|
||||
// Rust plan 保留 tree domain event / stream hint 作为正式契约;
|
||||
// Convex mindmaps.put legacy validator 仍只接收真实写入字段。
|
||||
map.remove("streamDeltaHint");
|
||||
map.remove("domainEventHint");
|
||||
map.remove("domainEventPlan");
|
||||
map.remove("domainEventPlans");
|
||||
}
|
||||
}
|
||||
if matches!(
|
||||
plan.command_name.as_str(),
|
||||
"documents.save" | "page.body.save"
|
||||
@@ -414,15 +445,7 @@ pub async fn execute_convex_command_plan(
|
||||
"args": [convex_command_args_for_plan(plan)],
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(20))
|
||||
.build()
|
||||
.map_err(|error| {
|
||||
WebError::internal(format!("Convex HTTP 客户端创建失败: {error}"))
|
||||
.with_context(context)
|
||||
.with_header("x-error-phase", "client_build")
|
||||
.with_header("x-upstream-service", "convex")
|
||||
})?;
|
||||
let client = convex_http_client(context)?;
|
||||
|
||||
let mut request = client
|
||||
.post(format!("{}/api/mutation", convex_url(config, context)?))
|
||||
@@ -550,15 +573,7 @@ pub async fn execute_convex_mutation_by_name(
|
||||
"args": [args],
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(20))
|
||||
.build()
|
||||
.map_err(|error| {
|
||||
WebError::internal(format!("Convex HTTP 客户端创建失败: {error}"))
|
||||
.with_context(context)
|
||||
.with_header("x-error-phase", "client_build")
|
||||
.with_header("x-upstream-service", "convex")
|
||||
})?;
|
||||
let client = convex_http_client(context)?;
|
||||
|
||||
let mut request = client
|
||||
.post(format!("{}/api/mutation", convex_url(config, context)?))
|
||||
@@ -847,6 +862,44 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convex_command_args_strips_mindmap_put_bridge_artifacts_for_legacy_mutation() {
|
||||
let plan = RuntimeCommandExecutionPlan {
|
||||
command_name: "mindmaps.put".into(),
|
||||
command_id: "cmd_mindmap_put_1".into(),
|
||||
function_name: "mindmaps:put".into(),
|
||||
workspace_id: Some("ws_1".into()),
|
||||
request_id: "req_1".into(),
|
||||
trace_id: "trace_1".into(),
|
||||
actor_id: "actor_1".into(),
|
||||
idempotency_key: None,
|
||||
source: json!({}),
|
||||
payload_json: "{}".into(),
|
||||
args_json: json!({
|
||||
"docId": "doc_1",
|
||||
"mindmapId": "mind_1",
|
||||
"data": {"data": {"text": "KMIND"}, "children": []},
|
||||
"createOnly": false,
|
||||
"streamDeltaHint": {"family": "tree"},
|
||||
"domainEventHint": {"eventType": "tree.resource.mindmap.put"},
|
||||
"domainEventPlan": {"eventType": "tree.resource.mindmap.put"},
|
||||
"domainEventPlans": [{"eventType": "tree.resource.mindmap.put"}],
|
||||
}),
|
||||
};
|
||||
|
||||
let args = convex_command_args_for_plan(&plan);
|
||||
|
||||
assert_eq!(
|
||||
args,
|
||||
json!({
|
||||
"docId": "doc_1",
|
||||
"mindmapId": "mind_1",
|
||||
"data": {"data": {"text": "KMIND"}, "children": []},
|
||||
"createOnly": false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convex_command_args_adapts_mindmap_command_apply_for_legacy_mutation() {
|
||||
let plan = RuntimeCommandExecutionPlan {
|
||||
|
||||
Reference in New Issue
Block a user