| title | Seed Loader |
|---|---|
| description | Seed Loader protocol schemas |
{/*
Defines the schemas for metadata-driven seed data loading with automatic
relationship resolution, dependency ordering, and multi-pass insertion.
-
Salesforce Data Loader: External ID-based upsert with relationship resolution
-
ServiceNow: Sys ID and display value mapping during import
-
Airtable: Linked record resolution via display names
1. Build object dependency graph from field metadata (lookup/master_detail)
2. Topological sort → determine insert order (parents before children)
3. Pass 1: Insert/upsert records, resolve references via externalId
4. Pass 2: Fill deferred references (circular/delayed dependencies)
5. Validate & report unresolved references
6. Return structured result with per-object stats
import { ObjectDependencyGraph, ObjectDependencyNode, ReferenceResolution, ReferenceResolutionError, SeedIdentity, SeedLoadResult, SeedLoaderConfig, SeedLoaderRequest, SeedLoaderResult } from '@objectstack/spec/data';
import type { ObjectDependencyGraph, ObjectDependencyNode, ReferenceResolution, ReferenceResolutionError, SeedIdentity, SeedLoadResult, SeedLoaderConfig, SeedLoaderRequest, SeedLoaderResult } from '@objectstack/spec/data';
// Validate data
const result = ObjectDependencyGraph.parse(data);Complete object dependency graph for seed data loading
| Property | Type | Required | Description |
|---|---|---|---|
| nodes | { object: string; dependsOn: string[]; references: { field: string; targetObject: string; targetField: string; fieldType: Enum<'lookup' | 'master_detail' | 'user'> }[] }[] |
✅ | All objects in the dependency graph |
| insertOrder | string[] |
✅ | Topologically sorted insert order |
| circularDependencies | string[][] |
✅ | Circular dependency chains (e.g., [["a", "b", "a"]]) |
Object node in the seed data dependency graph
| Property | Type | Required | Description |
|---|---|---|---|
| object | string |
✅ | Object name (snake_case) |
| dependsOn | string[] |
✅ | Objects this object depends on |
| references | { field: string; targetObject: string; targetField: string; fieldType: Enum<'lookup' | 'master_detail' | 'user'> }[] |
✅ | Field-level reference details |
Describes how a field reference is resolved during seed loading
| Property | Type | Required | Description |
|---|---|---|---|
| field | string |
✅ | Source field name containing the reference value |
| targetObject | string |
✅ | Target object name (snake_case) |
| targetField | string |
✅ | Field on target object used for matching |
| fieldType | Enum<'lookup' | 'master_detail' | 'user'> |
✅ | Relationship field type |
Actionable error for a failed reference resolution
| Property | Type | Required | Description |
|---|---|---|---|
| sourceObject | string |
✅ | Object with the broken reference |
| field | string |
✅ | Field name with unresolved reference |
| targetObject | string |
✅ | Target object searched for the reference |
| targetField | string |
✅ | ExternalId field used for matching |
| attemptedValue | any |
✅ | Value that failed to resolve |
| recordIndex | integer |
✅ | Index of the record in the dataset |
| message | string |
✅ | Human-readable error description |
Identity context for resolving os.user / os.org in seed CEL values
| Property | Type | Required | Description |
|---|---|---|---|
| user | { id: string; role?: string; email?: string } |
optional | Subject bound to os.user in seed CEL expressions |
| org | { id: string; tier?: string } |
optional | Organization bound to os.org in seed CEL expressions |
Result of loading a single dataset
| Property | Type | Required | Description |
|---|---|---|---|
| object | string |
✅ | Object that was loaded |
| mode | Enum<'insert' | 'update' | 'upsert' | 'replace' | 'ignore'> |
✅ | Import mode used |
| inserted | integer |
✅ | Records inserted |
| updated | integer |
✅ | Records updated |
| skipped | integer |
✅ | Records skipped |
| errored | integer |
✅ | Records with errors |
| total | integer |
✅ | Total records in dataset |
| referencesResolved | integer |
✅ | References resolved via externalId |
| referencesDeferred | integer |
✅ | References deferred to second pass |
| errors | { sourceObject: string; field: string; targetObject: string; targetField: string; … }[] |
✅ | Reference resolution errors |
Seed data loader configuration
| Property | Type | Required | Description |
|---|---|---|---|
| dryRun | boolean |
✅ | Validate references without writing data |
| haltOnError | boolean |
✅ | Stop on first reference resolution error |
| multiPass | boolean |
✅ | Enable multi-pass loading for circular dependencies |
| defaultMode | Enum<'insert' | 'update' | 'upsert' | 'replace' | 'ignore'> |
✅ | Default conflict resolution strategy |
| batchSize | integer |
✅ | Maximum records per batch insert/upsert |
| transaction | boolean |
✅ | Wrap entire load in a transaction (all-or-nothing) |
| env | Enum<'prod' | 'dev' | 'test'> |
optional | Only load datasets matching this environment |
| organizationId | string |
optional | Target organization id for per-tenant seed replay |
| identity | { user?: object; org?: object } |
optional | Identity bound to os.user / os.org when resolving CEL seed values |
Seed loader request with datasets and configuration
| Property | Type | Required | Description |
|---|---|---|---|
| seeds | { object: string; externalId: string | string[]; mode: Enum<'insert' | 'update' | 'upsert' | 'replace' | 'ignore'>; env: Enum<'prod' | 'dev' | 'test'>[]; … }[] |
✅ | Seeds to load |
| config | { dryRun: boolean; haltOnError: boolean; multiPass: boolean; defaultMode: Enum<'insert' | 'update' | 'upsert' | 'replace' | 'ignore'>; … } |
✅ | Loader configuration |
Complete seed loader result
| Property | Type | Required | Description |
|---|---|---|---|
| success | boolean |
✅ | Overall success status |
| dryRun | boolean |
✅ | Whether this was a dry-run |
| dependencyGraph | { nodes: { object: string; dependsOn: string[]; references: { field: string; targetObject: string; targetField: string; fieldType: Enum<'lookup' | 'master_detail' | 'user'> }[] }[]; insertOrder: string[]; circularDependencies: string[][] } |
✅ | Object dependency graph |
| results | { object: string; mode: Enum<'insert' | 'update' | 'upsert' | 'replace' | 'ignore'>; inserted: integer; updated: integer; … }[] |
✅ | Per-object load results |
| errors | { sourceObject: string; field: string; targetObject: string; targetField: string; … }[] |
✅ | All reference resolution errors |
| summary | { objectsProcessed: integer; totalRecords: integer; totalInserted: integer; totalUpdated: integer; … } |
✅ | Summary statistics |