08 定向 Bug Hunt + 架构文档刷新

## 08 定向 Bug Hunt(3.5)

- Bug 1: 侧栏「复制页面」从 `/api/documents/duplicate` 迁移到
  `copyTreeCommand()` → `/api/tree/commands`(`tree.subtree.copy`)
- Bug 2: 侧栏「清空垃圾箱」标注 TODO,等待 Rust `tree.trash.empty`
- Bug 3: 文档页「应用模板」标注 TODO,等待 Rust `tree.page.template`
- Bug 4: 删除 `createChildDocumentCommand` 死代码(函数 + 类型 + 旧
  Next.js `/api/documents/create-child` 路由)
- 归档 4 份 bug 文档到 `bugs/04-tree-domain/done/` 和
  `bugs/05-editor-mainline/done/`

## 架构文档刷新

- ARCHITECTURE.md: MVP 状态标记、三层树模型(§6.4)、8.4 AI 方向按 7-14 v2
  修正、新增 8.5 定向 Bug Hunt 节、刷新 §5 和 §9 卡点描述
- AGENTS.md: 匹配 ARCHITECTURE.md 的 AI 方向和三层模型口径
- 08 checklist: 标记 7-14 v2 影响(Phase A/B/C 重命名、新增 9 项 checklist)

关联设计稿: 7-14 v2, 08
This commit is contained in:
lix-2026
2026-05-16 23:48:41 +08:00
parent f292c6710a
commit 46ede5e251
11 changed files with 231 additions and 53 deletions
@@ -1,13 +0,0 @@
import { NextResponse } from "next/server";
import { isConvexEnabled } from "@/lib/convex/enabled";
import { executeDocumentCreateChildBridgeCommand } from "@/lib/documents/page-command-adapter";
export const dynamic = "force-dynamic";
export async function POST(request: Request) {
if (isConvexEnabled()) {
return executeDocumentCreateChildBridgeCommand(request);
}
return NextResponse.json({ error: "当前仅支持 Convex 模式" }, { status: 501 });
}
@@ -788,6 +788,7 @@ export function DocumentContent({
return;
}
window.alert("已添加为模板");
// TODO: Rust `tree.page.template` 或 `page.layout.applyTemplate` 命令就绪后切到 /api/tree/commands
router.refresh();
}, [documentId, readOnly, router]);
@@ -132,6 +132,7 @@ import { GroupManagerDialog } from "@/components/groups/group-manager-dialog";
import {
copyTreeCommand,
createDocumentCommand,
copyTreeCommand,
deleteDocumentCommand,
embedDocumentCommand,
moveDocumentCommand,
@@ -921,12 +922,12 @@ function SidebarContent({ initialData, sidebarData: externalSidebarData, sidebar
const handleDuplicateDocument = useCallback(
async (node: SidebarTreeNode) => {
const response = await fetch("/api/documents/duplicate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ documentId: node.id }),
});
if (!response.ok) {
try {
await copyTreeCommand({
targetParentId: null,
items: [{ documentId: node.id, recursive: true }],
});
} catch {
window.alert("复制失败,请稍后再试");
return;
}
@@ -2645,6 +2646,7 @@ function SidebarContent({ initialData, sidebarData: externalSidebarData, sidebar
return;
}
await Promise.all([sidebarQuery.refetch(), refreshTree()]);
// TODO: Rust `tree.trash.empty` 命令就绪后切到 /api/tree/commands
} finally {
setEmptyingTrash(false);
}
@@ -71,12 +71,6 @@ export type DocumentCreateCommandResult = {
meta?: DocumentCommandMeta;
};
export type DocumentCreateChildCommandResult = {
pageId: string;
title?: string | null;
meta?: DocumentCommandMeta;
};
type RenameDocumentInput = {
documentId: string;
workspaceId?: string | null;
@@ -141,12 +135,6 @@ type CopyTreeCommandInput = {
}>;
};
type CreateChildDocumentInput = {
parentId: string | null;
title: string;
blocks: unknown[];
};
async function postDocumentCommand<TResult>(path: string, payload: unknown, fallbackMessage: string): Promise<TResult> {
const response = await fetch(path, {
method: "POST",
@@ -222,16 +210,6 @@ export async function createDocumentCommand(parentId: string | null): Promise<Do
};
}
export async function createChildDocumentCommand(
input: CreateChildDocumentInput,
): Promise<DocumentCreateChildCommandResult> {
return postDocumentCommand<DocumentCreateChildCommandResult>(
"/api/documents/create-child",
input,
"创建子页面失败,请稍后再试",
);
}
export async function renameDocumentCommand(input: RenameDocumentInput): Promise<{ ok: true; meta?: DocumentCommandMeta }> {
const response = await postTreeCommand<TreeCommandResponse>(
{