Skip to content
Clone

API 契约交叉审计(view/app ⇄ KenApi)

本轮目标:找出与 8dfc4c1b 同类的接口契约错配——即「前端发的东西后端不认,或后端返回的东西前端按错的形状用」。 每个域一份报告:audit/<domain>.md,只读源码,不改业务代码。

判定基线

前端的唯一入口是 view/app/src/services/api:

  • Apis.<tag>.<op>({ pathParams, params, data }) 走 invoke(),OPS 表决定 path/query/body 的位置。 该表由 scripts/gen-api-ops.py 从 packages/apiclient 的签名生成,已与生成客户端一致——所以本轮的 错配只可能出在「前端调用方填的字段名/形状」与「后端真契约」之间。
  • 响应信封:{ code, message, data, error, error_code, request_id },code == HTTP status; data: null 是成功无内容。列表统一 { items, total, limit, offset }(chat 另有 has_more 等)。
  • 401 → /auth/login?callback_url=…,无令牌刷新。

五类问题(每条发现必须归到其中一类)

类名称含义
Qquery 名不符params 里的字段名不在后端 query 结构体 / 生成 *Params 类型里,会被 400 拒绝
Bbody 名不符data 里的字段名或嵌套形状与生成的 *Body/*Cmd 类型不一致(PATCH 三态:缺省=不变、null=清空、值=设置)
Ppath 顺序/数量pathParams 的键序与路由段顺序不一致,或段数不足
R响应形状误用把分页对象当数组、把数组当分页、字段名过时(如 sha vs id)、data: null 未处理
G幽灵端点调用了已被删除/改名的端点,或 ALIASES/MISSING_OPS 命不中,实际返回 501/404

每条的取证要求

  1. 前端:view/app/src/...:line 原始调用片段。
  2. 后端:lib/.../*.rs 的 query/body 结构体或 utoipa::path 声明(路径 + 行号)。
  3. 生成类型:packages/apiclient/<tag>/<op>.schemas.ts 的字段清单。
  4. 能实证就给 curl:http://localhost:7051/api/v1/...(公开仓库 demo/demorepos 可匿名读; 需要登录的端点记「未实证」并说明原因)。400 的响应体会直接点名字段,最有力。

报告格式(严格)

# <domain>

## 结论
- 检查调用点 N 个 / 操作 M 个
- 确认问题 X 条(Q a / B b / P c / R d / G e),可疑 Y 条,未实证 Z 条

## 确认问题
| # | 类 | 位置 | 操作 | 现象 | 后端依据 | 建议修法 |
|---|---|---|---|---|---|---|

## 可疑(需人工确认)
| # | 位置 | 操作 | 疑点 | 已排除的可能 |
|---|---|---|---|---|

## 已核对无问题
| 操作 | 依据 |
|---|---|

禁止

  • 不改 view/app/src、packages/apiclient、lib/**(本轮只出结论)。
  • 不把「风格问题」「性能问题」「a11y」写进报告——只写契约错配。
  • 不臆测:没找到后端结构体就标「未实证」。