---
id: TST-ACC-PRD-036
title: Financial setup persistence and grouped rollback
kind: integration
product_area: accounting
module: products
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
repository: services-accounting
files:
  - modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
implements:
  - ATS-ACC-PRD-015-03
  - ATS-ACC-PRD-015-04
  - ATS-ACC-PRD-015-05
  - ATS-ACC-PRD-015-06
  - ATS-ACC-PRD-015-07
  - ATS-ACC-PRD-015-08
  - ATS-ACC-PRD-015-09
  - ATS-ACC-PRD-015-10
  - ATS-ACC-PRD-016-01
  - ATS-ACC-PRD-016-02
  - ATS-ACC-PRD-016-03
  - ATS-ACC-PRD-016-04
  - ATS-ACC-PRD-016-05
  - ATS-ACC-PRD-016-06
  - ATS-ACC-PRD-016-07
  - ATS-ACC-PRD-017-02
  - ATS-ACC-PRD-017-03
  - ATS-ACC-PRD-017-04
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 3
estimation_note: Planning estimate; no runtime measurement is claimed.
isolation: 'Suite-named local workspaces, isolated fixture records and explicit cleanup or rollback.'
evidence:
  - >-
    services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
assertion_bindings:
  - scenario: ATS-ACC-PRD-015-03
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a revenue GL account of another business unit, naming both units
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a write-off GL account of another business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a department of another business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an accounting project of another business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a merchant account of another business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a GL account the tenant does not have
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-04
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an asset account as the revenue account, naming the slot and the types it takes, and writes no setup
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an income account as the receivable
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an income account as the deferred revenue account
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an account of the wrong kind in the write-off, cost of goods sold and inventory slots
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#accepts
        every slot holding an account of its type (premise of the refusals)
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-05
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        it newly named in another field
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#keeps
        it on an edit that changes only the notes
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        newly assigning an inactive GL account
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        newly assigning an inactive department
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-06
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#names
        an active tax class of the tenant, whatever the product’s business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        newly choosing an inactive tax class
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        another tenant’s tax class as one the tenant does not have
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-07
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        replacing a setup without the version read
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-08
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#leaves
        the previous setup and collections when a rule refuses the replacement
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#answers
        the replaced setup at version 2, its cleared fields left out and every collection replaced
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#leaves
        the previous setup and collections when the database refuses a new row after the old ones were removed
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-09
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#unlocks
        a setup locked against updates when the replacement states sys_locked null, then deletes it
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a setup locked against updates
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a setup locked against deletes
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-015-10
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#leaves
        the product, its accounting summary null
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-01
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        deferring revenue without a deferred revenue GL account
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-02
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        percentages that add up to less than 100, in Rhythm 1.0’s words
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        the fixed_dates strategy without fixed dates
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        percentages that add up to more than 100
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#accepts
        fractional percentages that add up to exactly 100
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        the same date twice
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-03
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#REGRESSION
        — refuses 1-3 beside 11-2, the wrapping last rule overlapping the first, which Rhythm 1.0 accepted
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        the relative_dates strategy without relative rules
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        two ranges sharing a month, in Rhythm 1.0’s words
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a range wrapping the year end overlapping the next, in Rhythm 1.0’s multi-year words
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#accepts
        disjoint ranges, one wrapping the year end, and stores them by start month
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-04
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a percentage split that also states an amount
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-05
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        fixed amounts adding up to more than the standard base price
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        percentages that add up to more than 100, in Rhythm 1.0’s words
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#accepts
        percentages that add up to exactly 100
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#accepts
        fixed amounts adding up to the standard base price
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-06
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#keeps
        the id of a split sent back
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#keeps
        the id a new split is sent with
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        two splits with the same id
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-016-07
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a liability account of a third unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an entry for the product’s own business unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        two entries for the same unit
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a business unit the tenant does not have
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a receivable account of the product’s own unit
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-017-02
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        101 setups before reading any product
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#saves
        100 setups in one request
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-017-03
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a rule of a later setup naming its position and product, the earlier create rolled back
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a stale version 409 naming the product, the earlier replacement rolled back
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a replacement without its version, naming the product
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a setup locked against updates 409, naming the product
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
  - scenario: ATS-ACC-PRD-017-04
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        a product named twice, naming both positions
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#refuses
        an unknown product 400, naming it, before writing any setup
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js
coverage_note: Scenario references name existing assertion evidence; broader unexecuted variants remain findings.
---

# Financial setup persistence and grouped rollback

## Verification Boundary

The suite exercises real PostgreSQL and Accounting persistence or database functions with isolated local workspace fixtures.

## What This Suite Proves

Setup persistence checks accounts, deferral, allocations, references and versions; grouped replacement verifies complete local rollback on a later refusal.

## What It Does Not Prove

Local execution does not prove deployed infrastructure, downstream purchase behavior, real domain extension completion or atomic remote-template recovery.

## Real Dependencies and Test Doubles

PostgreSQL, transaction context, constraints, foreign keys and Accounting persistence are real. The test owns its workspace fixtures and clock.

## Must Not Be Doubled

Do not double PostgreSQL, row-level security, transaction boundaries, constraints or the persistence implementation when claiming these local guarantees.
