收口本地工作区清理与资源投影

清理历史 Electron、Graphify、沙箱和截图等仓库跟踪残留,补充 CodeGraph 与 Convex active deploy source 协作说明。

新增 tree-first 下一阶段设计稿和 2026-05-20 清理总结,记录本地工作区、路径身份和 Zed/Lapce/VSCode 参考收口方向。

扩展 Rust Web 本地文件夹、DocumentBuffer、mindmap 资源、tree runtime 和页面聚合链路,并补充 task455 local-folder mindmap clean smoke。

验证:git diff --check 通过;pnpm store status --store-dir .pnpm-store 通过;npm ls --depth=0 --json 通过;find -L node_modules 未发现断链。cargo test -p mnote-web 当前 418 passed / 35 failed。
This commit is contained in:
lix-2026
2026-05-20 10:43:38 +08:00
parent 90818cdf75
commit b4c8bcb647
73 changed files with 8073 additions and 8240 deletions
+54
View File
@@ -82,6 +82,7 @@ impl RequestContext {
cookie_header: header_value(headers, axum::http::header::COOKIE.as_str()),
actor_id: header_value(headers, HEADER_ACTOR_ID)
.or_else(|| cookie_value(headers, COOKIE_ACTOR_ID))
.and_then(|value| stable_actor_id(&value))
.unwrap_or_else(|| "anonymous".into()),
actor_type: header_value(headers, HEADER_ACTOR_TYPE)
.or_else(|| cookie_value(headers, COOKIE_ACTOR_TYPE))
@@ -117,6 +118,22 @@ impl RequestContext {
}
}
pub(crate) fn stable_actor_id(value: &str) -> Option<String> {
let trimmed = value.trim();
if trimmed.is_empty() {
return None;
}
let stable = trimmed
.split_once('|')
.map(|(actor_id, _)| actor_id.trim())
.unwrap_or(trimmed);
if stable.is_empty() {
None
} else {
Some(stable.to_string())
}
}
fn header_or_generated(headers: &HeaderMap, key: &str, prefix: &str) -> String {
header_value(headers, key).unwrap_or_else(|| generate_id(prefix))
}
@@ -181,6 +198,23 @@ mod tests {
assert_eq!(context.auth.actor_id, "user_demo");
}
#[test]
fn request_context_normalizes_pipe_separated_actor_id() {
let mut headers = HeaderMap::new();
headers.insert(
HEADER_ACTOR_ID,
HeaderValue::from_static("user_demo|session_123"),
);
let context = RequestContext::from_http_parts(
&Method::GET,
&"/".parse::<Uri>().expect("uri"),
&headers,
);
assert_eq!(context.auth.actor_id, "user_demo");
}
#[test]
fn request_context_falls_back_to_actor_cookies() {
let mut headers = HeaderMap::new();
@@ -198,6 +232,26 @@ mod tests {
assert_eq!(context.auth.actor_id, "user_cookie");
assert_eq!(context.auth.actor_type, "user");
}
#[test]
fn request_context_normalizes_pipe_separated_actor_cookie() {
let mut headers = HeaderMap::new();
headers.insert(
axum::http::header::COOKIE,
HeaderValue::from_static(
"mnote_actor_id=user_cookie|session_abc; mnote_actor_type=user",
),
);
let context = RequestContext::from_http_parts(
&Method::GET,
&"/".parse::<Uri>().expect("uri"),
&headers,
);
assert_eq!(context.auth.actor_id, "user_cookie");
assert_eq!(context.auth.actor_type, "user");
}
}
fn cookie_value(headers: &HeaderMap, name: &str) -> Option<String> {