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.3 KiB
6.3 KiB
Research:Bruno 示例注入机制(再生会不会覆盖手改)—— research-bruno-examples.md
票 06 产出 · 20260828 · 依据:
C:\Users\luowj\.qoder\skills\bruno-sync\SKILL.md(205 行全读)+bruno-sync.config.json/bruno-sync.local.json+D:/code/crm-api-docs实际.bru抽样(商机管理/商机分页.bru)。
结论:(a) 合并式 sync、手改安全 → 直接改 .bru
bruno-sync 的同步模型是**「结构 patch + 表述归人」**,不是整文件重写。SKILL.md 使用者心智模型原话:**「Bruno 里随便改,skill 只 patch 结构;想重来就删文件。」**
依据 1:再生对已存在 .bru 的处理(SKILL.md 铁律 1 + Step 3)
| 手改内容 | 再生时的命运 | 依据 |
|---|---|---|
body:form-urlencoded / params:query 块的实参值 |
永不重置(「参数的实参值以文件现有内容为人认可的终稿,更新时一个字不重写」) | 铁律 1 |
| docs 里一切说明文字(接口描述、参数表「说明」列、任意新增段落) | 永不覆盖(表述归人;源码注释后续变化不覆盖 docs,只进报告「表述差异」由人决定) | 铁律 1 + Step 4 |
| docs「请求示例/响应示例」里填入的示例值 | 永不覆盖(两段示例属「表述初稿」:只新建文件或新增结构条目时写入,人改过之后同步永不覆盖) | 示例生成章节 |
| 结构(参数条目集合/类型/必填/默认值/响应字段骨架) | 由 skill 单向镜像源码维护:源码变了做行级 patch(参数表增删行、类型/必填/默认列更新),新增行的说明取源码注释初稿、新增字段补机械推导示例值 | Step 3 三向对比 |
无 generated 标记的 .bru(私产) |
永不修改、永不删除、不计入孤儿,报告列「跳过」 | 铁律 2 |
| 删掉文件重跑 | 唯一的「重建」通道:回到纯净生成态,不设强制覆盖参数 | Step 3 新建条目 |
对账钥匙 = METHOD + 接口路径(grouping: tag 下追加页面 tag 段,tag 由所在文件夹名隐式充当)——文件名可改、不影响对账;docs 首行反引号内 `METHOD 路径` 兼作钥匙提取源。
依据 2:.bru 实际格式与示例落点(商机管理/商机分页.bru 抽样)
.bru 单文件四层结构,示例值有三个可注入落点:
meta { name/type/seq/tags:[generated] } ← generated 标记=对账参与资格(勿删)
post { url/body/auth } ← 请求定义(skill 维护 url)
body:form-urlencoded { viewType: MANAGE ... } ← 落点① 可发送实参(Bruno GUI 直接发)
docs {
`POST /api/opportunity/page` ← 对账钥匙(勿动)
接口说明文字 ← 落点② 自由补充说明
## 请求参数(结构表:参数/类型/必填/默认/说明) ← 结构列 skill patch,说明列归人
## 请求示例(贴合传输格式的可发送样例) ← 落点③ 示例值(归人)
## 响应 data 结构(字段表)
## 响应示例(信封 JSON,机械推导初稿,值可改)
}
Bruno 原生无 example 块;docs 块(Markdown,GUI 渲染)就是「示例值 + 说明」的承载机制——skill 的模板已内置四个 H2 段。
推荐方案:直接改 .bru(票 11 执行手册)
- 实参块换真实值:把
body:form-urlencoded/params:query的机械推导值换成 E2E 实测真实数据(seed id / 字典 code / 枚举值),如viewType: MANAGE、current: 1、size: 10→ 可加keyword: 智慧园区。 - docs 两处同步:「请求示例」段的样例行改成与实参块一致;「响应示例」的 data 可换成实测响应摘录(或保留机械推导稿)。
- 说明可自由增补:接口描述下可加实测结论(如「实测 20260828:seed 基线 total=12」);参数表「说明」列可直接润色——全部受铁律 1 保护。
- 三条纪律:
- 保持 meta
tags: [generated]原样(删掉=变私产,skill 永不再更新 → 结构漂移失察); - docs 首行
`METHOD 路径`勿动(钥匙提取失败会退化到 url 推导,但别依赖兜底); - 表单里的复杂字段按 config
complexFields: json-string-in-form(JSON 串整体作为表单值)。
- 保持 meta
预期效果:票 11 改完后,任何人跑 /bruno-sync 商机模块,手改的示例值与说明全部逐字保留;只有后端源码结构变化(新增/删参数、类型变更)才触发对应行 patch。
附:config 要点(票 11 对照用)
sourceRoots含crm-opportunity+crm-rule(商机模块 + 规则族均在同步范围,规则族 25 端点此前未入集合——票 01 结论,票 11 补齐后再生即可)grouping: tag(页面归属分层,tag 原文即目录名,含/嵌套);naming.language: zhenvelope: code/success/message/data;params: write=form-urlencoded / read=querydocsRepoPath: D:/code/crm-api-docs;environments.local: http://localhost:8080- 同一接口挂 N 个 tag → N 个页面文件夹下同名同内容副本,各副本独立对账
票 11 执行记录(20260828)
按本文件「推荐方案」执行完毕,四脚本串成闭环:
| 步骤 | 脚本 | 结果 |
|---|---|---|
| 采集 | collect-specimens.py |
32 实测标本入 specimens.json(含 8080 补采 stage_versions/scheme_versions;debug token admin 口径) |
| 注入 | inject-examples.py(已完成勿动) |
存量 48 请求实参块 + docs 请求示例段换 seed 真实值 |
| 生成 | gen-rules-views.py(--force 限 OWN_DIRS 白名单) |
规则族 25 + 自定义视图 4 = 29 接口 .bru + 4 folder.bru 新入集合;幂等重跑 33 skipped;全仓 209 .bru 0 BOM |
| 对账 | verify_sync.py |
71 唯一钥匙全命中、双零差集(77 文件 = 71 + 3 接口 ×3 页面副本多 6);正则已覆盖 @PostMapping 无参形态(OpportunityCreateController 新建商机) |
结论验证:本文件「预期效果」段成立——真实值全部落在实参块与 docs(铁律 1 保护域),结构(钥匙/参数条目/响应骨架)与源码镜像一致;后端源码结构不变的前提下,任何人跑 /bruno-sync 重生成,77 个文件的示例值与说明逐字保留。