4-10 树域 Rust 家族化

This commit is contained in:
lix-2026
2026-04-24 06:10:18 +08:00
parent 41e958769e
commit 94631f3636
49 changed files with 5751 additions and 557 deletions
@@ -79,6 +79,8 @@ import { POST as postPurge } from "@/app/api/documents/purge/route";
import { POST as postTitle } from "@/app/api/documents/title/route";
import { POST as postOptions } from "@/app/api/documents/options/route";
import { POST as postSave } from "@/app/api/documents/save/route";
import { POST as postCreate } from "@/app/api/documents/create/route";
import { POST as postMove } from "@/app/api/documents/move/route";
import { GET as getPage } from "@/app/api/documents/page/route";
import {
executeDocumentCreateChildBridgeCommand,
@@ -91,6 +93,151 @@ import { executePageWriteBridgeCommand } from "@/lib/documents/page-write-comman
import { loadPageAggregate } from "@/lib/documents/page-aggregate-loader";
describe("documents route adapters", () => {
it("create route 作为 compat 壳委托 tree commands 主路径", async () => {
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(
JSON.stringify({
requestId: "req_tree_create_1",
traceId: "trace_tree_create_1",
result: {
action: "create",
workspaceId: "ws_1",
documentId: "doc_new",
parentId: null,
title: "无标题",
sortOrder: 0,
updatedAt: "2026-04-23T00:00:00Z",
execution: {
access_scope: "private",
is_template: false,
created_at: "2026-04-23T00:00:00Z",
updated_at: "2026-04-23T00:00:00Z",
},
},
}),
{ status: 200, headers: { "content-type": "application/json" } },
),
);
const response = await postCreate(new Request("http://localhost/api/documents/create", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ parentId: null }),
}));
const payload = await response.json() as {
id: string;
workspace_id: string;
meta: { commandName: string };
};
expect(fetchMock).toHaveBeenCalledWith(
"http://localhost/api/tree/commands",
expect.objectContaining({
method: "POST",
headers: expect.any(Headers),
body: JSON.stringify({
action: "create",
parentId: null,
}),
}),
);
expect(payload.id).toBe("doc_new");
expect(payload.workspace_id).toBe("ws_1");
expect(payload.meta.commandName).toBe("tree.node.create");
});
it("move route 作为 compat 壳委托 tree commands 主路径", async () => {
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(
JSON.stringify({
requestId: "req_tree_move_1",
traceId: "trace_tree_move_1",
result: {
action: "move",
workspaceId: "ws_1",
documentId: "doc_1",
parentId: "parent_1",
sortOrder: 2,
updatedAt: "2026-04-23T00:00:00Z",
},
}),
{ status: 200, headers: { "content-type": "application/json" } },
),
);
const response = await postMove(new Request("http://localhost/api/documents/move", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ documentId: "doc_1", parentId: "parent_1", position: 2.7, workspaceId: "ws_1" }),
}));
const payload = await response.json() as {
ok: boolean;
meta: { commandName: string };
};
expect(fetchMock).toHaveBeenCalledWith(
"http://localhost/api/tree/commands",
expect.objectContaining({
method: "POST",
headers: expect.any(Headers),
body: JSON.stringify({
action: "move",
documentId: "doc_1",
parentId: "parent_1",
sortOrder: 2,
workspaceId: "ws_1",
}),
}),
);
expect(payload.ok).toBe(true);
expect(payload.meta.commandName).toBe("tree.subtree.move");
});
it("title route 在树重命名兼容请求下委托 tree commands 主路径", async () => {
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(
JSON.stringify({
requestId: "req_tree_rename_1",
traceId: "trace_tree_rename_1",
result: {
action: "rename",
workspaceId: "ws_1",
documentId: "doc_1",
title: "新标题",
updatedAt: "2026-04-23T00:00:00Z",
},
}),
{ status: 200, headers: { "content-type": "application/json" } },
),
);
const response = await postTitle(new Request("http://localhost/api/documents/title", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ documentId: "doc_1", workspaceId: "ws_1", title: "新标题" }),
}));
const payload = await response.json() as {
ok: boolean;
meta: { commandName: string };
};
expect(fetchMock).toHaveBeenCalledWith(
"http://localhost/api/tree/commands",
expect.objectContaining({
method: "POST",
headers: expect.any(Headers),
body: JSON.stringify({
action: "rename",
documentId: "doc_1",
workspaceId: "ws_1",
title: "新标题",
}),
}),
);
expect(payload.ok).toBe(true);
expect(payload.meta.commandName).toBe("tree.node.rename");
});
it("creates child route delegates to unified adapter", async () => {
await postCreateChild(new Request("http://localhost/api/documents/create-child", {
method: "POST",
@@ -146,10 +293,15 @@ describe("documents route adapters", () => {
expect(payload.meta.queryName).toBe("documents.page.get");
});
it("title route delegates to unified page write adapter", async () => {
it("title route 在 page head 请求下仍委托 unified page write adapter", async () => {
await postTitle(new Request("http://localhost/api/documents/title", {
method: "POST",
body: JSON.stringify({ documentId: "doc_1", workspaceId: "ws_1", title: "新标题" }),
body: JSON.stringify({
documentId: "doc_1",
workspaceId: "ws_1",
title: "新标题",
commandName: "page.head.updateTitle",
}),
}));
expect(executePageWriteBridgeCommand).toHaveBeenCalled();