# 森林AI Feature Alignment Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 让前端核心工作流完整使用 `/api/v1`，补齐搜索、项目设置、Inbox 和受控 AI 会话，同时移除伪功能入口。

**Architecture:** 前端 API 层只认一种 camelCase DTO，页面事件由 `App` 编排后刷新聚合工作区。后端为搜索和 AI 会话提供独立 registrar；超出 MVP 的入口从页面移除。

**Tech Stack:** React、TypeScript、Gin、Gorm、Playwright、Go httptest。

## Global Constraints

- 所有前端 ID 是 identity 字符串；不兼容 PascalCase 或数字 ID。
- AI 未经用户确认不得创建任务、笔记或资料。
- 核心操作必须有 loading、成功反馈和可执行的中文错误。
- 不实现探索数据源、支付、窗口停靠、自主 Agent 或实时聊天。

---

### Task 1: 前端 API v1 客户端和错误类型

**Files:**
- Modify: `apps/web_v1/src/api/client.ts`
- Modify: `apps/web_v1/src/api/projects.ts`
- Modify: `apps/web_v1/src/api/mappers.tsx`
- Create: `apps/web_v1/src/api/search.ts`
- Create: `apps/web_v1/src/api/inbox.ts`
- Modify: `apps/web_v1/scripts/structure-check.mjs`

**Interfaces:**
- Produces: `ApiError { status: number; code: string; message: string }` and camelCase DTOs only.

- [ ] **Step 1: Add failing static checks**

Reject `ID?`, `Name?`, `/api/projects`, and `number` project/task IDs in `src/api`. Require `/api/v1` in login and project API paths.

- [ ] **Step 2: Verify failures**

Run: `node scripts/structure-check.mjs`

Expected: FAIL on legacy paths and PascalCase compatibility fields.

- [ ] **Step 3: Implement one response contract**

Parse the standard error envelope:

```ts
export class ApiError extends Error {
  constructor(public status: number, public code: string, message: string) {
    super(message)
  }
}
```

All DTOs use required camelCase fields and string IDs. Update date formatting to happen only in mappers.

- [ ] **Step 4: Verify frontend types**

Run: `node scripts/structure-check.mjs && npm run build && npm run lint`

Expected: PASS.

- [ ] **Step 5: Commit**

```powershell
git add apps/web_v1/src/api apps/web_v1/scripts/structure-check.mjs
git commit -m "refactor(web): consume api v1 contracts"
```

### Task 2: 搜索与项目设置真实往返

**Files:**
- Create: `backend/internal/logic/search/handlers.go`
- Create: `backend/internal/logic/search/handlers_test.go`
- Modify: `backend/cmd/api/main.go`
- Modify: `apps/web_v1/src/pages/projects/project-topbar.tsx`
- Modify: `apps/web_v1/src/pages/projects/project-sidebar.tsx`
- Modify: `apps/web_v1/src/app/App.tsx`

**Interfaces:**
- `GET /api/v1/search?q=` returns `{items: SearchResultDTO[]}`.
- `PATCH /api/v1/projects/:projectId` persists settings and returns ProjectDTO.

- [ ] **Step 1: Write failing search handler tests**

Assert blank query returns 400 `invalid_query`, authenticated matching query returns project/task/note results, and another user's private objects are absent.

- [ ] **Step 2: Verify backend failures**

Run: `go test ./internal/logic/search -v`

Expected: FAIL because handler is missing.

- [ ] **Step 3: Implement search registrar and front-end search state**

Topbar accepts `query`, `loading`, `onQueryChange`, `onSearch`. Submit on Enter or the Search button. Render results in an Arco dropdown/list and navigate to the owning project/channel when the result type is known.

- [ ] **Step 4: Persist project settings**

Replace the local `setWorkspaces`-only update with `updateProject(session, update)`, then call `loadWorkspaces` with the same identity. Keep the modal open on failure.

- [ ] **Step 5: Verify**

Run: `go test ./internal/logic/search ./internal/logic/projects -v; npm run build; npm run lint`

Expected: PASS.

- [ ] **Step 6: Commit**

```powershell
git add backend/internal/logic/search backend/cmd/api/main.go apps/web_v1/src
git commit -m "feat: connect search and project settings"
```

### Task 3: Inbox 确认流与核心写操作

**Files:**
- Modify: `backend/internal/logic/inbox/handlers.go`
- Modify: `backend/internal/logic/inbox/service.go`
- Modify: `backend/internal/logic/inbox/service_test.go`
- Modify: `apps/web_v1/src/api/inbox.ts`
- Create: `apps/web_v1/src/pages/projects/project-inbox.tsx`
- Modify: `apps/web_v1/src/pages/projects/project-channel-page.tsx`
- Modify: `apps/web_v1/src/app/App.tsx`

**Interfaces:**
- Inbox capture/analyze/confirm uses identity strings.
- `confirm` accepts only suggestions returned for the same inbox item and current user.

- [ ] **Step 1: Add failing identity and authorization tests**

Test capture, analyze without writes, confirm selected task/note/source with source Inbox identity, and reject confirming another user's inbox item.

- [ ] **Step 2: Verify failures**

Run: `go test ./internal/logic/inbox -v`

Expected: legacy numeric paths or authorization gaps fail new tests.

- [ ] **Step 3: Implement v1 Inbox DTOs and page**

The page shows item content, suggestion checkboxes and one `确认创建` action. Analysis results remain drafts until this action. On success refresh the workspace and show the created object count.

- [ ] **Step 4: Verify core write operations**

Run: `go test ./internal/logic/inbox ./internal/logic/tasks ./internal/logic/projects -v; npm run build; npm run lint`

Expected: PASS.

- [ ] **Step 5: Commit**

```powershell
git add backend/internal/logic/inbox apps/web_v1/src
git commit -m "feat: connect inbox confirmation workflow"
```

### Task 4: 受控 AI 会话与伪功能清理

**Files:**
- Create: `backend/internal/logic/ai/handlers.go`
- Create: `backend/internal/logic/ai/handlers_test.go`
- Modify: `backend/internal/logic/ai/sessions.go`
- Modify: `backend/internal/logic/ai/gateway.go`
- Modify: `backend/cmd/api/main.go`
- Modify: `apps/web_v1/src/pages/projects/project-ai.tsx`
- Modify: `apps/web_v1/src/pages/workspace-explore.tsx`
- Modify: `apps/web_v1/src/pages/projects/project-new-channel.tsx`
- Modify: `apps/web_v1/src/pages/projects/project-statusbar.tsx`
- Modify: `apps/web_v1/src/pages/projects/project-topbar.tsx`
- Modify: `apps/web_v1/scripts/visual-check.mjs`

**Interfaces:**
- `GET/POST /api/v1/projects/:projectId/ai-sessions` lists/creates controlled sessions.
- No endpoint converts AI output into formal objects without a separate confirmation request.

- [ ] **Step 1: Write failing AI handler tests**

Assert session creation checks project ownership, rate limit runs before provider selection, call logs contain required fields, and the response contains no automatic object IDs.

- [ ] **Step 2: Verify failures**

Run: `go test ./internal/logic/ai -v`

Expected: FAIL because handlers are missing.

- [ ] **Step 3: Implement controlled session endpoints**

Return a session DTO with identity, title, context, status and timestamps. If no provider key exists, return `ai_key_missing` without creating formal objects.

- [ ] **Step 4: Remove unsupported controls**

Remove active-looking sync/edit/delete actions from Explore, payment choices from the status bar, dock buttons, fake app launcher and nonfunctional channel save. Keep a concise “暂未开放” empty state only where navigation must remain visible.

- [ ] **Step 5: Update visual checks and verify**

Run: `go test ./...; $env:VISUAL_CHECK_PORT='4174'; node scripts/visual-check.mjs; npm run build; npm run lint`

Expected: all PASS, AI page has an `AI 助手` heading, and console errors are empty.

- [ ] **Step 6: Commit**

```powershell
git add backend/internal/logic/ai backend/cmd/api/main.go apps/web_v1/src apps/web_v1/scripts/visual-check.mjs
git commit -m "feat: align controlled AI sessions and MVP controls"
```

