---
id: WF-PFM-DJE-007
title: Write a keyed record and its producer mapping
trigger: >-
  A keyed item reaches domain application, or a batch resolves producer-key
  references.
product_area: platform
module: data-job-engine
revision: 1
status: draft
design_intent: confirmed
origin: >-
  services-platform:docs/proposals/rhythm-data-job-engine-plan.md §6.3 matching
  keys and ID mapping, §6.9 optimistic concurrency (approved 2026-10-12); CRM-M7
  D-38; services-platform:docs/standards/record-write-contracts.md#W4
implementation_evidence: observed
inference: []
source_sha:
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
  - CAP-PFM-DJE-006
  - CAP-PFM-DJE-012
  - CAP-PFM-DJE-015
moves:
  - STATE-PFM-DJE-002
crosses:
  - SVC-PFM-DJE-engine
  - SVC-PFM-DJE-crm-data-jobs
  - SVC-PFM-DJE-data-jobs
hops:
  - 'n': 1
    actor_or_service: Owning record's prevalidation
    action: >-
      Resolve producer references in a set-based lookup before writing dependent
      records.
    anchor: >-
      macroservice-libraries:packages/data-jobs/src/data-id-mappings.ts:resolveMappedIds
    seam: sync
    on_failure: Block unresolved required references with a dependency reason.
    left_inconsistent: A blocked item creates no destination record.
    observer: Refusals page (blocked).
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#blocks
      the child, and a retry after the parent is loaded applies it and finishes
      the job
  - 'n': 2
    actor_or_service: Batch runner (known skips)
    action: >-
      Preview surviving mappings and batch-write receipts for known stale or
      duplicate items.
    anchor: >-
      macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:itemsSkippedWhole
    seam: sync
    on_failure: Apply ordinary receipt-write failure handling.
    left_inconsistent: Known skips change no business record.
    observer: Results page (skipped duplicate or stale).
    provenance: documented
    source: >-
      macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts
      (module comment, step 6)
  - 'n': 3
    actor_or_service: 'Keyed apply, inside the item''s transaction'
    action: >-
      Lock an existing mapping and select create, update or skip using revision
      and conflict policy.
    anchor: >-
      macroservice-libraries:packages/data-jobs/src/keyed-item-decision.ts:decideKeyedItem
    seam: sync
    on_failure: Refuse a protected version mismatch as a conflict.
    left_inconsistent: Protected staff edits remain intact.
    observer: Refusals page (conflict).
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#refuses
      the delivery as a conflict and leaves the record alone
  - 'n': 4
    actor_or_service: Owning record's create or update
    action: >-
      Invoke the owner’s domain save with resolved identity and any expected
      version.
    anchor: 'services-crm:modules/data-jobs/services/operations/organization-import.ts'
    seam: sync
    on_failure: Roll back refused domain work together with its mapping.
    left_inconsistent: The item leaves no partial owned details.
    observer: Refusals page.
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/operations/record-imports.integration.spec.js#writes
      nothing at all of the rejected organization: not the row, not its
      addresses, not its mapping
  - 'n': 5
    actor_or_service: Keyed apply
    action: >-
      Insert or update the mapping beside the committed domain write, preserving
      the producer-written version for unchanged outcomes.
    anchor: >-
      macroservice-libraries:packages/data-jobs/src/apply-keyed-item.ts:applyDataJobItem
    seam: sync
    on_failure: Roll back the item if mapping persistence fails.
    left_inconsistent: >-
      Concurrent first deliveries can leave an extra record without this
      producer mapping.
    observer: Reconciliation lookups by producer key.
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#writes
      no crosswalk row for an item it refused, so the corrected delivery of that
      key is a create
idempotency: >-
  Lower revisions are stale skips and equal whole-record revisions are
  duplicates. An equal-revision patch may be another part of the same delivery.
  Mapping-based replay and per-job receipts protect different identities.
concurrency: >-
  Locks serialize existing mappings. An absent key has no row to lock, and
  conflict-updating insertion can leave two created records with only one
  mapped. Reject supplies the producer-written version; overwrite omits it
  unless the item names an explicit version.
branches:
  - >-
    An unresolved keyed patch goes to the domain and can be blocked; it does not
    create a record.
  - >-
    Initial imports can omit declared live effects and accept supported
    historical options.
waits: []
evidence:
  - >-
    macroservice-libraries at 54536a44: src/apply-keyed-item.ts,
    keyed-item-decision.ts, data-id-mappings.ts, run-data-job-batch.ts;
    README.md#Keyed writes and the ID crosswalk.
  - >-
    services-crm at a8d1364f: services/operations/contact-import.ts,
    organization-import.ts, configuration-import.ts; services/imports/**.
  - >-
    services-platform at ad3f6a65: services/operations/custom-field-import.ts,
    custom-object-record-import.ts.
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-CHG-007, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-DAT-006, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Write A Keyed Record And Its Producer Mapping

## What It Does

Producer mapping translates external identity into a destination and revision decision. The domain write and mapping share a transaction, with a known gap for simultaneous first deliveries of one key.

## The Flow

```mermaid
flowchart TD
  H1["Owning record's prevalidation"] --> H2
  H2["Batch runner (known skips)"] --> H3
  H3["Keyed apply, inside the item's transaction"] --> H4
  H4["Owning record's create or update"] --> H5
  H5["Keyed apply"]
```

## When Something Fails

A refused item commits neither its domain change nor its mapping. Existing-key guards preserve intervening edits under reject. First-key concurrency can still create an additional destination, so stable producer identity is weaker than the library commentary promises.

## Open Design Questions

Producer identity needs a first-key concurrency safeguard before the stronger mapping guarantee can be accepted.
