docs: 开发文档面向AI精简重构,补充文档编撰规范

This commit is contained in:
2026-06-01 16:43:17 +08:00
parent de51a817fb
commit b225b0a0c7
5 changed files with 177 additions and 369 deletions

View File

@@ -156,6 +156,8 @@ AI 工具必须严格遵守以下全部约束。
- 必填文本字段同时配 `required` + `whitespace` - 必填文本字段同时配 `required` + `whitespace`
- 操作确认用 `Popconfirm`,反馈用 antd message。 - 操作确认用 `Popconfirm`,反馈用 antd message。
### 错误边界
- 生产入口必须启用 `ErrorBoundary``ReactQueryDevtools``DEV` 模式渲染。 - 生产入口必须启用 `ErrorBoundary``ReactQueryDevtools``DEV` 模式渲染。
--- ---
@@ -234,3 +236,26 @@ AI 工具必须严格遵守以下全部约束。
## 更新触发条件 ## 更新触发条件
修改常用命令、质量门禁、开发规范(任何章节)、目录边界或开发文档索引时,必须更新本文档。 修改常用命令、质量门禁、开发规范(任何章节)、目录边界或开发文档索引时,必须更新本文档。
### 文档编撰规范
本节开发文档面向 AI 工具阅读,编撰时遵循以下原则:
**精简原则**
- 删除引导语、适用场景、过渡句等装饰性文字。AI 无需"应首先阅读"或"本文档说明…"类引导。
- 不重复项目结构树AI 可通过 glob 获取目录结构。
- 不重复已在 README.md 声明的规范细节专题文档只记录实现层面的函数签名、API 端点、模块职责等索引信息。
- 表格标题自明时不再加说明段落。
**信息完整性**
- 所有函数签名、API 端点(方法+路径+说明)、数据访问函数清单必须完整列举,不可用"等"省略。
- 页面行为描述须包含关键交互逻辑(如 Tab 切换、默认值、条件跳转、测试不阻止保存等),不可只写组件名。
- 配置文件列表必须完整,不可遗漏已有文件。
**结构规范**
- 每个专题文档末尾保留 `## 更新触发条件` 章节,明确列出哪些变更必须更新该文档。
- 用表格和编号列表替代散文段落,减少 token 消耗。
- 同一信息只在一处维护,避免多处重复导致不一致。

View File

@@ -1,159 +1,60 @@
# 架构与边界 # 架构与边界
本文档说明 alfred 的项目结构、启动链路、运行时流程、HTTP 请求流程和前后端边界。
适用场景修改目录边界、启动流程、运行时调度、HTTP server、前后端集成方式或主要模块职责。
## 项目结构
```text
src/
server/
bootstrap.ts 统一启动引导loadServerConfig -> DB 初始化 -> startServer
config.ts CLI 参数解析与配置文件加载 facade
config/ 配置解析模块
index.ts 配置模块导出
types.ts 配置类型定义
issues.ts 配置问题收集
variables.ts 变量解析
normalizer.ts 配置标准化
schema/ JSON Schema 生成与校验
builder.ts
export.ts
fragments.ts
validate.ts
db/ SQLite 数据库模块
index.ts 数据库模块导出
schema.ts Drizzle ORM schema 定义
connection.ts 数据库连接与 PRAGMA 设置
load-migrations.ts 从文件系统加载 migration SQL
migrate.ts migration 执行器(备份 + 事务应用)
projects.ts 项目数据访问函数
providers.ts 供应商数据访问函数
models.ts 模型数据访问函数
conversations.ts 会话与消息数据访问函数
ai/ AI 服务层
types.ts AI 配置类型定义
registry.ts AI Provider Registry 构建与连接测试
agents/ Agent 工厂
alfred-agent.ts Agent 工厂ToolLoopAgent + 工具)
tools/ 工具定义
get-current-time.ts 获取当前时间工具
dev.ts 开发模式启动入口
main.ts 生产模式启动入口
server.ts HTTP server 启动工厂Bun.serve routes 声明式路由)
static.ts 生产模式静态资源服务
helpers/ 共享工具模块
index.ts 模块导出
response.ts 响应格式化工具
url.ts URL 拼接工具
middleware/ API 中间件模块
index.ts 模块导出
validate.ts 参数校验中间件
error-handler.ts 错误处理中间件
logger.ts 结构化日志(基于 pino + pino-roll
version.ts 运行时版本号读取
routes/ API 路由处理器
meta.ts 应用元信息路由
providers/ 供应商 CRUD 与测试路由
models/ 模型 CRUD 与测试路由
projects/ 项目 CRUD、归档与恢复路由
chat/ 聊天会话与消息路由(含 SSE 流式发送)
shared/
api.ts 前后端共享 TypeScript 类型定义
app.ts 应用全局常量name、title、subtitle、description
web/ React 前端(通过 Vite 构建)
index.html HTML 入口
main.tsx React 入口StrictMode + ErrorBoundary + QueryClientProvider + BrowserRouter
app.tsx 根组件(设置 document 标题和 meta
routes.tsx 路由配置Admin + Workbench 两大控制台)
menu.tsx 共享菜单项类型定义
styles.css 全局样式
css.d.ts CSS Modules 类型声明
pages/ 页面组件
dashboard/ 总览页面
projects/ 项目管理页面及其子组件
models/ 模型管理页面及其子组件
404/ 404 页面
components/ 共享 UI 组件
ErrorBoundary.tsx 错误边界
ConsoleShell/ 通用控制台外壳ConsoleShell、ConsoleOutlet、types
Sidebar/ 侧边栏导航组件
consoles/ 控制台入口
admin/ Admin 管理台AdminConsoleLayout、菜单配置
workbench/ Workbench 工作台ProjectGate、ConsoleLayout、菜单配置、ChatPage 等)
hooks/ React Hooksuse-meta、use-projects、use-providers、use-models、use-conversations、主题/侧边栏偏好)
utils/ 前端工具函数fetch 封装、时间格式化)
scripts/ 独立运行脚本
tests/ 测试文件(镜像 src 目录结构)
docs/ 项目文档
openspec/ OpenSpec 规格、变更与 fast-drive workflow schema
```
## 启动流程 ## 启动流程
```text ```text
dev.ts / main.ts dev.ts / main.ts
-> parseRuntimeArgs(cli args) -> parseRuntimeArgs(cli args) — 必须指定 config.yaml
-> 必须指定 config.yaml
-> bootstrap({ configPath, mode }) -> bootstrap({ configPath, mode })
-> loadServerConfig(configPath) -> loadServerConfig(configPath)
-> createRuntimeLogger(config.logging) -> createRuntimeLogger(config.logging)
-> 确保 dataDir 就绪mkdirSync -> mkdirSync(dataDir)
-> 加载 migrations生产嵌入 bytes开发磁盘 drizzle/ 目录 -> 加载 migrations生产嵌入 bytes开发磁盘 drizzle/
-> createDatabase(dataDir) -> createDatabase(dataDir)
-> runMigrations(db, migrations)pending migration 存在时先备份 DB -> runMigrations(db, migrations)pending 时先备份 DB
-> startServer({ config, logger, db }) -> startServer({ config, logger, db })
-> logger 记录启动成功
-> SIGINT/SIGTERM -> db.close() -> logger.flush() -> exit -> SIGINT/SIGTERM -> db.close() -> logger.flush() -> exit
``` ```
## HTTP 请求流程 ## HTTP 请求流程
```text ```text
Request Request -> Bun.serve routes 声明式匹配 -> routes/*.ts handler -> helpers/ 响应格式化 -> Response
-> Bun.serve routes 声明式匹配
-> routes/*.ts handler
-> helpers/ 响应格式化
-> Response
``` ```
生产模式下,非 API 路径由 fetch fallback 处理:有文件扩展名返回静态资源或 404无扩展名返回 SPA index.html。 - 生产模式非 API 路径由 fetch fallback 处理,有扩展名返回静态资源或 404无扩展名返回 SPA index.html。
- 开发模式Vite proxy 将 /api 转发到 Bun。
开发模式下Vite proxy 将 /api 请求转发到 Bun API server。
## 前后端边界 ## 前后端边界
- 前端只通过 HTTP 调用后端API 路径为 /api/\*。 - 前端只通过 HTTP /api/\* 调用后端
- 共享类型在 src/shared/。 - 共享类型在 `src/shared/`
- 前端不得 import src/server/ 运行时实现。 - 前端禁止 import `src/server/` 运行时实现;后端禁止依赖 `src/web/` 运行时代码HTML import 集成除外)
- 后端不得依赖 src/web/ 运行时代码HTML import 集成除外。
## 主要模块职责 ## 主要模块
| 模块 | 职责 | | 模块 | 职责 |
| ------------------------- | ---------------------------------------------------------------------- | | ------------------------- | ------------------------------------------------ |
| `src/server/bootstrap.ts` | 统一启动引导、DB 初始化shutdown 编排 | | `src/server/bootstrap.ts` | 统一启动引导、DB 初始化shutdown 编排 |
| `src/server/server.ts` | Bun HTTP server routes 注册 | | `src/server/server.ts` | Bun HTTP server + routes 注册 |
| `src/server/routes/` | API handler按资源端点拆分meta、providers、models、projects、chat | | `src/server/routes/` | API handler按资源端点拆分 |
| `src/server/db/` | SQLite 连接、schema、migrationdata access | | `src/server/db/` | SQLite 连接、schema、migrationdata access |
| `src/server/ai/` | AI Provider Registry 构建与 Agent 流式调用 | | `src/server/ai/` | AI Provider Registry + Agent 流式调用 |
| `src/server/config/` | 配置解析模块types、variables、normalizer、schema | | `src/server/config/` | 配置解析types、variables、normalizer、schema |
| `src/server/helpers/` | 共享响应格式化URL 工具 | | `src/server/helpers/` | 响应格式化URL 工具 |
| `src/server/middleware/` | API 参数校验错误处理中间件 | | `src/server/middleware/` | 参数校验 + 错误处理 |
| `src/web/` | React 前端Admin + Workbench 双控制台架构) |
| `src/shared/api.ts` | 前后端共享 API 类型 | | `src/shared/api.ts` | 前后端共享 API 类型 |
| `src/shared/app.ts` | 应用全局常量 | | `src/shared/app.ts` | 应用全局常量 |
### 路由按资源分组 ## 路由分组
| 资源分组 | 路径前缀 | 路由文件 | | 资源 | 路径前缀 | 文件目录 |
| --------- | ------------------------------------------------------------- | ---------------------------- | | --------- | ----------------------------------------------- | ------------------- |
| meta | `/api/meta` | `routes/meta.ts` | | meta | `/api/meta` | `routes/meta.ts` |
| providers | `/api/providers` | `routes/providers/` (7 文件) | | providers | `/api/providers` | `routes/providers/` |
| models | `/api/models` | `routes/models/` (6 文件) | | models | `/api/models` | `routes/models/` |
| projects | `/api/projects` | `routes/projects/` (7 文件) | | projects | `/api/projects` | `routes/projects/` |
| chat | `/api/projects/:id/conversations``/api/projects/:id/chat` | `routes/chat/` (7 文件) | | chat | `/api/projects/:id/conversations``:id/chat` | `routes/chat/` |
## 更新触发条件 ## 更新触发条件

View File

@@ -1,92 +1,50 @@
# 后端开发 # 后端开发
本文档说明 alfred 后端的模块实现细节、API 索引和开发方式。开发规范库优先级、类型规范、配置契约、API 路由规范、测试约定等)见 [开发规范文档](README.md#开发规范)。 开发规范见 [开发规范文档](README.md)。
适用场景:修改 `src/server/`、了解现有模块 API、查找可供复用的工具函数和数据访问接口。
## 共享工具 ## 共享工具
`src/server/helpers/` 提供跨路由共用的工具模块: `src/server/helpers/`:
- `response.ts` — 响应格式化工具: - `response.ts``createApiError(error, status)``createHeaders(mode, init)``createMetaResponse(version)``formatDuration(ms)``jsonResponse(body, options)`
- `createApiError(error, status)` — 构造 API 错误体 - `url.ts``parseIdFromUrl(url)`
- `createHeaders(mode, init)` — 创建响应 Headers生产模式附加安全 header
- `createMetaResponse(version)` — 构造应用元信息响应
- `formatDuration(ms)` — 格式化毫秒时长为可读字符串
- `jsonResponse(body, options)` — JSON 响应构造
- `url.ts` — URL 工具:
- `parseIdFromUrl(url)` — 从 URL 解析路径中的 ID
`src/server/middleware/` 提供 API 参数校验和错误处理中间件: `src/server/middleware/`:
- `validate.ts` — 参数校验函数: - `validate.ts``validateIdParam(idStr, mode)` — 校验 ID 格式(字母数字 + `_-``validatePagination(pageParam, pageSizeParam, mode)` — page≥1, pageSize≤200`validateTimeRange(from, to, mode)`
- `validateIdParam(idStr, mode)` — 校验 ID 参数格式(字母数字 + `_` `-` - `error-handler.ts``AppError` — 业务异常类(含 statusCode`withErrorHandler(fn, mode, logger?)` — 包裹 handler 捕获异常
- `validatePagination(pageParam, pageSizeParam, mode)` — 校验分页参数page 最小 1pageSize 最大 200
- `validateTimeRange(from, to, mode)` — 校验时间范围参数
- `error-handler.ts` — 错误处理中间件:
- `AppError` — 业务异常类(含 statusCode
- `withErrorHandler(fn, mode, logger?)` — 包裹路由 handler捕获 AppError 和未知异常
## 数据库 ## 数据库
项目使用 SQLite 作为存储后端,通过 bun:sqlite + Drizzle ORM 实现类型安全的数据访问 SQLite + bun:sqlite + Drizzle ORM。
### schema 定义 - `src/server/db/schema.ts`Drizzle 表结构,列名 snake_caseTS 类型 camelCase。
- `src/server/db/connection.ts``createDatabase(dataDir, logger)` 打开 `alfred.db`PRAGMAforeign_keys=ON、journal_mode=WAL、busy_timeout=5000。`wrap(db)` 转为 Drizzle 实例。`paginateQuery()` 分页工具。
- Migration开发期 `drizzle-kit generate` 产出到 `drizzle/`;生产期嵌入可执行文件,启动时自动应用。备份到 `<dataDir>/backups/`,事务中执行,失败回滚。
`src/server/db/schema.ts` 使用 Drizzle ORM 定义表结构,列名使用 snake_caseTypeScript 类型使用 camelCaseDrizzle schema 负责映射。 ### 数据访问函数
### 数据库连接 | 文件 | 函数 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `projects.ts` | createProject、getProject、listProjects、updateProject、deleteProject、archiveProject、restoreProject |
| `providers.ts` | createProvider、getProvider、listProviders、listProviderOptions、updateProvider、deleteProvider |
| `models.ts` | createModel、getModel、listModels、getModelsByProviderId、updateModel、deleteModel |
| `conversations.ts` | createConversation、getConversation、listConversations、updateConversation、updateConversationTimestamp、deleteConversation、createMessage、createMessages、listMessages |
`src/server/db/connection.ts``createDatabase(dataDir, logger)` 打开 `<dataDir>/alfred.db`,设置 PRAGMAforeign_keys=ON、journal_mode=WAL、busy_timeout=5000 输入输出类型来自 `src/shared/api.ts`
### migration 机制
- 开发期:使用 `drizzle-kit generate` 从 TS schema 生成 SQL migration 文件到 `drizzle/` 目录
- 生产期:构建时将 `drizzle/*.sql` 嵌入可执行文件,启动时自动应用 pending migrations
- 每次 migration 前自动备份现有 DB 到 `<dataDir>/backups/alfred-<timestamp>.db`
- migration 在事务中执行,失败则回滚并停止启动
### 数据访问
`src/server/db/projects.ts` 提供项目数据访问函数(`createProject``getProject``listProjects``updateProject``deleteProject``archiveProject``restoreProject`)。`src/server/db/providers.ts` 提供供应商数据访问函数(`createProvider``getProvider``listProviders``listProviderOptions``updateProvider``deleteProvider`)。`src/server/db/models.ts` 提供模型数据访问函数(`createModel``getModel``listModels``getModelsByProviderId``updateModel``deleteModel`)。`src/server/db/conversations.ts` 提供会话和消息数据访问函数(`createConversation``getConversation``listConversations``updateConversation``updateConversationTimestamp``deleteConversation``createMessage``createMessages``listMessages`)。`src/server/db/connection.ts` 还提供 `paginateQuery``wrap` 工具函数。输入输出使用 `src/shared/api.ts` 的类型。函数内部使用 Drizzle query builder 包装 `bun:sqlite` Database。
## AI 服务层 ## AI 服务层
`src/server/ai/` 提供 AI Provider Registry 构建与连接测试能力 - `src/server/ai/types.ts``AIProviderConfig`name、type、baseUrl、apiKey`AIModelConfig`providerId、modelId、capabilities
- `src/server/ai/registry.ts`
- `buildProviderRegistry(db)` — 从 DB 查询供应商构建 AI SDK Provider Registry每次调用重建不缓存。通过 `registry.languageModel('providerId:modelId')` 获取模型实例。
- `testProviderConnection(config)` — 测试 Base URL 可达性 + `/models` 接口
- `testModelConnection(config)` — 测试模型连通性
- `countModels(db)` — 统计已配置模型数
- `src/server/ai/agents/alfred-agent.ts``createAlfredAgent(model)` — ToolLoopAgent + `stepCountIs(20)` + `getCurrentTime` 工具。
- `src/server/ai/tools/`AI 工具定义。
### 类型定义 ### 供应商类型
`src/server/ai/types.ts` 定义 AI 配置类型:
- `AIProviderConfig` — 供应商配置name、type、baseUrl、apiKey
- `AIModelConfig` — 模型配置providerId、modelId、capabilities
- `AIRegistryConfig` — Registry 构建配置providers、models供后续 AI 调用层组合使用
### Registry 构建
`src/server/ai/registry.ts` 提供:
- `buildProviderRegistry(db)` — 从 DB 查询所有供应商,构建 Vercel AI SDK Provider Registry
- `testProviderConnection(config)` — 先测试 Base URL 可达性,再请求 `/models` 验证 API Key 和模型列表接口
- `testModelConnection(config)` — 先通过 providerId 查询供应商(含 apiKey再以 modelId 请求对应模型的 API 连通性
- `countModels(db)` — 统计 DB 中已配置的模型总数,用于 Agent 调用前的可用性检查
每次 AI 调用时从 DB 查询 providers构建 registry 后通过 `registry.languageModel('providerId:modelId')` 获取模型实例。不使用缓存层。模型是否存在以及业务能力标签由调用方基于 models 表先行校验registry 只负责将 providerId/modelId 映射到 AI SDK 模型实例。
### Agent 流式调用
`src/server/ai/agents/alfred-agent.ts` 提供 `createAlfredAgent(model)` 工厂函数,返回 AI SDK `ToolLoopAgent` 实例。默认使用 `stepCountIs(20)` 限制最大迭代次数,配置 `getCurrentTime` 工具供 AI 调用。路由层通过 `createAgentUIStreamResponse()` 转为 SSE 响应,流结束通过 `onFinish` 回调可靠持久化 AI 回复(含完整 `parts`)。
### 供应商连通性测试
供应商连通性测试返回 `{ providerTestResponse: { ok, message } }`,前端根据 `ok` 展示成功或失败提示。
- `POST /api/providers/test` — 使用表单中尚未保存的供应商配置测试连接
- `POST /api/models/test` — 使用模型关联供应商配置和 modelId 测试模型连接
测试连接不会写入数据库也不会阻止保存。Base URL 不可达或 API Key 无效返回 `ok: false`Base URL 可达但 `/models` 不支持、非标准或返回非鉴权错误时返回 `ok: true` 并在 `message` 中提示用户可检查 URL 或忽略提醒。
### 支持的供应商类型
| type | AI SDK factory | | type | AI SDK factory |
| ------------------- | --------------------------------------------------- | | ------------------- | --------------------------------------------------- |
@@ -94,50 +52,37 @@
| `anthropic` | `createAnthropic({ apiKey, baseURL })` | | `anthropic` | `createAnthropic({ apiKey, baseURL })` |
| `openai-compatible` | `createOpenAICompatible({ name, apiKey, baseURL })` | | `openai-compatible` | `createOpenAICompatible({ name, apiKey, baseURL })` |
## 聊天 API ### 连通性测试
聊天 API 按项目维度组织会话和消息: - `POST /api/providers/test` — 用未保存配置测试,不写入 DB不阻止保存。Base URL 不可达或 API Key 无效返回 `ok: false``/models` 不支持返回 `ok: true` + 提示。
- `POST /api/models/test` — 用模型关联供应商 + modelId 测试。
## 聊天 API
| 方法 | 路径 | 说明 | | 方法 | 路径 | 说明 |
| ------ | ----------------------------------------------- | ------------------ | | ------ | ----------------------------------------------- | ------------------ |
| GET | `/api/projects/:id/conversations` | 列出项目下所有会话 | | GET | `/api/projects/:id/conversations` | 列出项目下所有会话 |
| POST | `/api/projects/:id/conversations` | 创建新会话 | | POST | `/api/projects/:id/conversations` | 创建新会话 |
| GET | `/api/projects/:id/conversations/:cid` | 获取会话详情 | | GET | `/api/projects/:id/conversations/:cid` | 获取会话详情 |
| PATCH | `/api/projects/:id/conversations/:cid` | 更新会话标题或模型 | | PATCH | `/api/projects/:id/conversations/:cid` | 更新会话 |
| DELETE | `/api/projects/:id/conversations/:cid` | 删除会话及消息 | | DELETE | `/api/projects/:id/conversations/:cid` | 删除会话及消息 |
| GET | `/api/projects/:id/conversations/:cid/messages` | 获取会话消息列表 | | GET | `/api/projects/:id/conversations/:cid/messages` | 获取消息列表 |
| POST | `/api/projects/:id/chat` | 发送消息并流式回复 | | POST | `/api/projects/:id/chat` | 发送消息SSE 回复 |
聊天路由处理器位于 `src/server/routes/chat/`,遵循统一的 handler 模式。`send.ts` 处理发送消息:验证会话归属后只保存最后一条用户消息到 DB通过 `createAlfredAgent` 创建 agent调用 `createAgentUIStreamResponse` 返回 SSE UI 消息流,流结束通过 `onFinish` 回调保存 AI 回复到 DB `send.ts`:验证会话归属 → 保存用户消息 → `createAlfredAgent` `createAgentUIStreamResponse` `onFinish` 持久化 AI 回复。
## 日志模块 ## 日志
后端运行时代码统一通过 Logger 接口输出日志。
| 实现 | 用途 | | 实现 | 用途 |
| --------------------- | ------------------------ | | --------------------- | -------------- |
| PinoLoggerWrapper | 生产运行时 | | PinoLoggerWrapper | 生产运行时 |
| ConsoleFallbackLogger | 配置加载失败前的降级日志 | | ConsoleFallbackLogger | 配置加载前降级 |
| NoopLogger | 静默丢弃日志 | | NoopLogger | 静默丢弃 |
| MemoryLogger | 测试替身 | | MemoryLogger | 测试替身 |
## 版本管理 ## 版本管理
版本号以 `package.json.version` 为唯一来源 唯一来源:`package.json`。开发模式从 package.json 运行时读取;生产模式构建时烘焙为字面量
版本获取方式:
- 开发模式:`src/server/version.ts` 运行时从 package.json 读取
- 生产模式:`scripts/build.ts` 在构建时将版本号烘焙为字面量注入
版本升迁命令:
```bash
bun run version:patch # 升迁 patch 版本
bun run version:minor # 升迁 minor 版本
bun run version:major # 升迁 major 版本
bun run version:set # 显式设置版本号
```
## 更新触发条件 ## 更新触发条件

View File

@@ -1,70 +1,53 @@
# 前端开发 # 前端开发
本文档说明 alfred 前端的运行时代码结构、组件索引和页面组成。开发规范组件规范、Ant Design 用法、样式规则、表单交互、TanStack Query、测试约定等见 [开发规范文档](README.md#开发规范)。 开发规范见 [开发规范文档](README.md)。
适用场景:修改 `src/web/`、了解现有组件和页面结构、查找 hooks 和工具函数。 ## 控制台架构
## 运行时外壳 两个控制台入口共享 ConsoleShell`src/web/components/ConsoleShell/`
前端提供两个入口外壳,共享通用 Console Shell 组件: - **Admin**`src/web/consoles/admin/`):路由 `/`(总览)、`/projects``/models`
- **Workbench**`src/web/consoles/workbench/`):路由 `/workbench/:projectId``/workbench/:projectId/chat``WorkbenchProjectGate` 从 URL 读 projectId通过 `ProjectContext` 提供项目上下文,仅 active 项目渲染。
- **Admin管理台**`src/web/consoles/admin/AdminConsoleLayout.tsx`,菜单配置在 `src/web/consoles/admin/menu.tsx`,路由 `/`(总览)、`/projects`(项目管理)、`/models`(模型管理) ConsoleShell 包含:`ConfigProvider(zhCN)` + `AntApp` + `Layout`(Header/Sider/Content) + 主题切换(明亮/黑暗/系统)+ 侧边栏折叠。Header 显示品牌名、版本号和控制台标题
- **Workbench工作台**`src/web/consoles/workbench/WorkbenchProjectGate.tsx``WorkbenchConsoleLayout.tsx`,菜单配置和路由构造在 `src/web/consoles/workbench/routes.ts`,路由 `/workbench/:projectId``/workbench/:projectId/chat`。默认菜单为"聊天室"。
通用 Console Shell`src/web/components/ConsoleShell/ConsoleShell.tsx`)包含 `ConfigProvider`zhCN locale`AntApp``Layout``Header``Sider``Content`、主题切换(明亮/黑暗/系统)和侧边栏折叠状态,由 Admin 和 Workbench 复用。Header 显示品牌名、版本号和控制台标题Admin 显示"管理台"Workbench 显示"工作台 · 项目名" `Sidebar``src/web/components/Sidebar/`)纯展示组件,通过 `menuItems` props 接收配置
Menu 类型定义在 `src/web/menu.tsx` 中的 `MenuItemConfig` 接口icon、label、path、value ## 页面
Sidebar`src/web/components/Sidebar/index.tsx`)是纯展示/导航组件,通过 `menuItems` props 接收菜单配置由调用方决定菜单内容和路径。Admin 传入静态路径 `/``/projects``/models`Workbench 通过 route builder`buildWorkbenchPath`)将相对菜单路径拼成 `/workbench/:projectId` 的子路径。 | 页面 | 路径 | 入口 |
| -------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
Workbench 项目上下文通过 `ProjectContext``src/web/consoles/workbench/ProjectContext.tsx` `ProjectContextValue.ts`)提供,在 `WorkbenchProjectGate` 中从 URL path param 读取 `projectId`,通过 `useProject(projectId)` 加载项目,仅 active 项目渲染工作台布局,不存在或 archived 项目显示"项目不存在或不可访问"。 | 总览 | `/` | `pages/dashboard/index.tsx` |
| 项目管理 | `/projects` | `pages/projects/index.tsx` — ProjectToolbar(Tab 切换 active/archived + 搜索 + 新建) + ProjectTable + ProjectFormModal。支持创建/编辑/归档/恢复/删除,仅 active 项目可跳转工作台。 |
### 页面概览 | 模型管理 | `/models` | `pages/models/index.tsx` — antd Tabs 切换供应商/模型视图。模型表单和表格使用 `GET /api/providers/options`。供应商表单支持预保存连通性测试(`POST /api/providers/test`),新建时 type 默认 `openai-compatible`,测试 `ok: false` 展示失败但不阻止保存。 |
| 聊天室 | `/workbench/:id` | `consoles/workbench/pages/ChatPage.tsx` |
| 页面 | 路径 | 入口文件 | | 404 | `*` | `pages/404/index.tsx` |
| -------- | ---------------- | ----------------------------------------------- |
| 总览 | `/` | `src/web/pages/dashboard/index.tsx` |
| 项目管理 | `/projects` | `src/web/pages/projects/index.tsx` |
| 模型管理 | `/models` | `src/web/pages/models/index.tsx` |
| 聊天室 | `/workbench/:id` | `src/web/consoles/workbench/pages/ChatPage.tsx` |
| 404 | `*` | `src/web/pages/404/index.tsx` |
### 项目管理页面
项目管理页面(`src/web/pages/projects/index.tsx`)使用 `ProjectToolbar`Tab 切换 active/archived + 搜索 + 新建按钮)、`ProjectTable`(列表展示、内联操作)和 `ProjectFormModal` 拆分职责。支持创建、编辑、归档、恢复和永久删除项目,仅 active 项目可点击跳转工作台。
### 模型管理页面
模型管理页面(`src/web/pages/models/index.tsx`)通过 antd `Tabs` 在同页组织供应商和模型两个视图。页面使用 `ModelsToolbar``ProviderTable``ProviderFormModal``ModelTable``ModelFormModal` 拆分职责;模型表单和模型表格必须使用 `GET /api/providers/options` 获取最小供应商选项。供应商表单支持未保存配置的连通性测试(`POST /api/providers/test`),新建供应商时 type 默认 `openai-compatible`baseURL 不设默认值。连通性测试返回 `ok: false` 时展示失败反馈;`/models` 不支持属于可忽略提醒,不阻止保存。
### 聊天页面 ### 聊天页面
Workbench 聊天页面位于 `src/web/consoles/workbench/pages/ChatPage.tsx`,组合 `ChatSidebar` `ChatPanel` 两个子组件 `ChatPage` = `ChatSidebar` + `ChatPanel`
- **ChatSidebar**`src/web/consoles/workbench/components/chat/ChatSidebar.tsx`):使用 TanStack Query 管理会话列表,提供创建删除会话操作。 - **ChatSidebar**TanStack Query 管理会话列表,创建/删除操作。
- **ChatPanel**`src/web/consoles/workbench/components/chat/ChatPanel.tsx`):使用 Vercel AI SDK `useChat` hook来自 `@ai-sdk/react`)管理聊天状态,通过 `DefaultChatTransport`来自 `ai` 包)与后端 SSE 端点通信。采用论坛式单列垂直布局,使用 antd `Card` 组件承载每条消息,通过按 `part.type` 分派渲染(文本/推理/工具调用。AI 文本使用 `streamdown` 流式 Markdown 渲染。支持编辑上一条用户消息后重新发送、重新生成最后一条 AI 回复、复制消息内容 - **ChatPanel**`useChat`@ai-sdk/react+ `DefaultChatTransport`ai 包)与后端 SSE 通信。`part.type` 分派渲染TextPartstreamdown Markdown、ReasoningPart、ToolPart四态。支持编辑重发、重新生成、复制
- **ChatInputArea**`src/web/consoles/workbench/components/chat/ChatInputArea.tsx`):使用 antd `Input.TextArea` + `Button` + `Select` 组合,支持模型切换和发送/停止操作 - **ChatInputArea**`Input.TextArea` + `Button` + `Select`(模型切换)
- **Part renderers**`src/web/consoles/workbench/components/chat/parts/``TextPart.tsx`Markdown 文本渲染)、`ReasoningPart.tsx`(推理过程)、`ToolPart.tsx`(工具调用展示,支持 input-streaming/input-available/output-available/output-error 四态)。
`use-conversations` hook 位于 `src/web/hooks/use-conversations.ts`,封装会话 CRUD 和消息获取的 fetch 调用。 ## Hooks
## Hooks 索引 | Hook | 说明 |
| ----------------------- | ----------------------------------------- |
| Hook 文件 | 说明 | | `use-meta.ts` | `/api/meta`30s 轮询5s staleTime |
| -------------------------- | ------------------------------------------------- | | `use-projects.ts` | 项目 CRUD + archive/restore |
| `use-meta.ts` | 获取 `/api/meta`30s 轮询5s staleTime | | `use-providers.ts` | 供应商 CRUD + test connection |
| `use-projects.ts` | 项目 CRUD + archive/restore API | | `use-models.ts` | 模型 CRUD + test connection |
| `use-providers.ts` | 供应商 CRUD + test connection API |
| `use-models.ts` | 模型 CRUD + test connection API |
| `use-conversations.ts` | 会话和消息 fetch 函数(不含 Query hooks | | `use-conversations.ts` | 会话和消息 fetch 函数(不含 Query hooks |
| `use-theme-preference.ts` | 主题偏好(明亮/黑暗/跟随系统)localStorage 持久化 | | `use-theme-preference` | 主题偏好 localStorage 持久化 |
| `use-sidebar-collapsed.ts` | 侧边栏折叠状态 localStorage 持久化 | | `use-sidebar-collapsed` | 侧边栏折叠 localStorage 持久化 |
## 工具函数索引 ## 工具函数
| 文件 | 说明 | | 文件 | 导出 |
| --------------- | --------------------------------------------------------------------------------------------- | | --------------- | --------------------------------------------------------------------------------------------- |
| `utils/api.ts` | `handleResponse()``handleVoidResponse()` — 通用 fetch 响应处理 | | `utils/api.ts` | `handleResponse(response, extract)``handleVoidResponse(response)` |
| `utils/time.ts` | `formatCountdown``formatDurationUnit``formatRelativeTime``isOlderThan``subtractHours` | | `utils/time.ts` | `formatCountdown``formatDurationUnit``formatRelativeTime``isOlderThan``subtractHours` |
## 更新触发条件 ## 更新触发条件

View File

@@ -1,107 +1,61 @@
# 构建与发布 # 构建与发布
本文档说明开发服务、前后端集成、生产构建、脚本维护和环境变量。 ## 开发运行
适用场景:修改 scripts/、构建流程、静态资源集成或环境变量。 - `bun run dev config.yaml` — 双进程Bun API server --watch + Vite dev server HMR
- `bun run dev:server config.yaml` — 仅后端
- `bun run dev:web` — 仅前端
## 开发期运行 开发模式 Vite proxy 将 /api/\* 转发到 Bun。
```bash
bun run dev config.yaml
```
scripts/dev.ts 同时启动两个进程:
| 进程 | 用途 |
| --------------- | --------------------------------------- |
| Bun API server | 后端 API 服务,--watch 监听变更自动重启 |
| Vite dev server | 前端 SPA、HMR 热更新 |
也可以单独启动:
```bash
bun run dev:server config.yaml # 仅启动后端 API server
bun run dev:web # 仅启动 Vite dev server
```
## 前后端集成 ## 前后端集成
开发模式下Vite 通过 proxy 将 /api/\* 转发到 Bun 生产模式Vite 构建为静态资源 → `import with { type: "file" }` 嵌入 Bun 可执行文件 → 非 API 路径 fetch fallback 处理
生产模式下,前端通过 Vite 构建为静态资源,通过 import with { type: "file" } 嵌入 Bun 可执行文件。非 API 路径由 fetch fallback 处理 路由优先级Bun routes 具体路径 > 通配符。`/api/meta` 优先于 `/api/*`
路由优先级Bun routes 具体路径 > 通配符。/api/meta 优先于 /api/\*。
## 构建 ## 构建
```bash `bun run build` 流程:
bun run build
```
构建流程: 1. `Vite build``dist/web/`
2. `Code generation``.build/static-assets.ts` + `.build/migrations-data.ts` + `.build/server-entry.ts`
3. `Bun compile``dist/alfred`
4. `Cleanup` → 清理 `.build/`
```text 构建参数:`BUN_TARGET` / `BUILD_TARGET` — 交叉编译目标平台。
1. Vite build -> dist/web/
2. Code generation -> .build/static-assets.ts + .build/migrations-data.ts + .build/server-entry.ts
3. Bun compile -> dist/alfred
4. Cleanup -> 清理 .build/ 临时目录
```
构建参数: ## 脚本
| 环境变量 | 说明 |
| ------------------------- | ---------------- |
| BUN_TARGET / BUILD_TARGET | 交叉编译目标平台 |
## 脚本说明
| 脚本 | 文件 | 说明 | | 脚本 | 文件 | 说明 |
| --------------------- | --------------------------------- | ------------------------------ | | ----------------------------- | --------------------------------- | ------------------------ |
| bun run dev | scripts/dev.ts | 双进程开发服务 | | dev | scripts/dev.ts | 双进程开发服务 |
| bun run dev:server | src/server/dev.ts | 仅启动后端 API server | | dev:server | src/server/dev.ts | 仅后端 |
| bun run dev:web | Vite CLI | 仅启动 Vite dev server | | dev:web | Vite CLI | 仅前端 |
| bun run build | scripts/build.ts | Vite -> codegen -> Bun compile | | build | scripts/build.ts | Vite codegen compile |
| bun run schema | scripts/generate-config-schema.ts | 生成配置 JSON Schema | | schema | scripts/generate-config-schema.ts | 生成 JSON Schema |
| bun run schema:check | scripts/generate-config-schema.ts | 检查配置 JSON Schema 同步 | | schema:check | (同上) | 检查 Schema 同步 |
| bun run clean | scripts/clean.ts | 清理构建缓存与临时文件 | | clean | scripts/clean.ts | 清理构建缓存 |
| bun run version:patch | scripts/bump-version.ts | 升迁 patch 版本 | | version:patch/minor/major/set | scripts/bump-version.ts | 版本升迁 |
| bun run version:minor | scripts/bump-version.ts | 升迁 minor 版本 |
| bun run version:major | scripts/bump-version.ts | 升迁 major 版本 |
| bun run version:set | scripts/bump-version.ts | 显式设置版本号 |
| bun test | (Bun 内置) | 运行全部测试 |
内部辅助脚本(不直接对外开放): 内部辅助`scripts/bump-version-logic.ts`(版本逻辑)、`scripts/generate-migrations-data.ts`(构建时嵌入 SQL
| 文件 | 说明 | ## 配置文件
| ----------------------------------- | ---------------------------------------------- |
| scripts/bump-version-logic.ts | 版本号升迁/设置的逻辑实现 |
| scripts/generate-migrations-data.ts | 构建时将 drizzle/\*.sql 嵌入为 TypeScript 模块 |
## 项目配置文件
| 文件 | 用途 | | 文件 | 用途 |
| -------------------- | --------------------------- | | -------------------- | -------------------- |
| package.json | 项目信息、脚本、依赖声明 | | package.json | 项目信息、脚本、依赖 |
| tsconfig.json | TypeScript 配置 | | tsconfig.json | TypeScript 配置 |
| eslint.config.js | ESLint 规则 | | eslint.config.js | ESLint 规则 |
| commitlint.config.js | commitlint 提交信息格式校验 | | commitlint.config.js | 提交信息格式校验 |
| .prettierrc.json | Prettier 格式化规则 | | .prettierrc.json | Prettier 规则 |
| .lintstagedrc.json | lint-staged 配置 | | .lintstagedrc.json | lint-staged 配置 |
| config.example.yaml | 配置文件示例 | | config.example.yaml | 配置示例 |
| config.schema.json | 配置文件 JSON Schema | | config.schema.json | 配置 JSON Schema |
| vite.config.ts | Vite 构建配置 | | vite.config.ts | Vite 构建配置 |
| bunfig.toml | Bun 配置 | | bunfig.toml | Bun 配置 |
| drizzle.config.ts | Drizzle ORM 配置 | | drizzle.config.ts | Drizzle ORM 配置 |
## 验证期望
| 变更类型 | 验证方式 |
| ---------------- | -------------------- |
| 构建脚本 | bun run verify |
| 静态资源集成 | bun run build |
| 配置 schema 同步 | bun run schema:check |
| 发布前完整验证 | bun run verify |
## 更新触发条件 ## 更新触发条件
修改开发服务、前后端集成、构建产物、脚本参数或验证方式时,必须更新本文档。 修改开发服务、前后端集成、构建产物、脚本参数或验证方式时,必须更新本文档。