You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.4 KiB
6.4 KiB
AI八荣八耻
- Shame in guessing APIs, Honor in careful research.
- Shame in vague execution, Honor in seeking confirmation.
- Shame in assuming business logic, Honor in human verification.
- Shame in creating interfaces, Honor in reusing existing ones.
- Shame in skipping validation, Honor in proactive testing.
- Shame in breaking architecture, Honor in following specifications.
- Shame in pretending to understand, Honor in honest ignorance.
- Shame in blind modification, Honor in careful refactoring.
必须遵循
- 注意代码的解耦,做到高内聚,低耦合
- 安装依赖时,必须写死依赖的版本,禁止任何升级的可能,如存在需要升级的场景,必须手动执行安装新版本命令
- 新建的mono包必须在根目录安装
- 使用nuxt时遇到不清楚的,必须先加载nuxt-remote查询文档再进行分析
- 能够用toast提示的尽量用toast
- 数据库schema编写完成之后,必须使用命令进行迁移,不能自己生成
代码抽离与复用
- 编写任何前端组件/工具函数时,必须评估是否可以抽离为通用模块,加入对应 packages(bolt-ui、common 等)
- bolt-ui 只放基础通用 UI 组件(Button、Input、Modal、Container 等),业务相关组件留在
app/components/ - 开发时随时查看 bolt-ui 已有组件(Button、ConfigProvider、Container 等),优先复用,避免重复造轮子
- 新增 bolt-ui 组件需遵循现有模式:
components/<Name>/src/<Name>.vue+index.ts(使用withInstall注册),并在components/index.ts中导出 - 必须时刻注意bolt-ui中readme.md的更新
设计方案
开发页面与组件时必须参考 DESIGN.md
E2E 测试
架构
- 框架:Playwright 1.49.1 +
@nuxt/test-utils3.15.4 - 测试目录:
e2e/(specs/、helpers/、fixtures/) - 测试服务器:build + preview 模式,
global-setup.ts自动执行 build → migrate → seed → spawn server - 数据库隔离:独立 SQLite 文件
packages/drizzle-pkg/db.test.sqlite,workers=1 避免并发 - 验证码注入:业务代码分支方式,
server/service/captcha/challenge.ts中E2E_TEST_MODE门控返回固定验证码 - 环境变量:
.env.test文件,由global-setup.ts和playwright.config.ts内部代码解析注入 - Mock LLM 服务器:global-setup 中内联启动,端口 3600,OpenAI 兼容 SSE 流式响应
运行命令
bun run test:e2e # 运行全部 E2E 测试(headless)
bun run test:e2e:headed # 有头模式运行
bun run test:e2e:ui # Playwright UI 模式
注意:Playwright 命令必须传
--config=e2e/playwright.config.ts,否则找不到 config 文件会跳过 globalSetup。package.json 脚本中已包含。
测试文件
| 文件 | 测试数 | 说明 |
|---|---|---|
specs/smoke.spec.ts |
5 | 冒烟测试:页面可访问、验证码 API、全局配置 API |
specs/auth-login.spec.ts |
7 | 登录流程:表单验证、成功登录、失败场景、登出 |
specs/auth-register.spec.ts |
6 | 注册流程:表单验证、成功注册、重复用户名、注册后登录 |
specs/auth-guard.spec.ts |
9 | 路由守卫:未登录重定向、已登录访问、白名单页面 |
specs/agent-chat.spec.ts |
10 | Agent 对话:欢迎页、输入框、发送消息、流式回复、连续对话 |
specs/agent-documents.spec.ts |
10 | Agent 文档:列表、详情、类型筛选、搜索、编辑、删除、权限守卫、导航 |
Mock LLM 架构
Agent 对话测试依赖 Mock LLM 服务器,在 global-setup.ts 中内联启动:
global-setup.ts 流程:
1. 加载 .env.test
2. 删除旧测试数据库
3. build Nuxt 应用
4. 运行数据库迁移
5. 运行 seed(创建 bootstrap admin 用户)
6. 启动 Mock LLM 服务器(端口 3600,OpenAI 兼容 SSE)
7. 向测试数据库插入 LLM provider + model + userConfig
8. 启动 preview 服务器(端口 3400)
9. 等待服务器就绪
Mock LLM 服务器(内联在 global-setup.ts 中):
- 监听端口:
MOCK_LLM_PORT(默认 3600) - 端点:
POST /v1/chat/completions - 响应格式:OpenAI 兼容 SSE 流式(
data: {"choices":[{"delta":{"content":"x"}}]}) - 固定回复内容:
你好!这是一个测试回复。(逐字符流式输出,20ms 间隔) - 不校验 API key,不校验请求体
数据库 seed(步骤7,直接 SQL 插入):
llm_providers表:id=1, user_id=1, name="mock-provider", slug="mock-provider", base_url="http://localhost:3600/v1", parse_mode="openai-compatible"llm_models表:id=1, provider_id=1, name="mock-model", model_id="mock-model", enabled=1, supports_tools=0user_configs表:user_id=1, key="preferredLlmModelId", value="1", value_type="number"
注意:Mock LLM 逻辑内联在 global-setup.ts 中,不通过 import 外部 .ts 文件。原因是 Playwright + Node ESM 无法正确解析
.ts扩展名导入。独立文件e2e/mock-llm-server.ts仍保留但不再被导入。
编写测试注意事项
- 用户名规则:
/^[a-zA-Z0-9_]{3,20}$/(3-20字符,仅字母数字下划线),生成动态用户名时注意长度 toHaveURL匹配完整 URL(含 host),正则应匹配路径结尾而非开头- 已登录状态测试:通过 UI 登录设置 cookie,不要用
requestcontext(cookie 不共享到page) - 避免使用
waitForLoadState("networkidle"),部分页面有持续网络请求会导致超时 - SSR 中间件重定向可能不带
?redirect=参数,测试应兼容此情况 execSync的stdio必须用"pipe"而非"inherit",否则在 Playwright 子进程中可能导致管道阻塞- Agent 对话测试间会共享数据库 session,登录后需点击"新建会话"按钮(
.new-chat-btn)避免跨测试 session 污染 - 示例卡片(
.example-card)点击后直接发送消息,不是填充输入框 - Agent 消息 DOM:用户消息
.agent-message.is-user .user-bubble,助手消息.agent-message.is-assistant .agent-markdown - Agent 输入 DOM:
textarea.agent-textarea,发送按钮button.btn-send,停止按钮button.btn-stop - 登录页面 DOM:
#login-username、#login-password、#login-captcha,提交button[type="submit"] - 固定验证码:
FIXED_CAPTCHA常量在e2e/fixtures/test-users.ts - 测试用户:
E2E_ADMIN(username/password)在e2e/fixtures/test-users.ts