docs(spec): 修正 SYNC_ARCHITECTURE.md 的 L3 Connector 示例并为其加编译门 (#5515) - #5603
Merged
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
|
Contributor
📓 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:
|
Contributor
Author
|
PM 预记( Generated by Claude Code |
os-zhuang
marked this pull request as ready for review
August 5, 2026 22:15
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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