---
id: ATS-COM-FUL-006
scope: CAP-COM-FUL-006
product_area: commerce
module: fulfillment
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-FUL-006-01
    title: Frozen reversal settings select distinct responses
    level: api
    proves:
      - BR-CAP-COM-FUL-006-01
      - BR-CAP-COM-FUL-006-02
      - BR-CAP-COM-FUL-006-03
      - BR-CAP-COM-FUL-006-04
    preconditions: >-
      Delivered fixtures use review, notify, suspend, cancellation and none,
      alongside pending work.
    steps: Apply one reversal affecting all fixtures.
    expected: >-
      Three enforcement instructions are queued, required reviews are raised and
      none or pending work is untouched.
    negative: false
    data_needs: Fixtures for frozen reversal settings select distinct responses.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        four enforcements: three dispatched (suspend, cancel_line, notify), one
        for a person (review); the none policy and the pending obligation get
        nothing
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#writes
        the suspend enforcement dispatched, with its enforce obligation
        authorized, queued and nudged, keyed on the fact
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#leaves
        the review enforcement pending with an enforcement_review exception and
        no obligation, and the cancel_line one dispatched with a review for the
        request
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#suspends
        the membership in the participant with the enforcement id stored, the
        original obligation still completed, the enforcement completed
      - TST-COM-FUL-027
      - TST-COM-FUL-018
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
      four enforcements: three dispatched (suspend, cancel_line, notify), one
      for a person (review); the none policy and the pending obligation get
      nothing
    category: rule
  - id: ATS-COM-FUL-006-02
    title: An unexplained reversal creates one order finding
    level: api
    proves:
      - BR-CAP-COM-FUL-006-06
    preconditions: A delivered order has no cancellation document.
    steps: Apply its financial reversal.
    expected: >-
      The order receives a single informational refund-without-cancellation
      exception.
    negative: false
    data_needs: Fixtures for an unexplained reversal creates one order finding.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#raises
        refund_without_cancellation once per delivered order, and the
        enforcement_created line on each history
      - TST-COM-FUL-027
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#raises
      refund_without_cancellation once per delivered order, and the
      enforcement_created line on each history
    category: edge
  - id: ATS-COM-FUL-006-03
    title: Replayed reversal events do not repeat enforcement
    level: api
    proves:
      - BR-CAP-COM-FUL-006-07
      - INV-DOM-COM-FUL-001-10
    preconditions: The reversal has already been applied.
    steps: Replay the already applied financial event.
    expected: 'No additional enforcement, instruction or exception is created.'
    negative: false
    data_needs: Fixtures for replayed reversal events do not repeat enforcement.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        nothing when the same fact is enforced again (idempotent on the event
        id)
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#enforces
        nothing twice when the batch is redelivered
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#hold
        an enforcement once per obligation and cause (enforcements_cause_uq) and
        an adjustment once per document (financial_adjustments_document_uq)
      - TST-COM-FUL-027
      - TST-COM-FUL-018
      - TST-COM-FUL-025
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
      nothing when the same fact is enforced again (idempotent on the event id)
    category: invariant
  - id: ATS-COM-FUL-006-04
    title: Restoration follows application support
    level: api
    proves:
      - BR-CAP-COM-FUL-006-08
      - BR-CAP-COM-FUL-006-09
    preconditions: Enforced deliveries include products with and without restoration support.
    steps: Apply restored-funds events and replay them.
    expected: >-
      Supported restorations dispatch once, unsupported work remains with staff
      and states follow the defined lifecycle.
    negative: false
    data_needs: Fixtures for restoration follows application support.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#dispatches
        a restore for the suspended and the notified deliveries (the unlimited
        product declares one) and leaves the capacity product’s with staff
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#restores
        the suspended delivery through the participant and closes the suspension
        as restored
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        nothing on a second restore fact for an enforcement already restored
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/enforcements.queries.integration.spec.js#moves
        an enforcement along its lifecycle (pending -> dispatched -> completed
        -> restored) and refuses a move it does not allow
      - TST-COM-FUL-027
      - TST-COM-FUL-030
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#dispatches
      a restore for the suspended and the notified deliveries (the unlimited
      product declares one) and leaves the capacity product’s with staff
    category: transition
  - id: ATS-COM-FUL-006-05
    title: Review resolution requires authority and cannot repeat
    level: api
    proves:
      - BR-CAP-COM-FUL-006-10
    preconditions: An enforcement awaits review.
    steps: >-
      Resolve using reader authority, administrator authority and then the
      administrator again.
    expected: >-
      Only the first authorized resolution succeeds and closes the review
      finding.
    negative: true
    data_needs: Fixtures for review resolution requires authority and cannot repeat.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#resolves
        the seat’s review on its route with the reason and the resolution,
        refusing a reader and a repeat
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#resolves
        the reviewed enforcement with its review exception, naming who; a
        resolved one is refused
      - TST-COM-FUL-018
      - TST-COM-FUL-070
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#resolves
      the seat’s review on its route with the reason and the resolution,
      refusing a reader and a repeat
    category: permission
  - id: ATS-COM-FUL-006-06
    title: >-
      Reversal enforcement completes beside the original delivery and remains
      reviewable
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-004-04
      - BR-CAP-COM-FUL-006-02
      - BR-CAP-COM-FUL-006-03
      - BR-CAP-COM-FUL-008-01
    exercises:
      - CAP-COM-FUL-004
      - CAP-COM-FUL-006
      - CAP-COM-FUL-008
    relies_on:
      - ATS-COM-FUL-004-03
      - ATS-COM-FUL-006-01
      - ATS-COM-FUL-008-01
    preconditions: >-
      A delivered membership uses suspension on reversal and a delivered seat
      uses staff review.
    steps: >-
      Reverse their payments, dispatch the acting instruction, and inspect the
      review queue.
    expected: >-
      The membership is suspended beside its unchanged delivery result; the seat
      remains a staff review.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#suspends
        the membership in the participant with the enforcement id stored, the
        original obligation still completed, the enforcement completed
      - TST-COM-FUL-018
    provenance: test
    source:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#completes
        the obligation and answers it as it stands; the repeat answers the same
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        four enforcements: three dispatched (suspend, cancel_line, notify), one
        for a person (review); the none policy and the pending obligation get
        nothing
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#lists
        the finding the reconciler raised about the unbilled order, filtered by
        kind, state and order, and never another tenant’s
evidence:
  - repository: services-commerce
    tests:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        four enforcements: three dispatched (suspend, cancel_line, notify), one
        for a person (review); the none policy and the pending obligation get
        nothing
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#writes
        the suspend enforcement dispatched, with its enforce obligation
        authorized, queued and nudged, keyed on the fact
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#leaves
        the review enforcement pending with an enforcement_review exception and
        no obligation, and the cancel_line one dispatched with a review for the
        request
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#suspends
        the membership in the participant with the enforcement id stored, the
        original obligation still completed, the enforcement completed
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#raises
        refund_without_cancellation once per delivered order, and the
        enforcement_created line on each history
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        nothing when the same fact is enforced again (idempotent on the event
        id)
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#enforces
        nothing twice when the batch is redelivered
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#hold
        an enforcement once per obligation and cause (enforcements_cause_uq) and
        an adjustment once per document (financial_adjustments_document_uq)
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#dispatches
        a restore for the suspended and the notified deliveries (the unlimited
        product declares one) and leaves the capacity product’s with staff
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#restores
        the suspended delivery through the participant and closes the suspension
        as restored
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#creates
        nothing on a second restore fact for an enforcement already restored
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/enforcements.queries.integration.spec.js#moves
        an enforcement along its lifecycle (pending -> dispatched -> completed
        -> restored) and refuses a move it does not allow
      - >-
        services-commerce:modules/fulfillment/tests/e2e/enforcement.e2e.spec.js#resolves
        the seat’s review on its route with the reason and the resolution,
        refusing a reader and a repeat
      - >-
        services-commerce:modules/operations/tests/integration/services/interventions/operations-interventions.integration.spec.js#resolves
        the reviewed enforcement with its review exception, naming who; a
        resolved one is refused
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-COM-FUL-061'
  permission: covered
  edge: covered
  failure: 'gap: FND-COM-FUL-061'
  boundary: 'gap: FND-COM-FUL-061'
  concurrency: 'gap: FND-COM-FUL-061'
  invariant: covered
  interaction: covered
coverage_notes:
  validation: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  failure: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  boundary: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  concurrency: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
transition_audit:
  - model: STATE-COM-FUL-002
    from: pending
    to: dispatched
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/enforcement/enforcement-handler.integration.spec.js#leaves
      the review enforcement pending with an enforcement_review exception and no
      obligation, and the cancel_line one dispatched with a review for the
      request
    coverage: covered
    scenarios:
      - ATS-COM-FUL-006-01
  - model: STATE-COM-FUL-002
    from: pending
    to: resolved
    source: >-
      services-commerce:modules/operations/services/interventions/operations-interventions.ts
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: pending
    to: restored
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts:settleEnforcement
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: dispatched
    to: completed
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/persistence/enforcements.queries.integration.spec.js#moves
      an enforcement along its lifecycle (pending -> dispatched -> completed ->
      restored) and refuses a move it does not allow
    coverage: covered
    scenarios:
      - ATS-COM-FUL-006-04
  - model: STATE-COM-FUL-002
    from: dispatched
    to: failed
    source: >-
      services-commerce:modules/fulfillment/services/register/register-sweeper.ts:sweepRegister
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: dispatched
    to: resolved
    source: >-
      services-commerce:modules/fulfillment/services/persistence/enforcements.ts:ENFORCEMENT_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: failed
    to: dispatched
    source: >-
      services-commerce:modules/fulfillment/services/persistence/enforcements.ts:ENFORCEMENT_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: failed
    to: resolved
    source: >-
      services-commerce:modules/fulfillment/services/persistence/enforcements.ts:ENFORCEMENT_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: completed
    to: restored
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts:settleEnforcement
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: completed
    to: resolved
    source: >-
      services-commerce:modules/fulfillment/services/persistence/enforcements.ts:ENFORCEMENT_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
  - model: STATE-COM-FUL-002
    from: resolved
    to: restored
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-worker.ts:settleEnforcement
    coverage: 'gap: FND-COM-FUL-061'
    scenarios: []
permission_audit:
  - key: commerce.enforcements.read
    where_checked: api
    coverage: 'gap: FND-COM-FUL-061'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.enforcements.resolve
    where_checked: api
    coverage: 'gap: FND-COM-FUL-061'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
related_audit:
  - capability: CAP-COM-FUL-008
    scenarios:
      - ATS-COM-FUL-006-06
invariant_audit:
  - invariant: INV-DOM-COM-FUL-001-01
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_subject_uq
  - invariant: INV-DOM-COM-FUL-001-02
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:OBLIGATION_TRANSITIONS;
      db/migrations/20261018004016_obligation_register.sql:refuse_obligation_regression
  - invariant: INV-DOM-COM-FUL-001-03
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_authorization_state_check
  - invariant: INV-DOM-COM-FUL-001-04
    scenarios:
      - ATS-COM-FUL-004-03
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_quantity_check
  - invariant: INV-DOM-COM-FUL-001-05
    scenarios:
      - ATS-COM-FUL-002-08
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:openGate
  - invariant: INV-DOM-COM-FUL-001-06
    scenarios:
      - ATS-COM-FUL-004-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordObligationOutcome
  - invariant: INV-DOM-COM-FUL-001-07
    scenarios:
      - ATS-COM-FUL-005-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligation-attempts.table.ts;
      modules/fulfillment/db/intervention-logs.table.ts (UPDATE, DELETE and
      TRUNCATE revoked)
  - invariant: INV-DOM-COM-FUL-001-08
    scenarios:
      - ATS-COM-FUL-005-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-interventions.ts
  - invariant: INV-DOM-COM-FUL-001-09
    scenarios:
      - ATS-COM-FUL-005-03
    coverage: covered
    provenance: test
    source: >-
      services-commerce:docs/migrations/obligation-register/README.md#D-P4-16
      (obligation-register.e2e five simultaneous approvals)
  - invariant: INV-DOM-COM-FUL-001-10
    scenarios:
      - ATS-COM-FUL-006-03
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/enforcements.table.ts:enforcements_cause_uq
  - invariant: INV-DOM-COM-FUL-001-11
    scenarios:
      - ATS-COM-FUL-002-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/facts/financial-facts-handler.ts
  - invariant: INV-DOM-COM-FUL-001-12
    scenarios: []
    coverage: 'gap: FND-COM-FUL-061'
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts (composite
      RESTRICT keys)
  - invariant: INV-DOM-COM-FUL-003-01
    scenarios:
      - ATS-COM-FUL-008-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/operational-exceptions.table.ts:operational_exceptions_open_uidx
  - invariant: INV-DOM-COM-FUL-003-02
    scenarios:
      - ATS-COM-FUL-009-04
    coverage: covered
    provenance: documented
    source: 'services-commerce:docs/migrations/operations/README.md#D-P5-08'
  - invariant: INV-DOM-COM-FUL-003-03
    scenarios:
      - ATS-COM-FUL-008-03
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/operations/services/interventions/operations-interventions.ts
  - invariant: INV-DOM-COM-FUL-003-04
    scenarios:
      - ATS-COM-FUL-009-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/operations/services/persistence/reconciler-candidates.ts
  - invariant: INV-DOM-COM-FUL-003-05
    scenarios:
      - ATS-COM-FUL-007-01
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/financial-adjustments.ts:requestFinancialAdjustment
  - invariant: INV-DOM-COM-FUL-003-06
    scenarios:
      - ATS-COM-FUL-007-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/adjustments/adjustment-worker.ts:planAdjustmentSteps
  - invariant: INV-DOM-COM-FUL-003-07
    scenarios: []
    coverage: 'gap: FND-COM-FUL-061'
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/financial-adjustments.ts:ADJUSTMENT_TRANSITIONS
  - invariant: INV-DOM-COM-FUL-003-08
    scenarios:
      - ATS-COM-FUL-007-03
    coverage: covered
    provenance: documented
    source: 'services-commerce:docs/migrations/operations/README.md#D-P5-06'
---

# Handle financial reversals after delivery: Capability Test Specification

## Coverage

The category map distinguishes available cases from missing proof. A covered category has a scenario; the lifecycle and permission audits retain gaps in exhaustive coverage. Proposed cases describe the intended verification and carry no execution result.

| Rule | Scenarios |
|---|---|
| `BR-CAP-COM-FUL-006-01` | `ATS-COM-FUL-006-01`, `ATS-COM-FUL-006-06` |
| `BR-CAP-COM-FUL-006-02` | `ATS-COM-FUL-006-01`, `ATS-COM-FUL-006-06` |
| `BR-CAP-COM-FUL-006-03` | `ATS-COM-FUL-006-01`, `ATS-COM-FUL-006-06` |
| `BR-CAP-COM-FUL-006-04` | `ATS-COM-FUL-006-01`, `ATS-COM-FUL-006-06` |
| `BR-CAP-COM-FUL-006-06` | `ATS-COM-FUL-006-02` |
| `BR-CAP-COM-FUL-006-07` | `ATS-COM-FUL-006-03` |
| `BR-CAP-COM-FUL-006-08` | `ATS-COM-FUL-006-04` |
| `BR-CAP-COM-FUL-006-09` | `ATS-COM-FUL-006-04` |
| `BR-CAP-COM-FUL-006-10` | `ATS-COM-FUL-006-05` |

## Interactions With Related Capabilities

The interaction cases exercise review and resolve operations findings. They vary the upstream record or outcome and inspect the resulting work across the capability boundary. Workflow crossings also include stock, financial or application records when the flow depends on them. Existing test bindings retain their source anchors so a reviewer can distinguish supporting assertions from a complete workflow run.
