feat: advance local-first workspace checklist
- add admin access-policy UI and local access control surfaces - add local markdown conflict resolution UI and smoke coverage - add ACP local agent changed-files audit scaffold and read-only write guard - document current P0-P2 checklist progress and verification evidence
This commit is contained in:
@@ -129,6 +129,8 @@ fn build_authorization(config: &AppConfig, context: &RequestContext) -> Result<S
|
||||
Ok(format!("Convex {admin_key}:{identity_encoded}"))
|
||||
}
|
||||
|
||||
// Convex 授权在 local-first 下只作为控制面身份委托;
|
||||
// 本地 workspace 的正文、附件和 AI 会话全文不依赖这里获得写入真相。
|
||||
struct ActingIdentityUser {
|
||||
user_id: String,
|
||||
session_suffix: &'static str,
|
||||
@@ -383,6 +385,8 @@ pub async fn execute_sidebar_dataset_query(
|
||||
context: &RequestContext,
|
||||
plan: &RuntimeQueryExecutionPlan,
|
||||
) -> Result<Value, WebError> {
|
||||
// sidebar:datasetList 只保留为 cloud source / compat projection source;
|
||||
// 默认 local-first 首屏应优先读取 LocalFS projection。
|
||||
execute_convex_query_plan(config, context, plan).await
|
||||
}
|
||||
|
||||
@@ -410,6 +414,8 @@ pub async fn execute_convex_query_by_name(
|
||||
}
|
||||
|
||||
fn convex_command_args_for_plan(plan: &RuntimeCommandExecutionPlan) -> Value {
|
||||
// 这里是 Rust command plan 到 legacy Convex validator 的兼容适配层。
|
||||
// documents:* 属于 compat / cloud source / sync replica,mediaAssets:* 属于 cloud resource replica。
|
||||
let mut args = plan.args_json.clone();
|
||||
if matches!(
|
||||
plan.command_name.as_str(),
|
||||
@@ -448,13 +454,11 @@ fn convex_command_args_for_plan(plan: &RuntimeCommandExecutionPlan) -> Value {
|
||||
plan.command_name.as_str(),
|
||||
"documents.save" | "page.body.save"
|
||||
) {
|
||||
if let Value::Object(map) = &mut args {
|
||||
// 当前自托管 Convex 的 documents:updateContent 仍是 legacy validator。
|
||||
// Rust plan 保留正式事件契约,但发送给 legacy mutation 时只传它实际接受的字段。
|
||||
map.remove("editorDocument");
|
||||
map.remove("tiptapDocument");
|
||||
}
|
||||
// 当前 Convex documents:updateContent 仍是 legacy content substrate:
|
||||
// 真实可见保存必须只发送 validator 接受的字段;原生编辑器快照留在
|
||||
// Rust plan / artifact 侧,待 Convex schema 正式迁移后再进入持久层。
|
||||
strip_tree_artifact_fields(&mut args);
|
||||
strip_editor_snapshot_fields(&mut args);
|
||||
}
|
||||
if matches!(
|
||||
plan.command_name.as_str(),
|
||||
@@ -552,6 +556,15 @@ fn strip_tree_artifact_fields(args: &mut Value) {
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_editor_snapshot_fields(args: &mut Value) {
|
||||
if let Value::Object(map) = args {
|
||||
map.remove("editorDocument");
|
||||
map.remove("tiptapDocument");
|
||||
map.remove("blockDocument");
|
||||
map.remove("blockProjectionVersion");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn execute_convex_command_plan(
|
||||
config: &AppConfig,
|
||||
context: &RequestContext,
|
||||
@@ -850,6 +863,7 @@ pub async fn persist_runtime_command_artifacts(
|
||||
context: &RequestContext,
|
||||
artifacts: &RuntimeCommandArtifactPlan,
|
||||
) -> Result<(), WebError> {
|
||||
// bridgeLogs 只作为控制面审计与事件副本,不承载 local-first 页面正文真相。
|
||||
execute_convex_mutation_by_name(
|
||||
config,
|
||||
context,
|
||||
@@ -958,9 +972,9 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convex_command_args_strips_editor_runtime_fields_for_legacy_document_save() {
|
||||
fn convex_command_args_strips_editor_runtime_fields_for_legacy_page_body_save() {
|
||||
let plan = RuntimeCommandExecutionPlan {
|
||||
command_name: "documents.save".into(),
|
||||
command_name: "page.body.save".into(),
|
||||
command_id: "cmd_1".into(),
|
||||
function_name: "documents:updateContent".into(),
|
||||
workspace_id: Some("ws_1".into()),
|
||||
@@ -975,7 +989,7 @@ mod tests {
|
||||
"content": [],
|
||||
"expectedRevision": 0,
|
||||
"conflictDetectionKey": "doc_1:0",
|
||||
"editorDocument": {"rootBlockIds": []},
|
||||
"editorDocument": {"documentId": "doc_1", "rootBlockIds": []},
|
||||
"tiptapDocument": {"type": "doc", "content": []},
|
||||
"streamDeltaHint": {"family": "tree"},
|
||||
"domainEventHint": {"eventType": "page.body.saved"},
|
||||
@@ -1133,7 +1147,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convex_resource_lifecycle_args_keep_effective_user_id() {
|
||||
fn convex_cloud_media_resource_lifecycle_args_keep_effective_user_id() {
|
||||
let plan = RuntimeCommandExecutionPlan {
|
||||
command_name: "tree.resource.archive".into(),
|
||||
command_id: "cmd_resource_archive_1".into(),
|
||||
|
||||
Reference in New Issue
Block a user