diff --git a/frontend/src/api/space.ts b/frontend/src/api/space.ts index 779c5437..b48828e1 100644 --- a/frontend/src/api/space.ts +++ b/frontend/src/api/space.ts @@ -165,6 +165,10 @@ function projectHref(projectId: string): string { return `/pmflow-os?projectId=${encodeURIComponent(projectId)}`; } +function executionHref(projectId: string): string { + return `/execution-bridge?projectId=${encodeURIComponent(projectId)}`; +} + function pendingChangeItems(truth: ProjectTruthState | null): ChangeItem[] { if (!truth) return []; return truth.changeItems.filter((item) => item.status === "pending_review"); @@ -249,7 +253,7 @@ function deriveAIProgress(snapshot: ProjectSnapshot): SpaceAIProgressItem[] { const { project, truth, execution } = snapshot; const projectId = String(project.id); const projectTitle = project.title || truth?.project.name || `项目 ${projectId}`; - const href = projectHref(projectId); + const href = executionHref(projectId); const items: SpaceAIProgressItem[] = []; if (execution && ACTIVE_EXECUTION_STATUSES.includes(execution.execution.status)) { diff --git a/frontend/src/features/personal-space/PersonalSpacePage.test.tsx b/frontend/src/features/personal-space/PersonalSpacePage.test.tsx index 63955866..f522c946 100644 --- a/frontend/src/features/personal-space/PersonalSpacePage.test.tsx +++ b/frontend/src/features/personal-space/PersonalSpacePage.test.tsx @@ -47,4 +47,97 @@ describe("PersonalSpacePage", () => { expect(screen.getByText("暂存想法只读聚合尚未接入后端合同,当前不使用 mock 数据冒充真实内容。")).toBeInTheDocument(); expect(screen.queryByText("AI 周报助手")).not.toBeInTheDocument(); }); + + it("keeps workbench actions as navigation-only links into the main flows", async () => { + vi.mocked(spaceApi.getWorkbench).mockResolvedValue({ + ...emptyWorkbench, + projects: [ + { + id: "17", + title: "真实项目", + summary: "真实项目摘要", + status: "进行中", + stage: "开发", + progress: 62, + pendingCount: 1, + activeTaskCount: 2, + riskLabel: "中", + nextAction: "继续推进核心任务", + updatedAt: "2026-04-26T08:00:00.000Z", + href: "/pmflow-os?projectId=17", + }, + ], + pendingConfirmations: [ + { + id: "change-91", + projectId: "17", + projectTitle: "真实项目", + title: "确认需求变更", + summary: "等待在主流程确认变更。", + source: "changeset", + stage: "需求", + riskLevel: "medium", + createdAt: "2026-04-26T08:00:00.000Z", + href: "/change-review?projectId=17&changeSetId=91", + }, + ], + aiProgress: [ + { + id: "execution-17", + projectId: "17", + projectTitle: "真实项目", + title: "AI 正在推进执行链路", + summary: "正在聚合执行进度与回写状态。", + status: "coding", + progress: 52, + updatedAt: "2026-04-26T08:00:00.000Z", + href: "/execution-bridge?projectId=17", + }, + ], + drafts: [ + { + id: "17-需求-draft-1", + projectId: "17", + projectTitle: "真实项目", + title: "待确认草案", + summary: "待确认草案摘要", + objectType: "需求", + status: "draft", + updatedAt: "2026-04-26T08:00:00.000Z", + href: "/pmflow-os?projectId=17", + }, + ], + recentProjects: [ + { + id: "17", + title: "真实项目", + summary: "真实项目摘要", + status: "进行中", + stage: "开发", + progress: 62, + pendingCount: 1, + activeTaskCount: 2, + riskLabel: "中", + nextAction: "继续推进核心任务", + updatedAt: "2026-04-26T08:00:00.000Z", + href: "/pmflow-os?projectId=17", + }, + ], + }); + + renderWithProviders(, ["/space"]); + + expect(await screen.findByRole("link", { name: /进入主流程/ })).toHaveAttribute( + "href", + "/pmflow-os?projectId=17" + ); + expect(screen.getAllByRole("link", { name: /确认需求变更/ })[0]).toHaveAttribute( + "href", + "/change-review?projectId=17&changeSetId=91" + ); + expect(screen.getAllByRole("link", { name: /AI 正在推进执行链路/ })[0]).toHaveAttribute( + "href", + "/execution-bridge?projectId=17" + ); + }); }); diff --git a/frontend/src/features/personal-space/PersonalSpacePage.tsx b/frontend/src/features/personal-space/PersonalSpacePage.tsx index c145b0e1..e626ff21 100644 --- a/frontend/src/features/personal-space/PersonalSpacePage.tsx +++ b/frontend/src/features/personal-space/PersonalSpacePage.tsx @@ -299,13 +299,13 @@ function WorkbenchHeader({

个人工作面

- 聚合继续推进、待确认、AI 正在推进、暂存想法和草案箱;点击项目后回到主流程处理。 + 聚合继续推进、待确认、执行中、暂存想法、草案箱和最近项目;点击项目后回到主流程处理。

- +