---
id: TST-PFM-DJE-115
title: Bulk data jobs
kind: integration
product_area: platform
module: data-job-engine
revision: 1
status: draft
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
repository: services-crm
files:
  - modules/data-jobs/tests/integration/services/jobs/bulk-data-jobs.integration.spec.js
implements: []
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 5
isolation: >-
  Suite-owned fixture records, job identifiers and workspace contexts; teardown removes the fixture
  data.
evidence:
  - >-
    services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-jobs.integration.spec.js
assertion_inventory:
  - a bulk job of two thousand contacts in one uploaded file
  - >-
    accepts the submission on the bulk lane, with no items counted yet, because nobody has read the
    file
  - 'freezes the object the upload named, with its version, so the job reads one immutable file'
  - >-
    writes the file into chunk files under the tenant’s own prefix, which is the engine’s key and
    never a caller’s
  - counts every line of the file as an item of the job
  - >-
    records each chunk on the job, with the item positions it holds, which is how a batch finds its
    records
  - >-
    freezes no item rows: a bulk job’s items are the lines of its chunk files, not rows of the
    database
  - plans one batch per chunk and counts them on the job
  - 'applies every record of the file, each as a new contact'
  - 'writes one crosswalk row per source key, each naming the contact it created'
  - 'finishes the job as succeeded, with every record counted as applied'
  - 'settles the orchestration, which is the task that finishes the job'
  - >-
    reports the orchestration’s four working steps as completed, which is what a person watching the
    import sees
  - the same file delivered a second time
  - creates every record on the first delivery
  - >-
    creates nothing on the second: an insert of a key the crosswalk already knows is a duplicate,
    every time
  - 'leaves one crosswalk row per source key, still of the producer that delivered it'
  - the producer’s identity on the contacts of a delivered file
  - keeps the external id a line sends as the contact’s own
  - keeps the producer’s key as the external id of the contact whose line sends none
  - 'a corrected file of a job’s rejections, submitted as a bulk job'
  - 'keeps the link on the job row it writes, as the interactive lane keeps it'
  - 'answers the link on the job’s status, which is what says the rejected job was corrected'
  - answers the link on the job’s row of the list
  - what a delivered job’s status says of its submission
  - >-
    names the producer, its delivery and the file the job reads, by its upload and its own name,
    never by bucket or key
  - 'names the conflict policy the delivery chose, which says it may overwrite a staff member’s edit'
  - >-
    answers no delivery id for a delivery that named none, rather than leaving the producer’s name
    out
  - 'names the policy a delivery that chose none runs under, the engine’s reject'
  - a bulk submission that names an upload it may not read
  - 'refuses an upload id of no upload of this tenant, saying only that it was not found'
  - 'refuses an upload whose file has not arrived, naming the state it is in'
registration_note: Registration describes existing source; the suite is not executed by this documentation job.
---

# Bulk data jobs

## Verification Boundary

The suite checks the production service or shared engine against its database fixture. The structured assertion inventory records the checks present at the pinned revision.

## What This Suite Proves

The existing checks exercise bulk data jobs. The specification bindings identify the narrower outcomes supported by those assertions.

## What It Does Not Prove

Local execution does not establish deployed queue, storage or service behavior. Independent test cases do not establish a complete cross-feature process.

## Real Dependencies and Test Doubles

The owning service exercises production persistence and domain behavior against real Postgres. The fixture supplies caller contexts; queue delivery, storage and external calls are doubled where the file installs a test port.

## Must Not Be Doubled

The database effects, security context and production operation under examination remain real. Their outcomes cannot be replaced with canned success responses.
