fix(frontend): 修复合并审阅发现的构建与契约问题
恢复 Vue TypeScript 生产构建,补齐可运行页面壳子,并修复文件树与 SSE 状态问题。 按 FastAPI Wire Contract 统一 Service DTO 映射,同时补充前端开发说明和问题修复复盘。
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
# 前端壳子与接口层开发说明
|
||||
|
||||
> 更新日期:2026-08-29
|
||||
> 适用范围:Vue 3 + TypeScript 前端壳子、Workspace、公共 Service、FastAPI 接口适配和 SSE。
|
||||
> 文档用途:帮助团队理解当前前端可用能力、模块边界、启动方式和后续页面开发入口。
|
||||
|
||||
## 1. 当前实现状态
|
||||
|
||||
本轮修复后,前端已经形成一条可安装、可类型检查、可生产构建的基础链路:
|
||||
|
||||
```text
|
||||
Vue Router
|
||||
→ App Shell
|
||||
→ Pinia Store
|
||||
→ Service / FastAPI DTO Adapter
|
||||
→ HTTP 或 SSE
|
||||
→ FastAPI
|
||||
```
|
||||
|
||||
当前可以使用的界面包括:
|
||||
|
||||
- Vault 入口页;
|
||||
- 应用标题栏、主侧边栏、辅助侧边栏和状态栏;
|
||||
- Workspace 文件树;
|
||||
- 基础 Markdown 文本编辑区;
|
||||
- 文件打开、新建、删除和重命名交互壳子;
|
||||
- 未完成模块的统一占位页。
|
||||
|
||||
Search、Chat、Agent、Task、Skill、Plugin、Theme 和 Settings 已保留稳定路由,但除公共 Store 与 Service 外,具体业务页面仍待后续实现。占位页用于保证主分支可构建、导航目标可识别,不代表对应功能页面已经验收。
|
||||
|
||||
## 2. 目录与职责
|
||||
|
||||
```text
|
||||
frontend/src/
|
||||
├── components/common/ App Shell 与公共导航组件
|
||||
├── contracts/index.ts UI View Model 与 FastAPI Wire DTO
|
||||
├── features/common/ 未实现功能的统一占位页
|
||||
├── features/editor/ 基础编辑器头部与文本编辑区
|
||||
├── features/vault/ Vault 入口
|
||||
├── features/workspace/ Workspace 与递归文件树
|
||||
├── router/index.ts 页面路由和 Vault Guard
|
||||
├── services/ HTTP、SSE、DTO 映射和模块 API
|
||||
├── stores/ Pinia 状态
|
||||
└── styles/tokens.css Design Token
|
||||
```
|
||||
|
||||
职责约定:
|
||||
|
||||
- Component 不直接拼接后端 URL;
|
||||
- Store 负责页面状态和业务操作编排;
|
||||
- Service 负责 HTTP/SSE 调用以及 Wire DTO 到 View Model 的转换;
|
||||
- `contracts/index.ts` 同时保留界面模型和以 `Api` 开头的 FastAPI DTO,两者不能混用;
|
||||
- OpenAPI `/openapi.json` 是后端 Wire Contract 的最终依据。
|
||||
|
||||
## 3. 路由与页面壳子
|
||||
|
||||
已注册路由:
|
||||
|
||||
```text
|
||||
/
|
||||
/workspace
|
||||
/search
|
||||
/chat
|
||||
/agent/runs/:runId?
|
||||
/tasks
|
||||
/extensions/skills
|
||||
/extensions/plugins
|
||||
/themes
|
||||
/settings
|
||||
```
|
||||
|
||||
除 Vault 入口外,其余路由需要先打开 Vault。尚未完成的页面统一加载 `PlaceholderView.vue`,后续开发时应逐个替换为真实页面组件,不要在路由中提前引用尚未提交的文件。
|
||||
|
||||
## 4. Workspace 与编辑器
|
||||
|
||||
Workspace 当前由以下组件构成:
|
||||
|
||||
```text
|
||||
WorkspaceView
|
||||
├── EditorHeader
|
||||
└── EditorPane
|
||||
|
||||
SecondarySidebar
|
||||
└── FileTreePanel
|
||||
└── FileTreeNode(递归)
|
||||
```
|
||||
|
||||
文件树把右键目标保存在 `contextTarget`,重命名和删除始终作用于实际被右键的节点,不再依赖当前编辑文件。根目录使用 `/` 表示,新增根级文件时直接写入 Store 顶层数组。
|
||||
|
||||
当前 `workspaceService` 仍是 Web 开发模式下的 Mock Adapter。保存、重命名和删除只保留调用边界,尚未接入 Tauri 文件系统命令。进入桌面端阶段后,应替换 Service 内部实现,不改变 Component 和 Store 的调用方式。
|
||||
|
||||
## 5. HTTP 接口层
|
||||
|
||||
公共请求由 `apiClient.ts` 处理:
|
||||
|
||||
- 支持 GET、POST、PUT、PATCH 和 DELETE;
|
||||
- 使用 `VITE_API_BASE_URL`,并兼容旧的 `VITE_API_BASE`;
|
||||
- 自动附加 `X-Request-Id`;
|
||||
- 将后端统一错误体转换为 `ApiErrorClass`;
|
||||
- 204 响应返回 `undefined`。
|
||||
|
||||
Service 已适配当前 FastAPI Contract:
|
||||
|
||||
| 模块 | 主要适配内容 |
|
||||
| --- | --- |
|
||||
| Notes | `folder`、`markdown`、直接 Note 响应和 `{items, page}` |
|
||||
| Search | 数组筛选字段、`items/page` 响应和 Search View Model 映射 |
|
||||
| Chat | `provider_id`、`model`、`messages` 和 ModelEvent SSE |
|
||||
| Agent | `input`、秒级 Timeout 字段、Run DTO 和 Permission Decision |
|
||||
| Skill / Plugin | 嵌套 `manifest`、安装 `package_path` 和 Plugin Permission PUT |
|
||||
| Provider | Provider Type、Capability 数组、模型列表包装和 Test 响应 |
|
||||
| Task | `due_at`、分页响应和当前后端支持字段 |
|
||||
| Index | `all/notes/vectors` Scope、Job 与状态 DTO |
|
||||
| System | `/health` 和 `/api/status` 的真实响应字段 |
|
||||
|
||||
界面模型中存在的展示字段不能直接发送给后端。例如 Task View Model 的 `priority` 和 `source` 当前只是界面层字段,Service 创建与更新请求不会把它们发送给不支持这些字段的 FastAPI Contract。
|
||||
|
||||
## 6. SSE
|
||||
|
||||
`SseClient` 同时服务于 Chat 和 Agent Event:
|
||||
|
||||
- 使用与普通 HTTP 相同的 API Base URL;
|
||||
- 支持 POST Chat Stream 和 GET Agent Event Stream;
|
||||
- 使用 `TextDecoder` 处理 UTF-8 增量字节;
|
||||
- 在网络分片之间保留 `event` 和多行 `data` 状态;
|
||||
- 以空行作为单个 SSE Event 的结束标志;
|
||||
- 识别 `Done`、`RunCompleted`、`RunFailed` 和 `RunCancelled`;
|
||||
- 支持 AbortController 主动取消。
|
||||
|
||||
Chat Store 已从定时器模拟输出切换为真实 `/api/chat` SSE。默认离线联调配置为:
|
||||
|
||||
```text
|
||||
provider_id = mock
|
||||
model = mock-1
|
||||
```
|
||||
|
||||
## 7. 环境和启动
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
联调前在另一个终端启动后端:
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
|
||||
```
|
||||
|
||||
生产构建:
|
||||
|
||||
```powershell
|
||||
cd frontend
|
||||
pnpm build
|
||||
```
|
||||
|
||||
## 8. 当前验证基线
|
||||
|
||||
```text
|
||||
pnpm build passed
|
||||
uv run pytest 62 passed
|
||||
preview smoke HTTP 200
|
||||
git diff --check passed
|
||||
```
|
||||
|
||||
后端测试出现过一次 `.pytest_cache` 无法写入的 Windows 权限警告,不影响 62 项测试结果,也不涉及产品代码。
|
||||
|
||||
## 9. 后续开发要求
|
||||
|
||||
- 新页面文件与路由修改必须在同一提交中出现;
|
||||
- 新增或修改接口时同步更新 FastAPI DTO、Service 映射和接口文档;
|
||||
- 不允许用 `as any` 或错误返回类型掩盖 Contract 差异;
|
||||
- SSE 相关变更需要覆盖跨 Chunk、CRLF、多行 data、终态事件和取消;
|
||||
- Workspace 接入 Tauri 后,需要增加路径规范化、写入失败恢复和外部修改冲突测试;
|
||||
- Search、Agent、Skill、Plugin 等占位页应按功能逐个替换,不一次提交大量空页面。
|
||||
Reference in New Issue
Block a user