---
id: CAP-PFM-DJE-018
title: Enable product records to use the shared job engine
feature: FEAT-PFM-DJE-05
product_area: platform
module: data-job-engine
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: partially-observed
supersedes: []
source_sha:
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
intent_sources:
  - 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S17'
  - 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#6. Approach'
purpose: >-
  Product areas connect their own record rules and persistence to a common job engine rather than
  defining separate bulk-processing behavior.
outcomes:
  - Operation declarations connect domain behavior to shared processing.
  - Platform metadata and custom records use the common engine.
  - Invalid operation contracts fail during initialization.
concepts:
  - CON-PFM-DJE-001
actors:
  - ACT-PFM-035
  - ACT-PFM-036
  - ACT-PFM-037
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: platform.custom-fields.bulk
    where_checked: api
    scope: tenant
  - key: platform.custom-fields.create
    where_checked: api
    scope: tenant
  - key: platform.custom-fields.update
    where_checked: api
    scope: tenant
  - key: platform.custom-records.create
    where_checked: api
    scope: tenant
  - key: platform.custom-records.update
    where_checked: service
    scope: record
  - key: platform.associations.create
    where_checked: api
    scope: tenant
  - key: platform.associations.update
    where_checked: api
    scope: tenant
rules:
  - id: BR-CAP-PFM-DJE-018-01
    proved_by: [ATS-PFM-DJE-001-15, ATS-PFM-DJE-018-01, ATS-PFM-DJE-018-09, TST-PFM-DJE-015, TST-PFM-DJE-037]
    statement: >-
      An operation declaration identifies accepted input versions, permissions, editable fields, matching
      keys, dependencies, grouping, suppression choices and domain checks and writes; missing versions or
      deletes with editable fields or rollback are refused at initialization.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/validate-data-job-request.spec.ts#refuses a delete
      that declares patchable fields, which a delete never sets
    origin: none
  - id: BR-CAP-PFM-DJE-018-02
    proved_by: [ATS-PFM-DJE-018-02, TST-PFM-DJE-035]
    statement: >-
      Consumers host eight base engine tables with fail-closed workspace security; receipt completion
      allows updates, rejection evidence is insert-and-read only, and queue, submission and mapping rows
      have their declared deletion grants.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: observed
    source: 'macroservice-libraries:packages/data-jobs/src/row-level-security.ts:PRIVILEGES'
    origin: none
  - id: BR-CAP-PFM-DJE-018-03
    proved_by: [ATS-PFM-DJE-018-03, TST-PFM-DJE-168]
    statement: >-
      Platform field-definition import uses metadata creation, update, archive and restore behavior;
      insert refuses an existing definition and incoming archived state is applied after its write.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#refuses
      the same change as an insert, naming the definition rather than writing a second one
    origin: 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S17'
  - id: BR-CAP-PFM-DJE-018-04
    proved_by: [ATS-PFM-DJE-018-04]
    statement: >-
      Supplied field rules replace the definition’s rule set, omitted rules remain intact, references to
      later definitions refuse the line, and archived definitions carry no rules.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: >-
      services-platform:docs/data-jobs/platform-data-operations.md#1.1 A definition's rules (the package
      format)
    origin: none
  - id: BR-CAP-PFM-DJE-018-05
    proved_by: [ATS-PFM-DJE-018-05]
    statement: >-
      Platform claims and processes queued batches in request handling after submission commits;
      exhausted transient errors pause work because there is no external queue redelivery.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: >-
      services-platform:docs/data-jobs/platform-data-operations.md#3. The batches run in the submitting
      request
    origin: none
  - id: BR-CAP-PFM-DJE-018-06
    proved_by: [ATS-PFM-DJE-018-06]
    statement: >-
      Platform parses uploaded datasets at submission and refuses more than 500 nonblank record lines
      with their count.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/jobs/custom-field-data-jobs.ts:parseDatasetLines'
    origin: none
  - id: BR-CAP-PFM-DJE-018-07
    proved_by: [ATS-PFM-DJE-001-15, ATS-PFM-DJE-016-18, ATS-PFM-DJE-018-07, ATS-PFM-DJE-018-09, ATS-PFM-DJE-018-10, TST-PFM-DJE-168]
    statement: >-
      Field-definition jobs require bulk and the appropriate create or update authority; custom-record
      and association jobs require their domain permissions with object scope checked for each line.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#refuses
      a caller who may create a definition but holds no bulk right
    origin: none
  - id: BR-CAP-PFM-DJE-018-08
    proved_by: [ATS-PFM-DJE-016-18, ATS-PFM-DJE-018-08, ATS-PFM-DJE-018-10, TST-PFM-DJE-169]
    statement: >-
      Custom-record prevalidation includes domain write rules, within-file uniqueness and association
      limits, with line-specific refusals and unchanged outcomes on repeated input.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-object-data-jobs.integration.spec.js#refuses
      a hull number an earlier line of the same file holds, naming that line
    origin: 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S17'
  - id: BR-CAP-PFM-DJE-018-09
    proved_by: []
    statement: >-
      Platform operations expose no rollback, leaving workspace reset as the recovery path for an
      unsuitable initial load.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/data-jobs/platform-data-operations.md#There is no `/rollback`'
    origin: none
  - id: BR-CAP-PFM-DJE-018-10
    proved_by: []
    statement: >-
      Membership declares organizational structure operations and parent dependencies but has no engine
      persistence, job routes or worker to execute them.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: observed
    source: 'services-membership:modules/data-jobs/services/operations/structure-data-operations.ts'
    origin: none
scenarios:
  - id: SC-CAP-PFM-DJE-018-01
    given: A field-definition dataset contains two eligible definitions and one invalid definition.
    when: The administrator submits its import.
    then: >-
      The two valid definitions apply and the invalid line becomes a refusal on a
      completed-with-rejections job.
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#applies
      the two good definitions and rejects only the bad one
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-DJE-001
  - CAP-PFM-DJE-016
journeys: []
open_questions: []
evidence:
  - >-
    Reviewed evidence: macroservice-libraries (54536a44): README.md (The operation contract; The tables;
    How a service adopts it); src/define-data-operation.ts, validate-data-job-request.ts,
    data-job-columns.ts, data-job-tables.ts, row-level-security.ts; tests
    validate-data-job-request.spec.ts, define-data-operation.spec.ts,
    tenant-isolation.integration.spec.ts.
  - >-
    Reviewed evidence: services-platform (ad3f6a65): docs/data-jobs/platform-data-operations.md;
    modules/data-jobs/services/operations/*, services/jobs/custom-field-data-jobs.ts,
    data-job-surfaces.ts; db/data-jobs.table.ts; tests custom-field-data-jobs.integration.spec.js,
    custom-object-data-jobs.integration.spec.js, custom-field-data-jobs.e2e.spec.js,
    custom-object-data-jobs.e2e.spec.js.
  - >-
    Reviewed evidence: services-crm (a8d1364f): services/operations/data-operations.ts;
    db/data-jobs.table.ts.
  - >-
    Reviewed evidence: services-membership (5994c270):
    modules/data-jobs/services/operations/structure-data-operations.ts;
    export/import-crosswalk.dataset.ts; tests structure-data-operations.integration.spec.ts.
controls: [TC-AVL-001, TC-AVL-004, 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-DAT-001, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, 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-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-DJE-05-01, FAS-PFM-DJE-05-02, FAS-PFM-DJE-05-03, FAS-PFM-DJE-05-04, FAS-PFM-DJE-05-05]
suites: [TST-PFM-DJE-015, TST-PFM-DJE-035, TST-PFM-DJE-037, TST-PFM-DJE-168, TST-PFM-DJE-169]
---

# Enable product records to use the shared job engine

## Purpose

Product areas connect their own record rules and persistence to a common job engine rather than defining separate bulk-processing behavior.

## How It Works

Each product area declares which record operations can use the engine. The declaration connects input contracts and authority to domain validation and writes. Unsupported declarations fail before serving requests. Consumer persistence supplies the common job records under workspace security. CRM uses workers and bulk workflows for its record jobs. Platform processes bounded datasets within request handling after the submission transaction commits. Its field definitions and custom records still use their domain rules. Platform has no rollback declaration for these imports. Membership’s operation declarations remain incomplete integration rather than runnable job surfaces. The product should complete that foundation before relying on Membership migration.

## Relationships

- Submission selects declared operations.
- Migration runs submit supported datasets to those operation surfaces.
