|
| 1 | +--- |
| 2 | +'@objectstack/spec': minor |
| 3 | +--- |
| 4 | + |
| 5 | +feat(spec)!: connector-attached sync leaves the connector — `syncConfig` and `fieldMappings` are retired, and a `mapping` gains the `connectorSource` pull binding (#20281) |
| 6 | + |
| 7 | +**BREAKING** — `connector.syncConfig` (the `DataSyncConfig` block: `strategy`, |
| 8 | +`direction`, `realtimeSync`, `timestampField`, `conflictResolution`, `batchSize`, |
| 9 | +`deleteMode`, `filters`) and `connector.fieldMappings` (the `ConnectorFieldMapping` |
| 10 | +list: `source`, `target`, `defaultValue`, `dataType`, `required`, `syncMode`) are |
| 11 | +removed from `ConnectorSchema` and `DeclarativeConnectorEntrySchema` — so from |
| 12 | +`defineConnector`, `stack.connectors[]`, the `PUT /api/v1/meta/connector/:name` door |
| 13 | +and `AutomationEngine.registerConnector`. The `DataSyncConfigSchema`, |
| 14 | +`SyncStrategySchema`, `ConnectorConflictResolutionSchema` and |
| 15 | +`ConnectorFieldMappingSchema` exports (and their `DataSyncConfig`, `SyncStrategy`, |
| 16 | +`ConnectorConflictResolution`, `ConnectorFieldMapping` types and `…Parsed` aliases) |
| 17 | +leave `@objectstack/spec/integration` with them. ADR-0049, ruled ENFORCE on the |
| 18 | +maintainer's criterion for a declared-but-unenforced family, with the definition |
| 19 | +MOVED: every mainstream platform binds a sync to its TARGET, not to the connection. |
| 20 | + |
| 21 | +Measured before removal: no engine ever ran a connector-attached sync or moved a |
| 22 | +value through a connector field mapping — outside the spec package `syncConfig` |
| 23 | +appeared only in two comments and `fieldMappings` nowhere, the automation service's |
| 24 | +declared-connector item carried neither key, and the def a provider registers is its |
| 25 | +own. The `latest_wins` and `soft_delete` defaults read as configured policy and did |
| 26 | +nothing; the platform has no soft delete. |
| 27 | + |
| 28 | +**Added (declared, not yet executed):** `mapping.connectorSource` — the pull |
| 29 | +binding on the target side, beside the mapping's existing `targetObject`, |
| 30 | +`fieldMapping`, `mode` and `upsertKey`: `connector` (a `rest` or `openapi` |
| 31 | +connector instance), `action` (the action that reads the records), optional |
| 32 | +`input`, optional `recordsPath`, and an optional `watermark` (`field` on the |
| 33 | +record, `param` on the request) for a timestamp-incremental pull. Version 1 is a |
| 34 | +one-way pull. It carries no cadence (a `job` sets that), no credential (the |
| 35 | +connector instance holds it) and no delete or conflict policy. Nothing executes it |
| 36 | +in this release, and `os validate` / `os build` warn when it is authored. |
| 37 | + |
| 38 | +### FROM → TO |
| 39 | + |
| 40 | +| removed | what to write instead | |
| 41 | +| --- | --- | |
| 42 | +| `connector.syncConfig` | delete the key. A sync you still want is a `mapping` on its target object, with `connectorSource` naming the connector and its read action, `watermark` for an incremental pull, and a `job` for the cadence. `direction`, `conflictResolution` and `deleteMode` have no counterpart: the pull is one-way and writes through `mode` / `upsertKey`. | |
| 43 | +| `connector.fieldMappings` | delete the key, and carry its `source` → `target` pairs into that mapping's `fieldMapping` (a `defaultValue` becomes a `constant` transform). | |
| 44 | +| `DataSyncConfigSchema`, `SyncStrategySchema`, `ConnectorConflictResolutionSchema`, `ConnectorFieldMappingSchema` and their types | no replacement — nothing parsed a sync or a connector field mapping into anything that ran. | |
| 45 | + |
| 46 | +**The one-line fix: delete `syncConfig:` and `fieldMappings:` from every connector.** |
| 47 | +`os migrate meta --from 17` lists the mechanical edits for existing sources. |
| 48 | + |
| 49 | +⚠️ Runtime behaviour is deliberately **unchanged**: no connector sync ever ran. |
| 50 | +What changes is the answer an author gets — both keys are refused at parse with a |
| 51 | +prescription naming the target-side binding, and in `tsc` (their input type is |
| 52 | +`never`), instead of being saved with no effect. |
| 53 | + |
| 54 | +### The retirement kit |
| 55 | + |
| 56 | +- **Tombstones.** `syncConfig` and `fieldMappings` are `retiredKey()` tombstones on |
| 57 | + the private `ConnectorBaseSchema` both published carriers wrap (the schema is not |
| 58 | + `.strict()`, so a bare deletion would be a silent strip, ADR-0104). |
| 59 | + `RETIRED_KEYS_BY_MAJOR[18]`: `integration/Connector:syncConfig`, |
| 60 | + `integration/Connector:fieldMappings`, |
| 61 | + `integration/DeclarativeConnectorEntry:syncConfig` and |
| 62 | + `integration/DeclarativeConnectorEntry:fieldMappings`. Neither key had a default, |
| 63 | + so no retired-default residue is owed. |
| 64 | +- **Four defs leave whole** (`RETIRED_DEFS_BY_MAJOR[18]`): `integration/DataSyncConfig`, |
| 65 | + `integration/SyncStrategy`, `integration/ConnectorConflictResolution`, |
| 66 | + `integration/ConnectorFieldMapping`. The two `RENAMED_DEFS` entries that targeted |
| 67 | + them left the rename table. |
| 68 | +- **D2 conversion `connector-sync-keys-removed`** (step 18, retired from the load |
| 69 | + path): strips both keys from `connectors[]` and from stored `sys_metadata` |
| 70 | + connector rows (the rehydration seam replays it), one notice per key, as a |
| 71 | + lossless delete. It never writes a `mapping`: a pulled mapping would start writes |
| 72 | + that never happened. |
| 73 | +- **D3 entry `connector-sync-keys-retired`** carries the family's judgement: which |
| 74 | + syncs should now exist as target-side mappings, and what an author who relied on |
| 75 | + `export`, `bidirectional`, `soft_delete` or a conflict policy does without them. |
| 76 | +- **No deprecation window**, per the project's startup-stage posture. |
| 77 | + |
| 78 | +⚠️ **The out-of-repo consumer population is NOT MEASURED.** `@objectstack/spec` is |
| 79 | +published, so this is breaking for consumers no telemetry was consulted for. |
| 80 | + |
| 81 | +Clause-②: yes (narrowing) |
| 82 | + |
| 83 | +<!-- adr-0087: registered connector-sync-keys-removed, connector-sync-keys-retired --> |
0 commit comments