内容
# qa-probe
**找出页面空白的原因 - 在5分钟内。**
qa-probe 是一个 Node.js 命令行工具,它读取您的 React 前端,映射每个 API 调用到其后端路由,实时探测这些端点,并告诉您问题的原因 - 而不仅仅是一个状态码。
```
总体得分:74/100
检测到的根本原因:
empty_db: 5 个路由 需要初始化数据库
feature_flag_disabled: 3 个路由 需要启用 HAS_BILLING, HAS_REPORTS
contract_mismatch: 1 个路由 前端调用 /api/users/,后端提供 /users
路由 得分 状态 根本原因
----------- ----- -------- ----------------------
/dashboard 100 健康
/users 80 健康 empty_db
/billing 0 损坏 feature_flag_disabled
/reports 50 降级 empty_db
/settings 85 健康
```
它最适合用于由 **FastAPI, Express, Next.js, GraphQL, 或 tRPC** 支持的 React 应用,并且有可用的 OpenAPI 规范。由 LightShield SIEM 团队构建,并在生产 SIEM 中经过战斗测试。
---
## 它解决的问题
您的仪表板加载了。没有任何崩溃。但是每个表格都是空的,每个图表都显示零,您不知道为什么。原因几乎总是以下之一:
- 前端调用 `/api/users/` 但后端路由是 `/api/users` (尾部斜杠)
- 功能标志(`HAS_BILLING=false`)静默禁用了整个路由器
- 数据库已连接但表格没有行
- 后端重构了字段名称,前端仍读取旧名称
- 端点缺少身份验证守卫,或在没有令牌的情况下泄漏数据
qa-probe 构建了一个源感知映射,从前端调用到实时后端响应,然后用修复提示解释每个故障。它补充了 Playwright(用户旅程)和 Schemathesis(契约模糊测试)- 它是回答“为什么这个页面是空白的?”的层。
---
## 快速开始
### 1. 安装
```bash
npx qa-probe run # 不需要安装即可使用
# 或
npm install -g qa-probe
```
### 2. 创建配置文件
`qa-probe.config.js` 在您的项目根目录:
```js
module.exports = {
baseUrl: 'http://localhost:8000', // 您的后端
frontendSrc: './frontend/src', // 您的 React 源代码
routerFile: './frontend/src/App.tsx', // 您的路由器文件
auth: {
type: 'bearer',
loginUrl: '/auth/login',
credentials: {
username: process.env.QA_USER, // 永远不要硬编码凭证
password: process.env.QA_PASS,
},
tokenPath: 'access_token',
},
};
```
### 3. 运行它
```bash
QA_USER=tester QA_PASS=secret npx qa-probe run
```
qa-probe 将解析您的前端,获取 `/openapi.json`,使用真实身份验证探测每个端点,并将完整报告写入 `.qaprobe/`(`report.md`、`report.json`、`ai-context.md`、`report.html`)。终端中将打印一个摘要表格。
---
## 了解报告
**路由状态**
| 状态 | 含义 |
|----------|---------|
| 健康 | 端点响应,数据存在,模式有效 |
| 降级 | 有效但存在问题(空数据,响应时间慢) |
| 损坏 | 无法访问,404,5xx,或安全/逻辑故障 |
**常见根本原因**
| 根本原因 | 发生了什么 | 需要做什么 |
|-------------------------|---------------|------------|
| `feature_flag_disabled` | 路由未注册(`HAS_*` 标志为假) | 启用标志并重启 |
| `contract_mismatch` | 存在类似路由(斜杠/大小写) | 对齐前端路径 |
| `missing_route` | 404,不在 OpenAPI 规范中 | 修复拼写错误或 `include_router()` |
| `empty_db` | 200 OK 但数组为空 | 初始化数据库 |
| `precondition_required` | 428 - 术语/注册/MFA 门户不满足 | 为探测帐户清除门户 |
| `auth_scope_mismatch` | 401/403 - 错误角色/范围 | 使用具有所需权限的用户 |
| `schema_mismatch` | 字段被重命名/删除 vs 规范 | 对齐前端、后端和规范 |
| `auth_bypass` | 端点在没有身份验证的情况下返回 200 | 添加缺少的身份验证守卫 |
| `assertion_failed` | 响应违反了声明的不变性 | 修复响应或声明 |
| `server_error` | 5xx | 检查后端日志 |
**每个结果都是可验证的。** 每个诊断都有其 **证据** (请求、响应快照、时间)和 **置信度** 级别 - `high`、`medium` 或 `none`。`confidence: none` / `unknown` 结果明确为 **不是** 确认通过。
**得分:** 每个路由的得分为 0-100;总体得分为平均值。使用 `--fail-under 80` 使 CI 在得分下降时失败。
---
## 用例
- **“为什么这个页面是空白的?”** - 每天都遇到这种情况。在一次运行中获取根本原因和修复提示,而不是深入研究网络标签和日志。
- **CI 门户** - `qa-probe run --fail-under 80` 在页面回归时阻止部署。
- **演示/预发布签发** - 在客户电话之前确认环境实际工作,而不是仅仅返回 200。
- **捕获合同漂移** - 后端重构重命名字段或移动路由;qa-probe 标记受影响的端点和前端调用。
- **安全烟雾** - 查找缺少身份验证守卫或泄漏 PII 的端点(可选,读取,只需参见安全检查)。
- **逻辑检查** - 在不编写测试套件的情况下断言响应不变性(有效枚举值,非负计数,要求字段)。
- **AI 辅助调试** - 让 Claude、Cursor 或 Codex 查询 QA 状态并用普通英语解释故障(见下文)。
---
## 与 AI 助手一起使用(Claude Code、Cursor、Codex)
qa-probe 配备了 **模型上下文协议(MCP)服务器**。将您的 AI 助手指向它,助手可以直接读取您的 QA 数据并直接解释故障 - 无需手动读取报告。
### 设置
运行 qa-probe 一次以填充缓存:
```bash
npx qa-probe run
```
然后添加 MCP 服务器。对于 **Claude Code** / **Cursor**,在您的存储库根目录中添加 `.mcp.json`:
```json
{
"mcpServers": {
"qa-probe": {
"command": "npx",
"args": ["qa-probe", "mcp"]
}
}
}
```
重启助手。现在,您可以问:
- “/reports 为什么显示没有数据?”
- “哪些页面会在用户端点关闭时损坏?”
- “显示所有损坏的路由。”
- “将空的 /alerts 结果标记为预期。”(记录反馈,重新应用下次运行)
### 可用的 MCP 工具
| 工具 | 提问 |
|------|--------|
| `qa_probe_get_report` | “显示所有损坏的路由及其得分” |
| `qa_probe_explain_failure`| “/reports 为什么显示没有数据?” |
| `qa_probe_probe_endpoint` | “GET /users 当前是否返回数据?” |
| `qa_probe_get_graph` | “哪些后端路由调用 /dashboard?” |
| `qa_probe_get_blast_radius`| “如果用户端点关闭,哪些页面会损坏?” |
| `qa_probe_suggest_fix` | “关于 feature_flag_disabled 我应该怎么做?” |
| `qa_probe_run_analysis` | “运行完整的 QA 检查并给我总结” |
| `qa_probe_label` | “将此发现标记为预期/真正的问题” |
MCP 输出经过净化处理 - SQL 错误、堆栈跟踪和表名在到达助手之前被编辑。原始数据保留在磁盘上。结果带有其证据和置信度,并且 `explain_failure` 返回一个纯英语的 `trust` 注释,当发现未经验证时,助手不会将猜测报告为通过。
您也可以简单地在 AI 编码工具中打开 `qa-probe` 文件夹(或带有 `.qaprobe/` 的项目),并要求它读取 `ai-context.md` - 一个紧凑的、面向 LLM 的摘要,在每次运行时编写。
---
## CLI 命令
```
qa-probe run [--config <path>] [--fail-under <N>] 分析 + 探测 + 报告
qa-probe analyze [--config <path>] 构建依赖图
qa-probe probe [--config <path>] 探测所有端点
qa-probe report [--config <path>] [--fail-under <N>] 得分,分类,写入报告
qa-probe label <endpoint> <verdict> [-r <reason>] 记录反馈(稍后重新应用)
qa-probe fix [--config <path>] [--apply] [--pr] 生成修复差异
qa-probe mcp [--config <path>] 启动 MCP 服务器(stdio)
```
`--fail-under <N>` 在整体得分低于 N 时退出并返回非零值(一个 CI 门户)。
---
## 功能
- **源感知映射** - Babel 解析您的前端;检测 axios/fetch 调用和常见的钩子模式;从 React Router(JSX 和 `createBrowserRouter`)和 TanStack Router 中提取路由。
- **实时探测,真实身份验证** - bearer、cookie、api-key 或 none。并发性有限,具有硬性每请求截止日期,因此流式端点永远不会挂起运行。
- **根本原因分类** - 大约 25 个原因,每个原因都有一个修复提示。
- **ID 链接** - 探测集合,首先获取一个真实 ID,然后使用它探测带有 ID 的详细路由而不是猜测值(默认开启)。
- **自适应基线** - 从最近的运行中学习每个端点的正常延迟和行数,并从其自身标记偏差。没有模型;完全可检查。
- **反馈** - `qa-probe label`(或 MCP 工具)记录一个判决,该判决在未来运行中重新应用。作用域标签自动撤销,如果行为发生变化,因此它们不能隐藏回归。
- **安全检查(可选)** - 匿名身份验证绕过探测,PII 扫描和每人权限提升矩阵。仅 GET;从不发出写入。
- **响应断言** - 声明不变性(`in`、`type`、`gte`、`pattern`、`present`、`minItems`,...),qa-probe 在每个 2xx 响应中验证它们。
- **写入流程(可选,变异)** - 完整的创建/读取/更新/删除链,保证清理。默认关闭;仅适用于一次性/测试租户环境。
- **SSE 和 WebSocket 检查**,模式漂移检测,爆炸半径,回归差异,覆盖率和 HAR 导入用于动态前端。
- **OpenAPI 自动发现** - 尝试常见的规范路径并支持本地规范文件,因此较少的应用程序会回退到无头模式。
---
## 配置
上面的示例足以开始使用。关键选项(除非另有说明,否则均为可选):
```js
module.exports = {
baseUrl: 'http://localhost:8000', // 必需
frontendApiPrefix: '/api', // 匹配调用路由时剥离
framework: 'fastapi', // fastapi | express | nextjs | graphql | trpc | generic
openApiUrl: '/openapi.json', // 如果丢失,则自动发现回退
openApiFile: null, // 或从本地文件加载规范
frontendSrc: './frontend/src',
routerFile: './frontend/src/App.tsx',
auth: { type: 'bearer', loginUrl: '/auth/login',
credentials: { username: process.env.QA_USER, password: process.env.QA_PASS },
tokenPath: 'access_token' },
probe: {
concurrency: 5,
timeoutMs: 10000,
idDiscovery: true, // 默认开启
safePosts: [], // 安全读取的 POST 端点
pathParamValues: { id: '1' }, // {id} 等的回退值
ignoreHTTPSErrors: false, // 开发/预发布仅
},
// 可选附加项:
security: { enabled: true, piiAllow: ['email'] },
assertions: { 'GET /alerts': [{ field: 'items[].severity', in: ['low','high','critical'] }] },
writeFlows: { enabled: false, flows: [] },
analyze: { har: { enabled: false, harFile: './traffic.har' } },
output: { dir: '.qaprobe', formats: ['json', 'markdown', 'ai-context', 'html'] },
seedCommand: 'npm run db:seed', // 显示在 empty_db 修复提示中
};
```
`qa-probe.config.js` 作为 JavaScript 执行(如 ESLint 或 Jest 配置文件)。永远不要硬编码凭证 - 使用环境变量。
---
## 工作原理
三个阶段,每个阶段都缓存,以便您可以独立重新运行它们。
1. **分析** - 解析前端 AST,提取路由,获取 OpenAPI 规范(或导入 HAR),并使用爆炸半径构建依赖图。
2. **探测** - 一次身份验证,然后实时探测每个发现的端点:HTTP、SSE、WebSocket,具有硬性截止日期和 ID 链接。
3. **报告** - 分类根本原因,应用基线和反馈,路由得分 0-100,并写入 JSON / Markdown / ai-context / HTML 报告。
---
## vs 其他工具
| 功能 | qa-probe | Schemathesis | Playwright | Postman |
|---|:---:|:---:|:---:|:---:|
| 前端到后端路由映射 | 是 | 否 | 否 | 否 |
| 带有修复提示的根本原因标签 | 是 | 否 | 否 | 否 |
| 实时探测,真实身份验证 | 是 | 是 | 是 | 是 |
| 基于属性的契约模糊测试 | 否 | 是 | 否 | 否 |
| 用户旅程 E2E | 否 | 否 | 是 | 否 |
| 用于 AI 助手的 MCP 服务器 | 是 | 否 | 否 | 否 |
| CI 退出代码门户 | 是 | 是 | 是 | 是 |
将 Schemathesis 用于彻底的契约模糊测试,将 Playwright 用于用户旅程。qa-probe 映射并解释;如果需要深入了解它所暴露的内容,请使用其他工具。
---
## 安全和安全使用
- 凭证在运行期间保存在内存中,永远不会写入任何报告。
- 配置文件作为 JavaScript 执行 - 只需运行 qa-probe 时信任配置文件。
- `ignoreHTTPSErrors: true` 禁用 TLS 验证;仅开发/预发布。
- 安全探测仅为 GET 并且永远不会写入。写入流程默认关闭,并在自己清理后关闭;仅适用于一次性环境。
要报告漏洞,请参阅 [SECURITY.md](SECURITY.md)。
---
## 已知限制
- 检测可见的 HTTP 调用和常见的钩子模式。生成的 SDK 客户端、GraphQL 客户端、tRPC 路由器和自定义服务层可能需要适配器 - 或使用 HAR 导入从真实流量中发现它们。
- 由任意工厂函数构建的动态 URL 未被检测。
- 最佳结果需要 OpenAPI 规范;无头模式会失去规范依赖的规则,但仍会检测观察到的形状漂移。
---
## 贡献
参见 [CONTRIBUTING.md](CONTRIBUTING.md)。贡献需要 [开发者证书来源](https://developercertificate.org/) 签署(`git commit -s`)。
---
## 品牌和商标
"qa-probe"、“LightShield”和“LS-SIEM”是 LS-SIEM LLP 的商标。Apache License 不授予使用这些名称或徽标的权限。
---
## 许可证
Copyright (c) 2026 LS-SIEM LLP - 由 LightShield SIEM 团队创建和维护。
根据 Apache License, Version 2.0 授权 - 参见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。您可以在 Apache-2.0 条款下使用、修改和重新分发 qa-probe;版权和上述商标仍归 LS-SIEM LLP 所有。