来源:#852 实施过程中通读 AGENTS.md 时发现(只报不改,#852 的边界是「只动 Schema Validation 清单第 3 条」)。基线 origin/main = 9d2c787。
事实
AGENTS.md §「💻 Tech Stack & Protocol」第 2 条(约第 61-64 行):
2. **ObjectQL (No-SQL)**:
- Data access MUST use **ObjectQL**.
- **NEVER** write raw SQL.
- Format: `broker.find('opportunity', { filters: [['amount', '>', 50000]] })`.
这一行同时踩了三点,全部实测于 17.0.0-rc.2 + 当前 src/:
-
调用面不存在于本仓:grep -rn "broker" src/ --include=*.ts → 0 命中。本仓的真实读路径是 ctx.api.object('crm_x').find({ ... })(例:src/objects/campaign.hook.ts:68、src/objects/lead.hook.ts:84)。
-
谓词键不是 filters:本仓自己的 .changeset/hook-query-where-not-filter.md 记录了这条教训——17 处 hook 侧调用曾把谓词写成 filter:,findOne 把 query 直接摊进 AST 从不做别名,谓词整个消失并返回该对象第一行;count 只读 query.where,于是统计全表。既不报错也不返回 null。规范侧的 filters(复数)确实存在,但那是 HTTP query-param 的已弃用别名(spec/src/api/protocol.zod.ts:326-327,值是 JSON 字符串),不是进程内 query 对象的键。范例给的恰是进程内调用。
-
对象名违反同文件第 59 行的强制前缀:'opportunity' 没有 crm_ 前缀,而同一份 AGENTS.md 第 59 行写着「All HotCRM business object names MUST use the crm_ prefix and the prefix MUST be written explicitly in source」,真实对象名是 crm_opportunity(pnpm validate 报 17 Objects,全部 crm_*)。
影响
与 #852 同类:这是给 agent 看的 binding 指令,且是它给出的唯一一条 ObjectQL 调用范例。照抄的失败方式分两档——broker 和 crm_ 前缀会在 typecheck/运行时立刻炸(吵闹、可发现);而 filters 谓词键是静默的:按 .changeset/hook-query-where-not-filter.md 实测,findOne 会返回错的记录、count 会数错,不报错不抛异常。本仓已经为同一形状的错误付过一次账。
建议改法(未做)
把范例换成本仓实际在用、且已被测试覆盖的形状,例如 ctx.api.object('crm_opportunity').find({ where: [['amount', '>', 50000]] })(以改动时实测的 hook 调用为准,不要照抄本行)。属于 binding 指令文件改动,措辞留给维护者定。
Refs #852
来源:#852 实施过程中通读
AGENTS.md时发现(只报不改,#852 的边界是「只动 Schema Validation 清单第 3 条」)。基线origin/main= 9d2c787。事实
AGENTS.md§「💻 Tech Stack & Protocol」第 2 条(约第 61-64 行):这一行同时踩了三点,全部实测于 17.0.0-rc.2 + 当前
src/:调用面不存在于本仓:
grep -rn "broker" src/ --include=*.ts→ 0 命中。本仓的真实读路径是ctx.api.object('crm_x').find({ ... })(例:src/objects/campaign.hook.ts:68、src/objects/lead.hook.ts:84)。谓词键不是
filters:本仓自己的.changeset/hook-query-where-not-filter.md记录了这条教训——17 处 hook 侧调用曾把谓词写成filter:,findOne把 query 直接摊进 AST 从不做别名,谓词整个消失并返回该对象第一行;count只读query.where,于是统计全表。既不报错也不返回null。规范侧的filters(复数)确实存在,但那是 HTTP query-param 的已弃用别名(spec/src/api/protocol.zod.ts:326-327,值是 JSON 字符串),不是进程内 query 对象的键。范例给的恰是进程内调用。对象名违反同文件第 59 行的强制前缀:
'opportunity'没有crm_前缀,而同一份 AGENTS.md 第 59 行写着「All HotCRM business object names MUST use thecrm_prefix and the prefix MUST be written explicitly in source」,真实对象名是crm_opportunity(pnpm validate报 17 Objects,全部crm_*)。影响
与 #852 同类:这是给 agent 看的 binding 指令,且是它给出的唯一一条 ObjectQL 调用范例。照抄的失败方式分两档——
broker和crm_前缀会在 typecheck/运行时立刻炸(吵闹、可发现);而filters谓词键是静默的:按.changeset/hook-query-where-not-filter.md实测,findOne会返回错的记录、count会数错,不报错不抛异常。本仓已经为同一形状的错误付过一次账。建议改法(未做)
把范例换成本仓实际在用、且已被测试覆盖的形状,例如
ctx.api.object('crm_opportunity').find({ where: [['amount', '>', 50000]] })(以改动时实测的 hook 调用为准,不要照抄本行)。属于 binding 指令文件改动,措辞留给维护者定。Refs #852