Files
Alfred/docs/development/README.md

217 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 开发文档
本文档是 alfred 的开发入口,包含**全部开发规范**和专题索引。AI 工具和开发者应首先阅读本文档掌握所有约束,再按需查阅专题文档获取实现细节。
适用场景:修改源码、测试、构建脚本、开发流程、架构边界或项目工程规则。
## 专题索引
| 文档 | 内容 |
| ---------------------------------- | ----------------------------------------------------------------- |
| [architecture.md](architecture.md) | 项目结构、启动流程、运行时流程、HTTP 请求流程、前后端边界 |
| [backend.md](backend.md) | 后端实现细节:模块 API、工具函数索引、数据访问函数清单、AI 层说明 |
| [frontend.md](frontend.md) | 前端实现细节运行时代码结构、组件索引、页面组成、hooks/工具清单 |
| [release.md](release.md) | 开发服务、前后端集成、构建、脚本、环境变量 |
| [../README.md](../README.md) | 文档路由、文档归属矩阵、文档更新规则 |
---
# 开发规范
以下规范是所有代码变更必须遵守的约束。AI 工具必须严格遵守,开发者 review 时以此为准。
## 一、全局规则
### 语言与环境
- 使用中文编写注释、文档和项目内交流内容。
- 仅使用 bun 作为包管理器,禁止使用 npm、pnpm、yarn。
- 运行工具使用 bunx禁止使用 npx、pnpx。
- 当前项目无需考虑向前兼容。
### 依赖引入
**后端**:新增依赖前必须按以下优先级检查,上层已有方案则不得引入新依赖:
| 优先级 | 来源 | 典型用途 |
| ------ | ------------ | ---------------------------------------------------- |
| 1 | Bun 内置 API | Bun.serve、Bun.file、Bun.YAML、Bun.spawn、bun:sqlite |
| 2 | es-toolkit | 类型判断、深度比较、并发控制 |
| 3 | 标准 Web API | Headers、fetch、AbortController |
| 4 | 主流三方库 | pino、@sinclair/typebox、ajv、drizzle-orm |
| 5 | 自行实现 | 仅在以上都无法满足时 |
**前端**:新增代码优先复用已有组件、工具和依赖库,不引入新依赖。确需新增依赖时先说明原因。
### Git 提交
- 提交信息使用中文,格式为 `类型: 简短描述`
- 提交类型限定为:`feat``fix``refactor``docs``style``test``chore`
- 多行提交描述时,标题和正文之间空一行。
### 目录边界
| 目录 | 约定 |
| ------------------- | -------------------------------------------------------------------- |
| `src/server/` | Bun 后端代码,不能 import src/web/HTML import 集成除外 |
| `src/server/db/` | SQLite 数据库模块,包含 schema、connection、migration 和 data access |
| `src/server/ai/` | AI Provider Registry 构建与连接测试 |
| `src/web/` | React 前端,不能 import src/server/ 运行时实现 |
| `src/shared/` | 前后端共享 TypeScript 类型 |
| `scripts/` | 独立运行脚本,可 import 项目源码 |
| `drizzle/` | Drizzle Kit 生成的 SQL migration 文件(开发期产出) |
| `tests/` | 测试目录,结构镜像 src/ |
| `docs/user/` | 用户使用、配置、部署和排障文档 |
| `docs/development/` | 架构、后端、前端、发布开发文档 |
| `openspec/` | OpenSpec 变更管理与规格文档 |
### 类型与配置
- 共享类型以 `src/shared/api.ts` 为唯一源头。
- 应用常量以 `src/shared/app.ts` 为唯一源头。
- 版本号以 `package.json.version` 为唯一源头。
- 前端不得 import `src/server/` 下的任何文件。
- 配置加载流程固定为unknown → AuthoringConfig → NormalizedConfig → ValidatedConfig → ServerConfig。
- Ajv 保持严格拒绝模式:不开类型强制转换、不注入默认值、不自动删除未知字段。
- 新增或修改配置字段时必须同步更新 TypeBox schema fragments、`config.schema.json`、测试和对应用户文档。
### 后端日志
- 后端运行时代码统一通过 Logger 接口输出日志,禁止直接使用 `console.*`(仅 `src/server/logger.ts` 的实现类内部可用)。
- 敏感信息自动 redact `authorization``cookie``password` 等字段。
### API 路由
- 路由文件位于 `src/server/routes/`,每个端点一个文件。
- 路由通过 `server.ts``Bun.serve({ routes })` 声明式注册。
- 新增路由步骤:创建 handler 文件 → 在 `server.ts` 注册 → 在 `tests/server/` 添加测试。
### 前端数据层
- 统一使用 `fetch`,不引入 axios。
- 错误抛异常,由 TanStack Query 的 error 状态承接。
- 前端 fetch 返回类型必须匹配后端真实 JSON 形状;后端返回包装对象(如 `{ project: Project }`)时,应声明对应响应类型并在 hook 内提取业务对象。
- 不引入额外状态管理库。TanStack Query 承担服务端状态,组件内状态使用 `useState`
---
## 二、前端红线
### 组件红线
- 优先使用 antd 组件默认能力和 props 配置行为,不额外改写组件视觉。
- 全局使用 `ConfigProvider` 配置中文 locale 和主题切换,不在 CSS 中硬编码亮色或暗色分支。
- 需要 message、modal、notification 等应用级能力时,在 `ConfigProvider` 内包裹 `App`(代码中别名为 `AntApp`),组件内通过 `App.useApp()` 获取。
- 页面组件保持编排职责,组合 hooks 和展示组件;当页面同时承担查询、筛选、分页、表格列、弹窗表单和 mutation 时,应按功能边界拆分。
### 样式红线
- **严禁**在组件中使用 `style` 属性内联样式。
- **严禁**通过 CSS 覆盖 antd 组件内部类名(`.ant-*`)。
- **严禁**使用 `!important`
- **严禁**使用硬编码色值,颜色统一使用 antd CSS 变量(`var(--ant-*)`)。
- 默认不引入 Tailwind、Sass、Less、CSS-in-JS 等额外样式方案;确需引入时必须先说明原因和影响范围。
### 样式指导原则
- antd 承担主视觉系统,项目 CSS 只补足页面外壳和局部布局,不另起一套样式体系。
- 样式选择优先级antd 默认能力 → antd props → antd 布局组件 → theme token → antd CSS 变量 → 全局 CSS。
- 全局 CSS 仅承载应用外壳和基础样式,类名使用 `app-*` 前缀,禁止泛名类(如 `.container``.title`)。
- 当样式需求增长到需要就近维护时,使用 CSS Modules 与页面/组件同级放置。
### 表单与交互
- Modal + Form 提交使用 `Form onFinish` 处理业务提交,`Modal onOk` 只触发 `form.submit()`
- 不在 `Modal onOk` 中直接执行异步 `validateFields` 和提交逻辑。
- 文本必填字段同时配置 `required: true``whitespace: true`,保持前后端校验一致。
- 操作确认优先使用 `Popconfirm`,成功/失败反馈优先使用 antd message。
### 错误边界
- 生产入口必须启用 `ErrorBoundary`
- `ReactQueryDevtools` 仅在 `import.meta.env.DEV` 条件下渲染。
---
## 三、测试规范
### 后端测试
- API 路由集成测试必须通过真实 `startServer` 覆盖路由注册、HTTP method、fallback、响应 header 和核心错误路径。
- SQLite 相关测试必须复用 `tests/helpers.ts` 中的测试数据库 helper不要在测试文件内分散实现临时目录清理。
- DAO 和路由边界测试应优先使用真实 migration 初始化测试库。
- logger/bootstrap 中预期的 fallback 输出必须在测试中捕获并断言,正常通过的测试不应污染 stdout/stderr。
### 前端测试
- 测试目录为 `tests/web/`,结构对应 `src/web/`
- 组件测试使用 jsdom 和 `@testing-library/react`,测试用户行为而非实现细节。
- 断言优先基于用户可见文本、role、按钮和交互结果不依赖 `.ant-*` 内部类名。
- 系统边界fetch mock、路由、QueryClientProvider优先复用 `tests/web/test-utils.tsx`
- 数据驱动页面至少覆盖请求 URL/query、method/body、成功后的用户可见结果以及关键错误路径。
- ErrorBoundary、hooks 纯逻辑和 fetch helper 应使用单元测试覆盖异常回退,页面测试只保留真实用户路径。
---
## 常用命令
| 命令 | 说明 |
| -------------------------------- | -------------------------------------- |
| `bun install` | 安装依赖 |
| `bun run dev config.yaml` | 启动双进程开发环境 |
| `bun run dev:server config.yaml` | 仅启动后端 API server |
| `bun run dev:web` | 仅启动 Vite dev server |
| `bun run schema` | 生成 config.schema.json |
| `bun run schema:check` | 检查导出 schema 是否同步 |
| `bun run typecheck` | TypeScript 类型检查 |
| `bun run lint` | ESLint 和 Prettier 格式检查 |
| `bun run format` | Prettier 自动格式化 |
| `bun run format:check` | Prettier 格式检查 |
| `bun test` | 运行全部测试 |
| `bun run check` | schema:check + typecheck + lint + test |
| `bun run build` | 构建生产可执行文件 |
| `bun run verify` | check + build 完整验证 |
| `bun run clean` | 清理构建缓存与临时文件 |
| `bun run version:patch` | 升迁 patch 版本x.y.Z |
| `bun run version:minor` | 升迁 minor 版本x.Y.0 |
| `bun run version:major` | 升迁 major 版本X.0.0 |
| `bun run version:set` | 显式设置版本号 |
## 质量门禁
代码变更必须按影响范围执行验证。
| 变更类型 | 必跑命令 |
| -------------------------- | ------------------------------------------------------------- |
| 常规代码变更 | `bun run check` |
| 构建、部署、前后端集成变更 | `bun run verify` |
| 配置 schema 变化 | `bun run schema``bun run schema:check``bun run check` |
| SQLite 测试基础设施变化 | 相关单文件测试 + SQLite 聚焦 `--rerun-each` + `bun run check` |
| 仅文档变更 | 检查链接、索引和文档归属一致性 |
正式提交或影响构建产物时优先运行 `bun run verify`。如果因环境限制无法执行完整验证,必须在收尾说明中记录未执行项和原因。
## 已知设计决策
| 决策 | 原因 |
| -------------------------- | ----------------------------------------------------------------------------------------- |
| Provider.apiKey 返回给前端 | 个人项目apiKey 非严格密码,前端需要展示和编辑。如需保护,应改为返回脱敏值或仅后端存储。 |
## 文档影响分析
每次代码变更都必须执行文档影响分析。
| 如果变更影响 | 更新 |
| ------------------------------------------ | ------------------------------------------ |
| 用户可见行为、配置、部署、运行行为 | `docs/user/` 对应文档 |
| 开发流程、架构、测试、构建发布流程 | `docs/development/` 对应文档 |
| 项目定位、快速开始、核心能力列表、文档导航 | `README.md` |
| 文档同步规则或文档归属矩阵 | `docs/README.md``openspec/config.yaml` |
| 开发规范变化 | 本文档对应章节 |
如果无需更新文档,必须在收尾说明中说明原因。详细规则见 [文档总览](../README.md)。
## 更新触发条件
修改常用命令、质量门禁、开发规范(任何章节)、目录边界或开发文档索引时,必须更新本文档。