Uh oh!
There was an error while loading. Please reload this page.
docs(spec): 修正 SYNC_ARCHITECTURE.md 的 L3 Connector 示例并为其加编译门 (#5515) - #5603
Conversation
…d gate it (#5515) The `sapConnector` example taught four spellings `integration/connector.zod.ts` turns down. Measured with the compiler API before the fix, verbatim: TS2353 'sourceField' does not exist in '{ source: string; target: string; ... }' TS2322 '"custom"' is not assignable to '"map" | "lookup" | "constant" | "cast" | "javascript"' TS2353 'retryPolicy' does not exist in the webhook shape TS2322 'string' is not assignable to '{ dialect: "cel"|"cron"|"template"; ... }' Fixed in the document: - fieldMappings[].sourceField/targetField -> source/target, the canonical spelling of the base protocol in shared/mapping.zod.ts. - transform { type: 'custom', function } -> { type: 'javascript', expression }, the nearest real member of the five-way discriminated union. The bare string is ExpressionInput shorthand and parses to { dialect, source }. - webhooks[].retryPolicy removed. WebhookSchema is a strictObject and already carries a curated tombstone for it (#3494): delivery retries are owned by the messaging outbox on a fixed schedule. There is no equivalent key, so the block becomes a comment saying why -- and saying that the sibling `retryConfig` is a different thing (the connector's own calls). - the annotation is now ConnectorInput (z.input), which is what an author writes. The bare `Connector` is z.infer on this file, so it is the shape a parse RETURNS. Flipping this file's 20 aliases to the #4963 X / XParsed house convention is a real but separate appetite -- filed as #5551 -- and is deliberately NOT done here. New gate: packages/spec/src/integration/connector-author-shape.test.ts, a sibling of automation/etl-author-shape.test.ts (#4963 / PR #5514) owned by the schema that owns the example. It compiles the L3 block verbatim, import line included, with a harness self-test against vacuity; classifies the document's three `Connector` blocks (two Migration-Guide sketches elide with a bare `...` and are not TypeScript); restores each of the four defects as a probe that must go red with a named diagnostic; and pins what the schema SAYS at runtime for each -- a curated tombstone for `retryPolicy`, a silent strip plus missing `source`/`target` for `sourceField` (the curated alias for that word lives on ./data's ImportFieldMappingSchema, not this one), a value verdict naming the five members for 'custom'. The document's total ```typescript block count is unchanged at 6; the sibling gate's pin holds. Fixes#5515 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018fxLGQdatPbBUvCgiVxg6D
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 109 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
commented
Aug 5, 2026
PM 预记( Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#5515
前提复核(先于实现)
对
origin/main(5acb93add)逐条核对,四条缺陷全部仍在,前提成立:packages/spec/docs/SYNC_ARCHITECTURE.md的 L3sapConnector示例原样带着sourceField/targetField/transform.type: 'custom'/webhooks[].retryPolicy。shared/mapping.zod.ts的FieldMappingSchema只声明source/target;FieldMappingTransformSchema是判别联合,type只有constant | cast | lookup | javascript | map。connector.zod.ts:296的WebhookConfigSchema链上没有retryPolicy。connector.zod.ts:742/744:Connector = z.infer(裸名 = parsed),ConnectorInput = z.input。automation/etl.zod.ts的九个别名回到X/XParsedhouse convention (#4963) #5514(automation/etl.zod.ts的九个类型别名全部导出 parsed 形状,违反X/XParsedhouse convention(SYNC_ARCHITECTURE.md 的示例因此不可编译) #4963 的 L2 修正)已合并,基线里有automation/etl-author-shape.test.ts,块数钉子为 6。一处需要更正的前提细节(不影响结论,但影响修法与钉法):issue 正文把
sourceField说成"schema 里挂了 curated alias 的被拒键",引用的是connector.test.ts:1028。那行的 curated alias registry 属于./data的ImportFieldMappingSchema(一个strictObject),不是ConnectorFieldMappingSchema。后者是普通z.object,实测:也就是说这个键在连接器面上是被静默丢弃的,作者只会被告知"少了 source/target",永远不会被告知他写的词有问题 —— 比 issue 描述的情形更难自查。这一条已按事实钉在新门里(见下)。
改了什么
1. 文档示例的四处修正(
packages/spec/docs/SYNC_ARCHITECTURE.md)fieldMappings[].sourceField/targetFieldsource/targetshared/mapping.zod.ts的基协议规范拼写transform: { type: 'custom', function: … }transform: { type: 'javascript', expression: 'value / 100' }ExpressionInput简写,parse 后包成{ dialect, source }webhooks[].retryPolicy: { … }WebhookSchema是strictObject,已为该键挂了 #3494 的 curated guidance:投递重试归消息 outbox 的固定排程所有,没有等价键。同时点明它与下方retryConfig不是一回事(后者管连接器发出的调用)const sapConnector: Connectorconst sapConnector: ConnectorInput(import 改import type)z.infer(parse 结果),作者形状是z.input第四条按派单裁定只改示例注解;
connector.zod.ts20 个z.infer裸名别名翻到 #4963 确立的X/XParsedhouse convention 是独立 appetite,本 PR 不动,已另立 #5551。示例上方新增一段散文说明作者形状 / parse 形状的区别,并如实点出它与上文 L2 的不对称(L2 的裸ETLPipeline是作者形状),指向 #5551。顺带把 Migration Guide 两段 L3 草图的注解也改成
ConnectorInput,否则同一篇文档会教两种注解。它们仍用裸...省略,不是 TypeScript,不进编译门。2. 新编译门
packages/spec/src/integration/connector-author-shape.test.tsautomation/etl-author-shape.test.ts的兄弟门,由拥有该示例的 schema 所在文件持有。四组断言:Connector的块必须是 3 个,其中 2 个是...省略草图、1 个是完整示例。选择器匹配为空会让下面的编译断言在空程序上通过 —— 门失效的经典形态。ts.createProgram(strict: true,@objectstack/spec/*映射到src/*/index.ts,types: ['node']—— 示例真的读process.env.SAP_CLIENT_ID!),要求零诊断;附一个必须失败的 harness 自检探针。ConnectorInput字面量,每个必须以具名诊断变红(不是"有诊断"),再配一个三处规范拼写同时为绿的对照组 —— 没有对照,那三处红说明不了问题出在拼写上。retryPolicy是 key 判决(unrecognized_keys+ 点名 [P2] Aspirational-config disposition: reconcile-or-prune the still-dead props from the 2026-06 liveness audit (Theme / Translation / Job / Webhook) #3494 + "There is no replacement");sourceField是静默剥离 + 缺source/target;'custom'是 value 判决(消息列出五个真实成员)。同时更新了兄弟门里那段现在已经过时的分类注释(它写着"L3 那段报四条诊断,filed as #5515, not fixed here")。
3. 块数钉子
文档的
```typescript总块数没有变化,仍是 6(改的是已有块,没有增删),etl-author-shape.test.ts的toBe(6)钉子原样成立,无需调整。验证
先证红 —— 新门跑在未修改的文档上,复现出 issue 里的四条诊断,逐字一致:
注意这一跑里其余 12 项(反向验证探针、运行期措辞、
ConnectorInputvsConnector那组)已经全绿 —— 它们描述的是 schema 的既有事实,不依赖文档改没改,所以红的只有"示例本身"这一项,正是应有的方向。后证绿(修完文档):
全量:
changeset
无。
packages/spec/docs/**不在该包package.json的files白名单里(只发dist/json-schema/src/**/*.zod.ts等),本 PR 没有任何 runtime / schema 行为变化,是文档 + 测试。按约定走skip-changeset标签,不放空 changeset。派单外发现(均已另立 issue,本 PR 不修)
integration/connector.zod.ts20 个裸名别名仍是z.infer,与automation/etl.zod.ts的九个类型别名全部导出 parsed 形状,违反X/XParsedhouse convention(SYNC_ARCHITECTURE.md 的示例因此不可编译) #4963 确立的 house convention 相反。这是本 issue 第四条的根因;本 PR 只改示例注解绕过它。迁移面不为空(defineConnector是 live parse path),需单独裁定。新门里那组ConnectorInput/Connector探针就是那次翻转的第一处落点。shared/mapping.zod.ts的javascript变换成员,describe推荐dialect="js",而ExpressionDialect只有cel/cron/template(js在 formula: retire thejsexpression dialect — redundant with L2 ScriptBody;hasDialectalso mis-reports the stub as real #3278 就退役了)。照 describe 写显式信封会被拒;唯一走得通的裸字符串简写落到的是 cel。附带量到FieldMappingTransform全仓无消费者。connector.rateLimitConfig及其整个形状已在 「v17」ConnectorRateLimitConfig 出站限流词表按 ADR-0049 摘除 —— 执行引擎不存在(#4686 拆向之二) #4911 退役。属同一节的散文而非示例块,措辞选择独立,没有搭本 PR 的车。侧查(issue 的"未验证"一节,已完成)
content/docs/references/integration/connector.mdx:grepsourceField/targetField/custom/retryPolicy—— 零命中,无同类缺陷。(该目录是生成产物,本 PR 未触碰。)connector.zod.ts自己的@example:该文件@example块数为 0,无从出错。shared/mapping.zod.ts的两处@example用的就是source/target+{ type: 'cast', targetType: 'string' },是对的。content/docs/**其余retryPolicy命中(automation/retry-policy.mdx、system/job.mdx等)属于另外几个真实存在的RetryPolicySchema,与 webhook 的退役键无关。侧查结论:无需修改、无需重新生成任何
content/docs/references/**。风险
低。改动面是一份不随包发布的仓内设计文档 + 一个新测试文件 + 一段兄弟测试的注释;无 schema、无运行时、无生成产物。唯一的行为性影响是新门从此会对这份文档的 L3 段变红 —— 那正是它存在的意义。
Generated by Claude Code