---
id: ATS-ACC-PRD-014
scope: CAP-ACC-PRD-014
product_area: accounting
module: products
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-ACC-PRD-014-01
    title: Shared templates must fit confirmation use
    level: unit
    proves:
      - BR-CAP-ACC-PRD-014-02
    preconditions: 'Template fixtures span owners, purposes and workspaces.'
    steps: 'Select missing, wrong-purpose, foreign or owned templates as shared, then select an eligible template.'
    expected: Invalid choices fail and the eligible shared template succeeds.
    negative: true
    data_needs: 'Template fixtures span owners, purposes and workspaces.'
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        a product’s OWN template named as a shared one
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        a template id Platform does not have
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        a template of another purpose
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        another tenant’s template
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#names
        a shared template of the purpose
      - TST-ACC-PRD-039
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
      a product’s OWN template named as a shared one
    category: validation
    binding_scope:
      - suite: TST-ACC-PRD-039
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            a product’s OWN template named as a shared one
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            a template id Platform does not have
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            a template of another purpose
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            another tenant’s template
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#names
            a shared template of the purpose
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          a product’s OWN template named as a shared one;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          a template id Platform does not have;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          a template of another purpose;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          another tenant’s template;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#names
          a shared template of the purpose
  - id: ATS-ACC-PRD-014-02
    title: Platform failure rolls back product writes
    level: unit
    proves:
      - BR-CAP-ACC-PRD-014-03
      - BR-CAP-ACC-PRD-014-04
    preconditions: A product can own confirmation content.
    steps: 'Submit refused content, missing reply-to, a Platform failure and two valid template saves.'
    expected: Failed calls preserve product data and valid saves retain one template across versions.
    negative: true
    data_needs: A product can own confirmation content.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        content Platform refuses, naming the property, and writes nothing
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#rolls
        the product back when Platform cannot save the template
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
        a first template without a reply-to address, as Platform does
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#saved
        its own template in Platform, owned by the product, once
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
        one template, as its new version
      - TST-ACC-PRD-039
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
      content Platform refuses, naming the property, and writes nothing
    category: failure
    binding_scope:
      - suite: TST-ACC-PRD-039
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            content Platform refuses, naming the property, and writes nothing
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#rolls
            the product back when Platform cannot save the template
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
            a first template without a reply-to address, as Platform does
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#saved
            its own template in Platform, owned by the product, once
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
            one template, as its new version
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          content Platform refuses, naming the property, and writes nothing;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#rolls
          the product back when Platform cannot save the template;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#refuses
          a first template without a reply-to address, as Platform does;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#saved
          its own template in Platform, owned by the product, once;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
          one template, as its new version
  - id: ATS-ACC-PRD-014-03
    title: Switching confirmation ownership clears content
    level: unit
    proves:
      - BR-CAP-ACC-PRD-014-05
    preconditions: A product owns a confirmation template.
    steps: Switch to shared content and disable another product’s owned content.
    expected: Both previously owned templates are cleared.
    negative: false
    data_needs: A product owns a confirmation template.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#clears
        the product’s own template when it switches to a shared one
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#archives
        the product’s own template in Platform
      - TST-ACC-PRD-039
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#clears
      the product’s own template when it switches to a shared one
    category: transition
    binding_scope:
      - suite: TST-ACC-PRD-039
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#clears
            the product’s own template when it switches to a shared one
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#archives
            the product’s own template in Platform
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#clears
          the product’s own template when it switches to a shared one;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#archives
          the product’s own template in Platform
  - id: ATS-ACC-PRD-014-04
    title: Omission avoids a template call
    level: unit
    proves:
      - BR-CAP-ACC-PRD-014-06
    preconditions: A product has owned confirmation content.
    steps: Replace ordinary product details without confirmation configuration.
    expected: The template remains unchanged and Platform receives no request.
    negative: false
    data_needs: A product has owned confirmation content.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
        Platform for nothing
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
        the confirmation e-mail and its template
      - TST-ACC-PRD-039
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
      Platform for nothing
    category: rule
    binding_scope:
      - suite: TST-ACC-PRD-039
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
            Platform for nothing
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
            the confirmation e-mail and its template
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
          Platform for nothing;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
          the confirmation e-mail and its template
  - id: ATS-ACC-PRD-014-05
    title: Shared confirmation switches to owned content and off
    category: transition
    level: api
    proves:
      - BR-CAP-ACC-PRD-014-01
      - BR-CAP-ACC-PRD-014-03
      - BR-CAP-ACC-PRD-014-05
    preconditions: A product selects a valid shared confirmation template and the communications port records calls.
    steps: 'Replace with valid owned content, then return to shared and disable the selection.'
    expected: >-
      The selection follows each saved state; owned content is saved and subsequently cleared, and shared
      content is never cleared.
    negative: true
    data_needs: A product selects a valid shared confirmation template and the communications port records calls.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/products/services/persistence/products.ts:templateChangeOf;
      rhythm-v2-docs:specs/accounting/products/design/state-models/STATE-ACC-PRD-004-confirmation-message-setting.md#transitions
    binding_scope: []
  - id: ATS-ACC-PRD-014-06
    title: Remote success followed by local failure leaves a recovery gap
    category: edge
    level: api
    proves:
      - BR-CAP-ACC-PRD-014-04
      - INV-DOM-ACC-PRD-001-07
    preconditions: An owned-template operation succeeds before a forced response-read or local commit failure.
    steps: >-
      Fail local completion after the remote write, then inspect local configuration and remote content
      independently.
    expected: >-
      The local replacement rolls back while remote content may have changed; the observation exposes the
      documented compensation gap.
    negative: true
    data_needs: An owned-template operation succeeds before a forced response-read or local commit failure.
    bound_to: []
    provenance: proposed
    source: >-
      rhythm-v2-docs:specs/accounting/products/design/workflows/WF-ACC-PRD-001-create-or-replace-a-product-with-its-owned-settings.md#hops;
      services-accounting:modules/products/services/persistence/products.ts:updateProduct
    binding_scope: []
  - id: ATS-ACC-PRD-014-07
    title: Owned confirmations survive omission and are cleared after deletion
    category: interaction
    level: api
    proves:
      - BR-CAP-ACC-PRD-014-06
      - BR-CAP-ACC-PRD-004-02
      - BR-CAP-ACC-PRD-006-06
    preconditions: A product selects owned confirmation content.
    steps: >-
      Replace ordinary details without confirmation configuration, then delete the product with cleanup
      succeeding and failing in separate runs.
    expected: Omission sends no template mutation; deletion commits independently of cleanup success.
    negative: true
    data_needs: A product selects owned confirmation content.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
      Platform for nothing;
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
      the confirmation e-mail and its template;
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
      the delete standing when Platform cannot clear the template
    exercises:
      - CAP-ACC-PRD-014
      - CAP-ACC-PRD-004
      - CAP-ACC-PRD-006
    binding_scope: []
evidence:
  - 'services-accounting:modules/products/services/confirmation-emails/confirmation-email-templates.ts'
  - 'services-accounting:modules/products/services/persistence/communication-templates.ts'
  - 'services-accounting:modules/products/tests/e2e/product-features.e2e.spec.js'
  - >-
    services-accounting:modules/products/tests/integration/services/persistence/communication-templates.queries.integration.spec.js
  - >-
    services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js
  - >-
    rhythm-v2-docs:specs/accounting/products/design/workflows/WF-ACC-PRD-001-create-or-replace-a-product-with-its-owned-settings.md
coverage:
  rule: covered
  transition: covered
  validation: covered
  permission: 'gap: FND-ACC-PRD-063'
  edge: covered
  failure: covered
  boundary: 'gap: FND-ACC-PRD-063'
  concurrency: 'gap: FND-ACC-PRD-063'
  invariant: 'gap: FND-ACC-PRD-063'
  interaction: covered
coverage_notes:
  permission:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-063
  boundary:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-063
  concurrency:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-063
  invariant:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-063
  remaining_obligations:
    reason: >-
      All shared-to-owned and shared-to-off transitions, local failure after remote success, permission
      refusal and concurrency across the remote call need execution with real communications. Workflow edges
      not named by a scenario remain in this finding rather than gaining a binding from shared workflow
      membership.
    provenance: unknown
    source: FND-ACC-PRD-063
  meaning:
    reason: >-
      Covered means a specification scenario exists in this category. Executable coverage and run results
      remain independent.
    provenance: documented
    source: 'rhythm-v2-docs:specs/CONVENTIONS.md#9.10 Capability Test Specification (`ATS`, under `design/tests/`)'
coverage_findings:
  - FND-ACC-PRD-063
related_capabilities:
  - CAP-ACC-PRD-004
  - CAP-ACC-PRD-006
workflows:
  - WF-ACC-PRD-001
rule_coverage:
  - rule: BR-CAP-ACC-PRD-014-02
    scenarios:
      - ATS-ACC-PRD-014-01
  - rule: BR-CAP-ACC-PRD-014-03
    scenarios:
      - ATS-ACC-PRD-014-02
      - ATS-ACC-PRD-014-05
  - rule: BR-CAP-ACC-PRD-014-04
    scenarios:
      - ATS-ACC-PRD-014-02
      - ATS-ACC-PRD-014-06
  - rule: BR-CAP-ACC-PRD-014-05
    scenarios:
      - ATS-ACC-PRD-014-03
      - ATS-ACC-PRD-014-05
  - rule: BR-CAP-ACC-PRD-014-06
    scenarios:
      - ATS-ACC-PRD-014-04
      - ATS-ACC-PRD-014-07
interaction_coverage:
  - scenario: ATS-ACC-PRD-014-07
    exercises:
      - CAP-ACC-PRD-014
      - CAP-ACC-PRD-004
      - CAP-ACC-PRD-006
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#asks
      Platform for nothing;
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
      the confirmation e-mail and its template;
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
      the delete standing when Platform cannot clear the template
state_coverage:
  - model: STATE-ACC-PRD-004
    from: 'off'
    to: product-owned
    scenarios:
      - ATS-ACC-PRD-014-02
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#saved
      its own template in Platform, owned by the product, once
  - model: STATE-ACC-PRD-004
    from: product-owned
    to: product-owned
    scenarios:
      - ATS-ACC-PRD-014-02
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#keeps
      one template, as its new version
  - model: STATE-ACC-PRD-004
    from: product-owned
    to: shared
    scenarios:
      - ATS-ACC-PRD-014-03
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#clears
      the product’s own template when it switches to a shared one
  - model: STATE-ACC-PRD-004
    from: product-owned
    to: 'off'
    scenarios:
      - ATS-ACC-PRD-014-03
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#archives
      the product’s own template in Platform
  - model: STATE-ACC-PRD-004
    from: 'off'
    to: shared
    scenarios:
      - ATS-ACC-PRD-014-01
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#names
      a shared template of the purpose
  - model: STATE-ACC-PRD-004
    from: shared
    to: 'off'
    scenarios:
      - ATS-ACC-PRD-014-05
    finding: null
    provenance: proposed
    source: 'services-accounting:modules/products/services/persistence/products.ts:templateChangeOf'
  - model: STATE-ACC-PRD-004
    from: shared
    to: product-owned
    scenarios:
      - ATS-ACC-PRD-014-05
    finding: null
    provenance: proposed
    source: 'services-accounting:modules/products/services/persistence/products.ts:templateChangeOf'
permission_coverage:
  - key: accounting.products.update
    where_checked: api
    scope: tenant
    scenarios: []
    finding: FND-ACC-PRD-063
    provenance: unknown
    source: >-
      rhythm-v2-docs:specs/accounting/products/planning/capabilities/CAP-ACC-PRD-014-send-the-buyer-a-confirmation-e-mail.md#permissions
---

# Configure a purchase confirmation message: Capability Test Specification

## Coverage

The frontmatter lists a proof scenario or finding for every required rule and records each applicable category. Scenario coverage describes what to check; bindings identify the assertions that already exist, and execution results remain unverified. All shared-to-owned and shared-to-off transitions, local failure after remote success, permission refusal and concurrency across the remote call need execution with real communications. Workflow edges not named by a scenario remain in this finding rather than gaining a binding from shared workflow membership.

## Interactions With Related Capabilities

Owned confirmations survive omission and are cleared after deletion. A product selects owned confirmation content. Replace ordinary details without confirmation configuration, then delete the product with cleanup succeeding and failing in separate runs. Omission sends no template mutation; deletion commits independently of cleanup success.
