---
id: ATS-ACC-BKS-005
scope: CAP-ACC-BKS-005
product_area: accounting
module: books
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-ACC-BKS-005-01
    title: Normalize codes within each unit
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-01
      - INV-DOM-ACC-BKS-002-01
    preconditions: Two separate units exist.
    steps: >-
      Create a lower-case code, repeat its upper-case form locally, then use it
      in the other unit.
    expected: >-
      The code is stored upper-case with a derived identity, the local repeat is
      refused and the other-unit code succeeds.
    negative: false
    data_needs: The setup needs no extra fixture records.
    bound_to:
      - TST-ACC-BKS-055
      - TST-ACC-BKS-089
      - TST-ACC-BKS-063
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#stores
      the code trimmed and upper-cased, under the id from the lower-cased code
    category: validation
    binding_evidence:
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#stores
        the code trimmed and upper-cased, under the id from the lower-cased code
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
        a second account with a code the unit already has, naming the code, when
        the id is derived (DEF-ACT-0001)
      - >-
        services-accounting:modules/books/tests/integration/db/configuration-records.table.integration.spec.js#accepts
        the same code in another unit
  - id: ATS-ACC-BKS-005-02
    title: Keep account identity stable
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-02
    preconditions: A saved USD account has a unit and code.
    steps: 'Change code, unit and currency in separate replacements.'
    expected: Each receives a field-specific conflict.
    negative: true
    data_needs: The setup needs no extra fixture records.
    bound_to: []
    provenance: proposed
    source: FND-ACC-BKS-081
    category: invariant
    binding_evidence:
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        409 to a change of code, naming the column
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        409 to a change of business unit, naming the column
      - >-
        services-accounting:modules/books/tests/integration/db/configuration-records.table.integration.spec.js#refuses
        a change of currency_code (RHF01)
    candidate_bindings:
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        409 to a change of code, naming the column
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        409 to a change of business unit, naming the column
      - >-
        services-accounting:modules/books/tests/integration/db/configuration-records.table.integration.spec.js#refuses
        a change of currency_code (RHF01)
    finding: FND-ACC-BKS-081
    note: >-
      Code and unit refusals have test evidence. The currency refusal has a
      database test but no matching service guard; the complete expectation
      awaits conformance verification.
  - id: ATS-ACC-BKS-005-03
    title: Present default and invalid account types
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-03
    preconditions: A unit is ready for account setup.
    steps: Create a nameless account with no type and another with an unknown type.
    expected: The first defaults to income and displays its code; the other is refused.
    negative: false
    data_needs: The setup needs no extra fixture records.
    bound_to:
      - TST-ACC-BKS-055
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#defaults
      the account type to income
    category: rule
    binding_evidence:
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#defaults
        the account type to income
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        the code alone as the display_name
      - >-
        services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
        400 to an account type that is not one of the fourteen
  - id: ATS-ACC-BKS-005-04
    title: Retain referenced accounts
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-04
      - INV-DOM-ACC-BKS-002-05
    preconditions: Each restricting kind references the account in turn.
    steps: Attempt account removal for each reference.
    expected: The conflict identifies the dependency and retains the account.
    negative: true
    data_needs: The setup needs no extra fixture records.
    bound_to:
      - TST-ACC-BKS-089
      - TST-ACC-BKS-009
    provenance: test
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
      the refusal of each restrict foreign key to a GL account into a 409 naming
      it
    category: failure
    binding_evidence:
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
        the refusal of each restrict foreign key to a GL account into a 409
        naming it
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
        an account a bank account uses, naming bank accounts, and keeps it
      - >-
        react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0010.spec.ts#ACT-ACC-0010
  - id: ATS-ACC-BKS-005-05
    title: Protect default destinations
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-05
      - INV-DOM-ACC-BKS-002-04
    preconditions: The account supplies receivable and deferral purposes.
    steps: Try deactivation and deletion.
    expected: Both are refused with purposes listed in their display order.
    negative: true
    data_needs: The setup needs no extra fixture records.
    bound_to:
      - TST-ACC-BKS-089
      - TST-ACC-BKS-049
    provenance: test
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
      deactivating the unit’s Accounts Receivable default, naming the purpose
    category: invariant
    binding_evidence:
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
        deactivating the unit’s Accounts Receivable default, naming the purpose
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
        an account that is two defaults, naming both purposes in display order
      - >-
        services-accounting:modules/books/tests/e2e/default-gl-accounts.e2e.spec.js#answers
        409 to the deactivation, naming the purpose it serves
  - id: ATS-ACC-BKS-005-06
    title: Exercise the grants for maintain a business unit’s chart
    category: permission
    level: api
    proves:
      - BR-CAP-ACC-BKS-016-01
    preconditions: >-
      An application-authorized reader and administrator share the run-owned
      setup. A third principal lacks the relevant resource grant.
    steps: >-
      Read the relevant configuration as the reader, attempt each supported
      mutation, then repeat with the matching administrator grants. Repeat the
      reads without their resource grants.
    expected: >-
      The permission outcomes match the cited authorization rule, and refused
      mutations leave every configured value unchanged.
    negative: true
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/books/tests/e2e/configuration-security.e2e.spec.js#is
      refused the create 403 permission_missing
    permissions_exercised:
      - accounting.gl-accounts.read
      - accounting.gl-accounts.create
      - accounting.gl-accounts.update
      - accounting.gl-accounts.delete
    binding_evidence: []
    supporting_tests:
      - >-
        services-accounting:modules/books/tests/e2e/configuration-security.e2e.spec.js#is
        refused the create 403 permission_missing
  - id: ATS-ACC-BKS-005-07
    title: Chart page-size endpoints
    category: boundary
    level: api
    proves:
      - BR-CAP-ACC-BKS-005-06
    preconditions: >-
      An isolated workspace has records needed for both eligible and ineligible
      examples.
    steps: >-
      Read a populated chart with page sizes one and five hundred, then request
      five hundred and one.
    expected: >-
      Eligible page sizes return bounded pages; the excessive request is
      refused.
    negative: true
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
      every account by business unit, then code
    binding_evidence: []
  - id: ATS-ACC-BKS-005-08
    title: Refuse the second replacement of a shared read version
    category: concurrency
    level: api
    proves:
      - BR-CAP-ACC-BKS-016-05
    preconditions: >-
      Two administrators read the same version of the relevant mutable record.
      Each prepares a different otherwise valid replacement.
    steps: >-
      Release both replacement requests from a barrier. Read the record again
      and retry the losing payload at its original version.
    expected: >-
      One replacement commits, the other is stale, and repeating the stale
      request preserves the winning values.
    negative: true
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/books/tests/e2e/payment-terms.e2e.spec.js#answers
      400 naming is_active to a replacement that leaves it out
    interaction_with:
      - CAP-ACC-BKS-016
    binding_evidence: []
  - id: ATS-ACC-BKS-005-09
    title: Released default frees its chart destination
    category: interaction
    level: browser
    proves:
      - BR-CAP-ACC-BKS-005-05
      - BR-CAP-ACC-BKS-006-04
    preconditions: >-
      Run-owned records satisfy the preconditions of the referenced capability
      proofs.
    steps: >-
      Assign an account as a default, try deactivation, clear the assignment
      twice and deactivate the account.
    expected: Only the released destination can become inactive.
    negative: false
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to:
      - TST-ACC-BKS-007
    provenance: test
    source:
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
        deactivating the unit’s Accounts Receivable default, naming the purpose
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/default-gl-accounts.integration.spec.js#answers
        the purpose with no account when clearing a purpose the unit has no
        default for
    exercises:
      - CAP-ACC-BKS-005
      - CAP-ACC-BKS-006
    workflows: []
    binding_evidence:
      - >-
        react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0008.spec.ts#ACT-ACC-0008
  - id: ATS-ACC-BKS-005-10
    title: A receiving account prevents chart removal
    category: interaction
    level: browser
    proves:
      - BR-CAP-ACC-BKS-005-04
      - BR-CAP-ACC-BKS-007-01
    preconditions: >-
      Run-owned records satisfy the preconditions of the referenced capability
      proofs.
    steps: >-
      Create a receiving destination on a local chart account, try removing the
      chart account, remove the destination and retry.
    expected: >-
      The dependency blocks the first removal and its release permits the later
      removal.
    negative: false
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to:
      - TST-ACC-BKS-009
    provenance: test
    source:
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
        the refusal of each restrict foreign key to a GL account into a 409
        naming it
      - >-
        services-accounting:modules/books/tests/e2e/bank-accounts.e2e.spec.js#answers
        400 to another unit’s GL account, naming both units
    exercises:
      - CAP-ACC-BKS-005
      - CAP-ACC-BKS-007
    workflows: []
    binding_evidence:
      - >-
        react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0010.spec.ts#ACT-ACC-0010
  - id: ATS-ACC-BKS-005-11
    title: A tax destination prevents chart removal
    category: interaction
    level: browser
    proves:
      - BR-CAP-ACC-BKS-005-04
      - BR-CAP-ACC-BKS-013-02
    preconditions: >-
      Run-owned records satisfy the preconditions of the referenced capability
      proofs.
    steps: >-
      Map a tax rate to the unit account, try deleting that account, remove the
      mapping and retry.
    expected: >-
      The mapped destination remains protected until the tax reference is
      released.
    negative: false
    data_needs: >-
      Run-owned records for the stated setup; retain the initial values for
      comparison.
    bound_to:
      - TST-ACC-BKS-009
    provenance: test
    source:
      - >-
        services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
        the refusal of each restrict foreign key to a GL account into a 409
        naming it
      - >-
        react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0022.spec.ts#ACT-ACC-0022
    exercises:
      - CAP-ACC-BKS-005
      - CAP-ACC-BKS-013
    workflows: []
    binding_evidence:
      - >-
        react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0010.spec.ts#ACT-ACC-0010
evidence:
  - >-
    Verified source file:
    react-console:acceptance/accounting/playwright/journeys/configuration/ACT-ACC-0010.spec.ts
  - >-
    Verified source file:
    services-accounting:modules/books/tests/e2e/default-gl-accounts.e2e.spec.js
  - >-
    Verified source file:
    services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js
  - >-
    Verified source file:
    services-accounting:modules/books/tests/integration/db/configuration-records.table.integration.spec.js
  - >-
    Verified source file:
    services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js
product_intent: proposed
coverage:
  rule: covered
  transition: 'gap: FND-ACC-BKS-066'
  validation: covered
  permission: covered
  edge: 'gap: FND-ACC-BKS-066'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: 'gap: FND-ACC-BKS-081'
  interaction: covered
coverage_notes:
  rule:
    scenarios:
      - ATS-ACC-BKS-005-03
    provenance: documented
    source:
      - ATS-ACC-BKS-005-03
  transition:
    scenarios: []
    provenance: unknown
    source: FND-ACC-BKS-066
    reason: >-
      No scenario isolates this category for the capability at the pinned
      revision.
    gap: FND-ACC-BKS-066
  validation:
    scenarios:
      - ATS-ACC-BKS-005-01
    provenance: documented
    source:
      - ATS-ACC-BKS-005-01
  permission:
    scenarios:
      - ATS-ACC-BKS-005-06
    provenance: documented
    source:
      - ATS-ACC-BKS-005-06
  edge:
    scenarios: []
    provenance: unknown
    source: FND-ACC-BKS-066
    reason: >-
      No scenario isolates this category for the capability at the pinned
      revision.
    gap: FND-ACC-BKS-066
  failure:
    scenarios:
      - ATS-ACC-BKS-005-04
    provenance: documented
    source:
      - ATS-ACC-BKS-005-04
  boundary:
    scenarios:
      - ATS-ACC-BKS-005-07
    provenance: documented
    source:
      - ATS-ACC-BKS-005-07
  concurrency:
    scenarios:
      - ATS-ACC-BKS-005-08
    provenance: documented
    source:
      - ATS-ACC-BKS-005-08
  invariant:
    scenarios:
      - ATS-ACC-BKS-005-02
      - ATS-ACC-BKS-005-05
    provenance: unknown
    source: FND-ACC-BKS-081
    gap: FND-ACC-BKS-081
    reason: >-
      The examples isolate part of this category; the finding records its
      remaining specification or execution boundary.
  interaction:
    scenarios:
      - ATS-ACC-BKS-005-09
      - ATS-ACC-BKS-005-10
      - ATS-ACC-BKS-005-11
    provenance: documented
    source:
      - ATS-ACC-BKS-005-09
      - ATS-ACC-BKS-005-10
      - ATS-ACC-BKS-005-11
rule_coverage:
  - rule: BR-CAP-ACC-BKS-005-01
    scenarios:
      - ATS-ACC-BKS-005-01
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#stores
      the code trimmed and upper-cased, under the id from the lower-cased code
  - rule: BR-CAP-ACC-BKS-005-02
    scenarios:
      - ATS-ACC-BKS-005-02
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
      409 to a change of code, naming the column
    gap: FND-ACC-BKS-081
    reason: >-
      The currency refusal conflicts with the service guard; the complete proof
      remains proposed.
  - rule: BR-CAP-ACC-BKS-005-03
    scenarios:
      - ATS-ACC-BKS-005-03
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
      400 to an account type that is not one of the fourteen
  - rule: BR-CAP-ACC-BKS-005-04
    scenarios:
      - ATS-ACC-BKS-005-04
      - ATS-ACC-BKS-005-10
      - ATS-ACC-BKS-005-11
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
      the refusal of each restrict foreign key to a GL account into a 409 naming
      it
  - rule: BR-CAP-ACC-BKS-005-05
    scenarios:
      - ATS-ACC-BKS-005-05
      - ATS-ACC-BKS-005-09
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#refuses
      deactivating the unit’s Accounts Receivable default, naming the purpose
related_coverage:
  - capability: CAP-ACC-BKS-006
    scenarios:
      - ATS-ACC-BKS-005-09
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
  - capability: CAP-ACC-BKS-007
    scenarios:
      - ATS-ACC-BKS-005-10
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
  - capability: CAP-ACC-BKS-013
    scenarios:
      - ATS-ACC-BKS-005-11
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
workflow_coverage: []
coverage_interpretation: >-
  Covered means a specified scenario exists. Proposed scenarios and registered
  bindings do not establish a passed run or verified conformance.
invariant_coverage:
  - invariant: INV-DOM-ACC-BKS-002-01
    scenarios:
      - ATS-ACC-BKS-005-01
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
      409 to a change of code, naming the column
  - invariant: INV-DOM-ACC-BKS-002-02
    scenarios:
      - ATS-ACC-BKS-002-06
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/gl-accounts.e2e.spec.js#answers
      400 to a currency the unit is not enabled for, in Rhythm 1.0’s words
  - invariant: INV-DOM-ACC-BKS-002-03
    scenarios:
      - ATS-ACC-BKS-006-02
      - ATS-ACC-BKS-007-01
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/default-gl-accounts.e2e.spec.js#answers
      400 to another unit’s GL account, naming both units
  - invariant: INV-DOM-ACC-BKS-002-04
    scenarios:
      - ATS-ACC-BKS-005-05
    provenance: documented
    source: >-
      services-accounting:modules/books/db/gl-accounts.table.ts:gl_accounts_default_guard_trigger
  - invariant: INV-DOM-ACC-BKS-002-05
    scenarios:
      - ATS-ACC-BKS-005-04
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/gl-accounts.integration.spec.js#translates
      the refusal of each restrict foreign key to a GL account into a 409 naming
      it
  - invariant: INV-DOM-ACC-BKS-002-06
    scenarios:
      - ATS-ACC-BKS-006-02
      - ATS-ACC-BKS-006-06
    provenance: documented
    source: >-
      services-accounting:modules/books/db/business-unit-default-gl-accounts.table.ts:business_unit_default_gl_accounts_active_trigger
  - invariant: INV-DOM-ACC-BKS-002-07
    scenarios:
      - ATS-ACC-BKS-007-02
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/bank-accounts.e2e.spec.js#answers
      400 to an account_number_last4 of five digits
  - invariant: INV-DOM-ACC-BKS-002-08
    scenarios:
      - ATS-ACC-BKS-007-04
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/merchant-accounts.e2e.spec.js#answers
      400 to a processor account reference without a processor
  - invariant: INV-DOM-ACC-BKS-002-09
    scenarios:
      - ATS-ACC-BKS-008-01
      - ATS-ACC-BKS-008-02
    provenance: documented
    source: >-
      services-accounting:modules/books/tests/e2e/departments.e2e.spec.js#answers
      400 to a code the unit already has, under the id it derives
permission_coverage:
  - key: accounting.gl-accounts.read
    where_checked: api
    scenarios:
      - ATS-ACC-BKS-005-06
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
    execution_gap: FND-ACC-BKS-066
  - key: accounting.gl-accounts.create
    where_checked: api
    scenarios:
      - ATS-ACC-BKS-005-06
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
    execution_gap: FND-ACC-BKS-066
  - key: accounting.gl-accounts.update
    where_checked: api
    scenarios:
      - ATS-ACC-BKS-005-06
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
    execution_gap: FND-ACC-BKS-066
  - key: accounting.gl-accounts.delete
    where_checked: api
    scenarios:
      - ATS-ACC-BKS-005-06
    provenance: documented
    source: >-
      specs/accounting/books/planning/capabilities/CAP-ACC-BKS-005-keep-each-business-units-chart-of-accounts.md
    execution_gap: FND-ACC-BKS-066
reviewed_at: '2026-10-23'
---

# Maintain a business unit’s chart: Capability Test Specification

## Coverage

- Normalize codes within each unit.
- Keep account identity stable.
- Present default and invalid account types.
- Retain referenced accounts.
- Protect default destinations.

The structured coverage map distinguishes specified examples from remaining findings. Proposed examples require executable proof before qualification.

## Interactions With Related Capabilities

- Released default frees its chart destination.
- A receiving account prevents chart removal.
- A tax destination prevents chart removal.

Related-capability and workflow references identify the seams each scenario exercises. The lifecycle coverage record retains transitions that still need individual proof.

## Binding Review

The pinned service and browser assertions support the registered bindings. Original test references remain beside each scenario so partial evidence and unresolved conformance remain reviewable.
