| title | Sync |
|---|---|
| description | Sync protocol schemas |
{/*
Data Sync Protocol - LEVEL 1: Simple Synchronization
Inspired by Salesforce Connect, Segment Sync, and Census Reverse ETL.
Positioning in 3-Layer Architecture:
-
L1: Simple Sync (THIS FILE) - Business users - Sync Salesforce to Sheets
-
L2: ETL Pipeline (automation/etl.zod.ts) - Data engineers - Aggregate 10 sources to warehouse
-
L3: Enterprise Connector (integration/connector.zod.ts) - System integrators - Full SAP integration
Data sync provides bidirectional or unidirectional data synchronization
between ObjectStack and external systems, maintaining data consistency
across platforms.
SCOPE: Simple field mappings only. NO complex transformations.
For complex transformations (joins, aggregates, custom SQL), use ETL Pipeline (Level 2).
Use Simple Sync when:
-
Syncing 1:1 fields between two systems
-
Simple field transformations (uppercase, cast, etc.)
-
No complex logic required
-
Business users need to configure integrations
Examples:
-
Salesforce Contact ↔ Google Sheets
-
HubSpot Company ↔ CRM Account
-
Shopify Orders → Accounting System
When to upgrade:
-
Need multi-source joins → Use ETL Pipeline
-
Need complex authentication/webhooks → Use Enterprise Connector
-
Need aggregations or data warehousing → Use ETL Pipeline
See also: ./etl.zod.ts for Level 2 (data engineering)
See also: [../integration/connector.zod.ts](/docs/references/integration/connector) for Level 3 (enterprise integration)
- CRM Integration
-
Sync contacts between ObjectStack and Salesforce
-
Keep opportunity data synchronized
-
Bidirectional updates
- Customer Data Platform (CDP)
-
Sync user profiles to Segment
-
Enrichment data from Clearbit
-
Marketing automation sync
- Operational Analytics
-
Sync production data to analytics warehouse
-
Real-time dashboards
-
Business intelligence
See also: https://help.salesforce.com/s/articleView?id=sf.platform_connect_about.htm
See also: https://segment.com/docs/connections/sync/
See also: https://www.getcensus.com/
@example
const contactSync: DataSyncConfig = \{
name: 'salesforce_contact_sync',
label: 'Salesforce Contact Sync',
source: \{
object: 'contact',
filters: \{ status: 'active' \}
\},
destination: \{
connector: 'salesforce',
operation: 'upsert_contact',
mapping: \{
first_name: 'FirstName',
last_name: 'LastName',
email: 'Email'
\}
\},
syncMode: 'incremental',
schedule: '0 * * * *' // Hourly
\}import { DataDestinationConfig, DataSourceConfig, SyncDirection, SyncExecutionResult, SyncExecutionStatus, SyncMode } from '@objectstack/spec/automation';
import type { DataDestinationConfig, DataSourceConfig, SyncDirection, SyncExecutionResult, SyncExecutionStatus, SyncMode } from '@objectstack/spec/automation';
// Validate data
const result = DataDestinationConfig.parse(data);| Property | Type | Required | Description |
|---|---|---|---|
| object | string |
optional | ObjectStack object name |
| connectorInstanceId | string |
optional | Connector instance ID |
| operation | Enum<'insert' | 'update' | 'upsert' | 'delete' | 'sync'> |
✅ | Sync operation |
| mapping | Record<string, string> | { source: string; target: string; transform?: { type: 'constant'; value: any } | { type: 'cast'; targetType: Enum<'string' | 'number' | 'boolean' | 'date'> } | { type: 'lookup'; table: string; keyField: string; valueField: string } | { type: 'javascript'; expression: string | { dialect: Enum<'cel' | 'cron' | 'template'>; source?: string; ast?: any; meta?: object } } | { type: 'map'; mappings: Record<string, any> }; defaultValue?: any }[] |
optional | Field mappings |
| externalResource | string |
optional | External resource ID |
| matchKey | string[] |
optional | Match key fields |
| Property | Type | Required | Description |
|---|---|---|---|
| object | string |
optional | ObjectStack object name |
| filters | any |
optional | Filter conditions |
| fields | string[] |
optional | Fields to sync |
| connectorInstanceId | string |
optional | Connector instance ID |
| externalResource | string |
optional | External resource ID |
pushpullbidirectional
| Property | Type | Required | Description |
|---|---|---|---|
| id | string |
✅ | Execution ID |
| syncName | string |
✅ | Sync name |
| status | Enum<'pending' | 'running' | 'completed' | 'partial' | 'failed' | 'cancelled'> |
✅ | Execution status |
| startedAt | string |
✅ | Start time |
| completedAt | string |
optional | Completion time |
| durationMs | number |
optional | Duration in ms |
| stats | { recordsProcessed: integer; recordsInserted: integer; recordsUpdated: integer; recordsDeleted: integer; … } |
optional | Execution statistics |
| errors | { recordId?: string; field?: string; message: string; code?: string }[] |
optional | Errors |
| logs | string[] |
optional | Execution logs |
pendingrunningcompletedpartialfailedcancelled
fullincrementalrealtime