chore: align local-first control plane and editor fixes

- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
This commit is contained in:
lix-2026
2026-05-23 23:38:42 +08:00
parent 42fb58310c
commit 5f97800489
110 changed files with 5344 additions and 889 deletions
+21 -5
View File
@@ -3,7 +3,7 @@ use crate::context::RequestContext;
use crate::error::WebError;
use crate::routes::local_folder_source::{
control_plane_db_path_display, create_default_local_workspace_for_actor,
ensure_local_workspace_read_access, is_local_access_policy_admin_context,
ensure_local_workspace_read_access_with_state, is_local_access_policy_admin_context,
load_local_folder_page_tree_snapshot, load_local_trash_entries,
};
use crate::routes::snapshot_support::load_sidebar_dataset;
@@ -311,7 +311,7 @@ pub async fn root_entry(
.ok_or_else(|| {
WebError::bad_request_code("local_folder_root_required", "缺少本地文件夹 rootUri")
})?;
ensure_local_workspace_read_access(&context, root_uri)?;
ensure_local_workspace_read_access_with_state(&state, &context, root_uri)?;
let snapshot = load_local_folder_page_tree_snapshot(root_uri)?;
let workspace_id = snapshot
.dataset
@@ -614,7 +614,7 @@ pub async fn trash_entry(
.ok_or_else(|| {
WebError::bad_request_code("local_folder_root_required", "缺少本地文件夹 rootUri")
})?;
ensure_local_workspace_read_access(&context, root_uri)
ensure_local_workspace_read_access_with_state(&state, &context, root_uri)
.map_err(|error| error.with_context(&context))?;
let workspace_id =
crate::routes::local_folder_source::local_workspace_id_from_root_uri(root_uri)?;
@@ -1780,6 +1780,7 @@ fn handle_sqlite_auth_action(
&resolved.user.id,
resolved.user.email.as_deref().unwrap_or_default(),
&resolved.user.display_name,
&effective_sqlite_auth_actor_type(&resolved.user.id, &resolved.user.role),
))
}
@@ -1809,18 +1810,20 @@ fn build_sqlite_auth_response(
user_id: &str,
email: &str,
name: &str,
actor_type: &str,
) -> Response {
let mut response = axum::Json(json!({
"ok": true,
"userId": user_id,
"email": email,
"name": name,
"authMode": "sqliteSession"
"authMode": "sqliteSession",
"actorType": actor_type
}))
.into_response();
set_literal_cookie(response.headers_mut(), COOKIE_MNOTE_SESSION, session_token);
set_literal_cookie(response.headers_mut(), COOKIE_MNOTE_ACTOR_ID, user_id);
set_literal_cookie(response.headers_mut(), COOKIE_MNOTE_ACTOR_TYPE, "user");
set_literal_cookie(response.headers_mut(), COOKIE_MNOTE_ACTOR_TYPE, actor_type);
if !email.trim().is_empty() {
set_encoded_cookie(response.headers_mut(), COOKIE_MNOTE_ACTOR_EMAIL, email);
}
@@ -1835,6 +1838,19 @@ fn build_sqlite_auth_response(
response
}
fn effective_sqlite_auth_actor_type(user_id: &str, stored_role: &str) -> String {
let role = stored_role.trim();
let fallback_role = if role.is_empty() { "user" } else { role };
if crate::routes::local_folder_source::is_local_access_policy_admin_actor(
user_id,
fallback_role,
) {
"admin".to_string()
} else {
fallback_role.to_string()
}
}
fn build_sqlite_sign_out_response(state: &AppState, context: &RequestContext) -> Response {
if let Some(raw_token) = extract_cookie_value(context, COOKIE_MNOTE_SESSION) {
let token_hash = session_token_hash(&raw_token);