---
id: CAP-PFM-DJE-005
title: Inspect job progress and account for its changes
feature: FEAT-PFM-DJE-01
product_area: platform
module: data-job-engine
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: partially-observed
supersedes:
  - RUL-DJE-ENG-013
  - RUL-DJE-ENG-014
source_sha:
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D3'
  - 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D4'
  - 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6'
  - 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S10'
  - 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S20'
  - 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#R3'
  - >-
    services-platform:docs/milestones/plans/PLAT-M21-plan.md#Added 2026-10-22 (from PLAT-M19 review R3):
    results at scale, server side
purpose: Administrators inspect job outcomes and connect a record’s history to the work that changed it.
outcomes:
  - Authorized users can find jobs with their submitters and totals.
  - Ordered result and refusal pages explain individual outcomes.
  - Record history identifies the responsible job.
concepts:
  - CON-PFM-DJE-001
actors:
  - ACT-PFM-035
  - ACT-PFM-036
  - ACT-PFM-037
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: crm.contacts.bulk
    where_checked: api
    scope: tenant
  - key: crm.organizations.bulk
    where_checked: api
    scope: tenant
  - key: platform.custom-fields.bulk
    where_checked: api
    scope: tenant
  - key: platform.custom-records.update
    where_checked: service
    scope: tenant
  - key: data.jobs.view
    where_checked: console
    scope: tenant
rules:
  - id: BR-CAP-PFM-DJE-005-01
    proved_by: [ATS-PFM-DJE-005-01, TST-PFM-DJE-123, TST-PFM-DJE-170]
    statement: >-
      Workspace-wide access for a record kind permits viewing all of its jobs; without it, service-level
      visibility is limited to the caller’s submissions and conceals other jobs.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/jobs/list-contact-data-jobs.integration.spec.js#answers
      a caller without the bulk key only the jobs they submitted
    origin: 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S20'
  - id: BR-CAP-PFM-DJE-005-02
    proved_by: [ATS-PFM-DJE-005-02, TST-PFM-DJE-064, TST-PFM-DJE-109]
    statement: >-
      Job lists use newest-first paging with at most 100 rows and strict filters for state, operation,
      mode, submitter and submission dates.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/e2e/data-jobs.e2e.spec.js#refuses a state no job can be in
      with 400, rather than a filter it quietly ignores
    origin: 'services-platform:docs/milestones/plans/PLAT-M19-plan.md#S20'
  - id: BR-CAP-PFM-DJE-005-03
    proved_by: [ATS-PFM-DJE-001-13, ATS-PFM-DJE-003-13, ATS-PFM-DJE-005-03, ATS-PFM-DJE-005-08, ATS-PFM-DJE-005-09, TST-PFM-DJE-117]
    statement: >-
      Result and refusal pages retain input order, contain at most 100 rows and resume after the previous
      cursor; an outcome filter narrows the result set.
    kind: policy
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#answers
      the next page from the cursor the last one gave, so no item is read twice
    origin: none
  - id: BR-CAP-PFM-DJE-005-04
    proved_by: []
    statement: >-
      Delivered job details identify the producer, delivery, referenced uploads and filenames, and
      selected conflict policy.
    kind: policy
    enforced_at:
      - api
    must_prove: false
    provenance: documented
    source: 'services-crm:docs/data-jobs.md#Listing a tenant''s jobs'
    origin: none
  - id: BR-CAP-PFM-DJE-005-05
    proved_by: [ATS-PFM-DJE-003-13, ATS-PFM-DJE-005-04, ATS-PFM-DJE-005-09, ATS-PFM-DJE-005-10, ATS-PFM-DJE-008-08, TST-PFM-DJE-079, TST-PFM-DJE-117]
    statement: >-
      Record revisions commit with job and batch attribution and the submitter’s identity; change events
      also identify their job.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#stamps
      the job on the revision, so every record one job changed can be listed
    origin: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D4'
  - id: BR-CAP-PFM-DJE-005-06
    proved_by: []
    statement: An initial import records one history revision for each created record.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D3'
    origin: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D3'
  - id: BR-CAP-PFM-DJE-005-07
    proved_by: [ATS-PFM-DJE-005-05]
    statement: >-
      The product should keep jobs and their outcome evidence for 90 days after completion and allow
      rollback during that window; a retention sweep is still absent.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6'
    origin: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6'
  - id: BR-CAP-PFM-DJE-005-08
    proved_by: [ATS-PFM-DJE-005-06, TST-PFM-DJE-034]
    statement: The daily workspace purge removes idempotency entries older than 30 days.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/submission-purge.integration.spec.ts#deletes
      the tenant's rows older than 30 days and keeps the rest, the row exactly 30 days old included
    origin: none
  - id: BR-CAP-PFM-DJE-005-09
    proved_by: [ATS-PFM-DJE-005-07]
    statement: >-
      The product should provide server-side searches by record, producer key or input position, refusal
      totals by code and server-built exports; these remain planned.
    kind: policy
    enforced_at:
      - api
      - console
    must_prove: true
    provenance: documented
    source: >-
      services-platform:docs/milestones/plans/PLAT-M21-plan.md#Added 2026-10-22 (from PLAT-M19 review
      R3): results at scale, server side
    origin: 'services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#R3'
  - id: BR-CAP-PFM-DJE-005-10
    proved_by: []
    statement: Job response timestamps use UTC with millisecond precision.
    kind: policy
    enforced_at:
      - api
    must_prove: false
    provenance: test
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/jobs/data-job-instants.integration.spec.js#answers
      a finished apply’s submission, queueing, start and finish in ISO 8601
    origin: none
scenarios:
  - id: SC-CAP-PFM-DJE-005-01
    given: 'An API import contains twelve contact rows, including one invalid e-mail address.'
    when: The administrator inspects the job through Data Imports.
    then: >-
      List and detail agree on eleven applied and one refused; refusal detail identifies the row and
      field, and a created contact’s history identifies its job.
    provenance: test
    source: >-
      react-console:acceptance/data-jobs/playwright/journeys/cross-application/DJE-ACC-0050.spec.ts#DJE-ACC-0050
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-DJE-003
  - CAP-PFM-DJE-008
journeys:
  - JNY-PFM-DJE-001
  - JNY-PFM-DJE-005
open_questions: []
evidence:
  - >-
    Reviewed evidence: macroservice-libraries (54536a44): src/data-job-reads.ts, submission-purge.ts,
    data-job-config.ts; tests submission-purge.integration.spec.ts.
  - >-
    Reviewed evidence: services-crm (a8d1364f): docs/data-jobs.md (Listing a tenant's jobs; Attribution);
    services/persistence/data-jobs.ts; tests list-contact-data-jobs.integration.spec.js,
    contact-data-jobs.integration.spec.js, data-job-instants.integration.spec.js, data-jobs.e2e.spec.js.
  - >-
    Reviewed evidence: services-platform (ad3f6a65): docs/data-jobs/platform-data-operations.md (The
    surfaces); tests data-job-visibility.integration.spec.js; docs/milestones/PLAT-M19 (D3, D4, D6, R3),
    plans/PLAT-M21-plan.md.
  - >-
    Reviewed evidence: react-console (baf6dae3): dataManagement/dataJobs pages;
    components/data-management/data-jobs/data-jobs-screen.tsx, job-detail-screen.tsx,
    job-results-tab.tsx, job-rejections-tab.tsx; lib/api/data-jobs/crm.ts (CRM_SERVES_ITEM_TOOLS).
controls: [TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-DAT-005, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-DJE-01-01, FAS-PFM-DJE-01-02, FAS-PFM-DJE-01-03, FAS-PFM-DJE-01-04, FAS-PFM-DJE-01-05]
suites: [TST-PFM-DJE-034, TST-PFM-DJE-064, TST-PFM-DJE-079, TST-PFM-DJE-109, TST-PFM-DJE-117, TST-PFM-DJE-123, TST-PFM-DJE-170]
---

# Inspect job progress and account for its changes

## Purpose

Administrators inspect job outcomes and connect a record’s history to the work that changed it.

## How It Works

An administrator uses the job list to locate recent work and narrow it by the available filters. Record-kind visibility determines which submissions the service can reveal. CRM routes additionally require bulk access, so their ordinary callers already meet that wider visibility condition. Job detail exposes progress and ordered outcome pages. Staff use refusals to locate input that needs correction. Delivered work also retains source and file context. Record history provides a separate route back to the responsible job and submitter. The approved retention period and large-result tools describe work still to implement. Their absence must remain visible when Product considers approval.

## Relationships

- Batch processing creates the receipts and refusals inspected here.
- Rollback planning uses those receipts to determine restoration candidates.
