Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/connector-jsdoc-retirement-drift.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@objectstack/spec': patch
---

connector.zod.ts 的模块 JSDoc 不再宣传已退役的出站限流与字段映射转换

`packages/spec/src/integration/connector.zod.ts` 的模块级 JSDoc 有四处措辞比它描述的 schema 晚了两次退役,而这段 JSDoc 被 `gen:docs` 逐字生成进 `content/docs/references/integration/connector.mdx`——同一页的属性表已经写着「已移除」,散文却还在承诺「comprehensive rate limiting」。读者相信哪一个,取决于他先读到哪一段。

收敛的四处:

- 「Includes authentication, webhooks, **rate limiting**, field mapping, …」
- 「… and comprehensive **rate limiting**.」
- 「- Bidirectional sync with field mapping **and transformations**」
- 「- Webhook management **and rate limiting** required」

出站限流从来没有引擎:平台唯一的令牌桶(`packages/runtime/src/security/rate-limit.ts`)是**入站**的,`connector.rateLimitConfig` 连同 `ConnectorRateLimitConfig` / `RateLimitStrategy` 整个形状已在 `@objectstack/spec` 17.0.0 移除(#4911, ADR-0049 D2)。字段映射同理:`FieldMapping.transform` 与整个 `FieldMappingTransform` 联合已在 17.0.0 移除(#5552, ADR-0049),没有任何 runtime 执行过其中五个成员。

JSDoc 因此新增一节「What this layer does NOT provide」,把两条否定连同处方写明——出站限流请在 connector provider 或上游网关做;取值转换请用会真正执行它的面(import mapping 的 `mapping.fieldMapping[].transform`,或 L2 的 ETL 转换步骤)。措辞直接复用 #4911 / #5552 墓碑与 `SYNC_ARCHITECTURE.md`(#5554)的现成句,一次退役只保留一种说法。

参考文档 `content/docs/references/integration/connector.mdx` 由 `gen:docs` 随动重生成(未手改)。仅注释与生成文档变化,schema 形状与运行时行为不变。
40 changes: 36 additions & 4 deletions content/docs/references/integration/connector.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,43 @@ retired in #4738 — narrative-only, zero consumers; see
- **Enterprise Connector** (THIS FILE) - System integrators - Full SAP integration; connector-attached sync via `syncConfig`

**SCOPE: Most comprehensive integration layer.**
Includes authentication, webhooks, rate limiting, field mapping, bidirectional sync,
Includes authentication, webhooks, field mapping, bidirectional sync,
retry policies, and complete lifecycle management.

This protocol supports multiple authentication strategies, bidirectional sync,
field mapping, webhooks, and comprehensive rate limiting.
field mapping, webhooks, and comprehensive retry and resilience policies.

## What this layer does NOT provide

**There is no outbound rate limiting.** This header used to advertise "rate
limiting" twice — once in the SCOPE line, once as "comprehensive rate limiting" —
and no engine ever backed either. `connector.rateLimitConfig`, and the entire
`ConnectorRateLimitConfig` / `RateLimitStrategy` shape behind it, was removed in
`@objectstack/spec` 17.0.0 (#4911, ADR-0049 D2), because **no outbound
rate-limiting engine ever existed**. The platform's only token bucket (runtime
`security/rate-limit.ts`) throttles **INBOUND** requests *to* us; nothing throttles
the calls a connector makes *out*. Do **not** substitute `shared`'s
`RateLimitConfig` — that is the inbound limiter and would cap the wrong direction.
**Until an outbound throttle exists, rate-limit at the connector provider or
upstream gateway.** What L3 does declare for a rate-limited upstream is
`retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, 503,
504]` includes `429` — and `health.circuitBreaker`. The full removal reasoning is
recorded at the removal site: the "REMOVED: outbound rate limiting" block in
`integration/connector.zod.ts`, and `packages/spec/docs/SYNC_ARCHITECTURE.md`.

**Field mapping does not transform values.** This header used to offer "field
mapping and transformations"; only the first half was ever true.
`ConnectorFieldMappingSchema` extends the base mapping with exactly three keys —
`dataType`, `required` and `syncMode`. `FieldMapping.transform` was removed in
`@objectstack/spec` 17.0.0 (#5552, ADR-0049), and the whole `FieldMappingTransform`
union went with it (`constant` / `cast` / `lookup` / `javascript` / `map`) — **no
runtime ever executed any of the five**. An L3 connector mapping moves a value from
`source` to `target`; it does not compute one. **Value conversion belongs on a
surface that runs it:** the import mapping's own `mapping.fieldMapping[].transform`
(`data/mapping.zod.ts` — a string enum,
`none`/`constant`/`map`/`split`/`join`/`lookup`, with its settings in `params`),
applied row by row by the REST import path — or an ETL transformation step
(L2 above). Already authored the retired key? `os migrate meta --from 16` rewrites it.

## Runtime contract — descriptor vs. registered connector (#2612)

Expand Down Expand Up @@ -52,8 +84,8 @@ Authentication is now imported from the canonical `auth/config.zod.ts`.
**Use Enterprise Connector when:**
- Building enterprise-grade connectors (e.g., Salesforce, SAP, Oracle)
- Complex OAuth2/SAML authentication required
- Bidirectional sync with field mapping and transformations
- Webhook management and rate limiting required
- Bidirectional sync with field mapping (`dataType` / `syncMode` per field — it moves values, it does not transform them)
- Webhook management required
- Full CRUD operations and data synchronization
- Need comprehensive retry strategies and error handling

Expand Down
42 changes: 37 additions & 5 deletions packages/spec/src/integration/connector.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,43 @@ import { retiredKey } from '../shared/retired-key';
* - **Enterprise Connector** (THIS FILE) - System integrators - Full SAP integration; connector-attached sync via `syncConfig`
*
* **SCOPE: Most comprehensive integration layer.**
* Includes authentication, webhooks, rate limiting, field mapping, bidirectional sync,
* Includes authentication, webhooks, field mapping, bidirectional sync,
* retry policies, and complete lifecycle management.
*
*
* This protocol supports multiple authentication strategies, bidirectional sync,
* field mapping, webhooks, and comprehensive rate limiting.
* field mapping, webhooks, and comprehensive retry and resilience policies.
*
* ## What this layer does NOT provide
*
* **There is no outbound rate limiting.** This header used to advertise "rate
* limiting" twice — once in the SCOPE line, once as "comprehensive rate limiting" —
* and no engine ever backed either. `connector.rateLimitConfig`, and the entire
* `ConnectorRateLimitConfig` / `RateLimitStrategy` shape behind it, was removed in
* `@objectstack/spec` 17.0.0 (#4911, ADR-0049 D2), because **no outbound
* rate-limiting engine ever existed**. The platform's only token bucket (runtime
* `security/rate-limit.ts`) throttles **INBOUND** requests *to* us; nothing throttles
* the calls a connector makes *out*. Do **not** substitute `shared`'s
* `RateLimitConfig` — that is the inbound limiter and would cap the wrong direction.
* **Until an outbound throttle exists, rate-limit at the connector provider or
* upstream gateway.** What L3 does declare for a rate-limited upstream is
* `retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, 503,
* 504]` includes `429` — and `health.circuitBreaker`. The full removal reasoning is
* recorded at the removal site: the "REMOVED: outbound rate limiting" block in
* `integration/connector.zod.ts`, and `packages/spec/docs/SYNC_ARCHITECTURE.md`.
*
* **Field mapping does not transform values.** This header used to offer "field
* mapping and transformations"; only the first half was ever true.
* `ConnectorFieldMappingSchema` extends the base mapping with exactly three keys —
* `dataType`, `required` and `syncMode`. `FieldMapping.transform` was removed in
* `@objectstack/spec` 17.0.0 (#5552, ADR-0049), and the whole `FieldMappingTransform`
* union went with it (`constant` / `cast` / `lookup` / `javascript` / `map`) — **no
* runtime ever executed any of the five**. An L3 connector mapping moves a value from
* `source` to `target`; it does not compute one. **Value conversion belongs on a
* surface that runs it:** the import mapping's own `mapping.fieldMapping[].transform`
* (`data/mapping.zod.ts` — a string enum,
* `none`/`constant`/`map`/`split`/`join`/`lookup`, with its settings in `params`),
* applied row by row by the REST import path — or an ETL transformation step
* (L2 above). Already authored the retired key? `os migrate meta --from 16` rewrites it.
*
* ## Runtime contract — descriptor vs. registered connector (#2612)
*
Expand Down Expand Up @@ -55,8 +87,8 @@ import { retiredKey } from '../shared/retired-key';
* **Use Enterprise Connector when:**
* - Building enterprise-grade connectors (e.g., Salesforce, SAP, Oracle)
* - Complex OAuth2/SAML authentication required
* - Bidirectional sync with field mapping and transformations
* - Webhook management and rate limiting required
* - Bidirectional sync with field mapping (`dataType` / `syncMode` per field — it moves values, it does not transform them)
* - Webhook management required
* - Full CRUD operations and data synchronization
* - Need comprehensive retry strategies and error handling
*
Expand Down
Loading