---
id: ATS-ACC-PRD-006
scope: CAP-ACC-PRD-006
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-006-01
    title: A bundle dependency blocks removal
    level: unit
    proves:
      - BR-CAP-ACC-PRD-006-01
      - INV-DOM-ACC-PRD-001-10
    preconditions: Bundle B includes product A.
    steps: Request removal of product A.
    expected: Deletion fails and A remains available.
    negative: true
    data_needs: Bundle B includes product A.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
        deleting a product another product bundles, 409, and keeps it
      - >-
        services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a product
        a bundle includes
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        deleting a product another product bundles
      - TST-ACC-PRD-040
      - TST-ACC-PRD-030
      - TST-ACC-PRD-031
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      deleting a product another product bundles, 409, and keeps it
    category: interaction
    binding_scope:
      - suite: TST-ACC-PRD-040
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
            deleting a product another product bundles, 409, and keeps it
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          deleting a product another product bundles, 409, and keeps it;
          services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
          product a bundle includes;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
          deleting a product another product bundles
      - suite: TST-ACC-PRD-030
        assertions:
          - >-
            services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
            product a bundle includes
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          deleting a product another product bundles, 409, and keeps it;
          services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
          product a bundle includes;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
          deleting a product another product bundles
      - suite: TST-ACC-PRD-031
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
            deleting a product another product bundles
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          deleting a product another product bundles, 409, and keeps it;
          services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
          product a bundle includes;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
          deleting a product another product bundles
    exercises:
      - CAP-ACC-PRD-006
      - CAP-ACC-PRD-011
  - id: ATS-ACC-PRD-006-02
    title: Invoice product use blocks removal
    level: browser
    proves:
      - BR-CAP-ACC-PRD-006-02
    preconditions: An invoice line names the product.
    steps: Attempt deletion.
    expected: An in-use refusal preserves the product.
    negative: true
    data_needs: An invoice line names the product.
    bound_to:
      - 'react-console:acceptance/accounting/playwright/journeys/products/ACT-ACC-0121.spec.ts#ACT-ACC-0121'
      - TST-ACC-PRD-011
    provenance: test
    source: 'react-console:acceptance/accounting/playwright/journeys/products/ACT-ACC-0121.spec.ts#ACT-ACC-0121'
    category: rule
    binding_scope:
      - suite: TST-ACC-PRD-011
        assertions:
          - 'react-console:acceptance/accounting/playwright/journeys/products/ACT-ACC-0121.spec.ts#ACT-ACC-0121'
        provenance: test
        source: 'react-console:acceptance/accounting/playwright/journeys/products/ACT-ACC-0121.spec.ts#ACT-ACC-0121'
  - id: ATS-ACC-PRD-006-03
    title: Other financial references need useful refusals
    level: api
    proves:
      - BR-CAP-ACC-PRD-006-02
    preconditions: One product is an invoice discount reference and another appears on an installment line.
    steps: Attempt to delete each product.
    expected: The proposed contract requires explained in-use refusals instead of server faults.
    negative: true
    data_needs: One product is an invoice discount reference and another appears on an installment line.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/transactions/db/invoice-lines.table.ts:invoice_lines_product_fk;
      modules/transactions/db/invoice-lines.table.ts:invoice_lines_discount_product_fk;
      modules/billing/db/installment-schedule-lines.table.ts:installment_schedule_lines_product_fk
    category: failure
    binding_scope: []
  - id: ATS-ACC-PRD-006-04
    title: Deletion removes owned configuration
    level: unit
    proves:
      - BR-CAP-ACC-PRD-006-03
    preconditions: 'A product carries pricing, components, features and accounting children.'
    steps: Delete the product.
    expected: Neither the product nor its owned configuration remains.
    negative: false
    data_needs: 'A product carries pricing, components, features and accounting children.'
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
        its prices, components, accounting setup and the setup’s collections with it
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
        the id it deleted
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes its
        accounting setup with it
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes its
        setup’s revenue splits with it
      - TST-ACC-PRD-040
      - TST-ACC-PRD-031
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
      its prices, components, accounting setup and the setup’s collections with it
    category: invariant
    binding_scope:
      - suite: TST-ACC-PRD-040
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
            its prices, components, accounting setup and the setup’s collections with it
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
            the id it deleted
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
          its prices, components, accounting setup and the setup’s collections with it;
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
          the id it deleted;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
          its accounting setup with it;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
          its setup’s revenue splits with it
      - suite: TST-ACC-PRD-031
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
            its accounting setup with it
          - >-
            services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
            its setup’s revenue splits with it
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
          its prices, components, accounting setup and the setup’s collections with it;
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
          the id it deleted;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
          its accounting setup with it;
          services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#takes
          its setup’s revenue splits with it
  - id: ATS-ACC-PRD-006-05
    title: Delete locks protect products
    level: unit
    proves:
      - BR-CAP-ACC-PRD-006-04
    preconditions: Products carry each supported lock.
    steps: Attempt to delete both.
    expected: Both deletions fail with lock explanations.
    negative: true
    data_needs: Products carry each supported lock.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
        a product locked against deletes
      - >-
        services-accounting:modules/products/tests/unit/rules/product-rules.spec.js#refuses a delete of a
        record under either lock, naming it
      - TST-ACC-PRD-040
      - TST-ACC-PRD-066
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product locked against deletes
    category: permission
    binding_scope:
      - suite: TST-ACC-PRD-040
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
            a product locked against deletes
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          a product locked against deletes;
          services-accounting:modules/products/tests/unit/rules/product-rules.spec.js#refuses a delete of a
          record under either lock, naming it
      - suite: TST-ACC-PRD-066
        assertions:
          - >-
            services-accounting:modules/products/tests/unit/rules/product-rules.spec.js#refuses a delete of a
            record under either lock, naming it
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          a product locked against deletes;
          services-accounting:modules/products/tests/unit/rules/product-rules.spec.js#refuses a delete of a
          record under either lock, naming it
  - id: ATS-ACC-PRD-006-06
    title: Setup protection extends to product removal
    level: unit
    proves:
      - BR-CAP-ACC-PRD-006-05
    preconditions: The product’s setup has a delete lock.
    steps: Attempt product deletion.
    expected: Both records remain after the refusal.
    negative: true
    data_needs: The product’s setup has a delete lock.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
        a product whose accounting setup is locked against deletes, leaving the product and its setup
        (DEF-ACT-0101)
      - TST-ACC-PRD-040
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product whose accounting setup is locked against deletes, leaving the product and its setup
      (DEF-ACT-0101)
    category: permission
    binding_scope:
      - suite: TST-ACC-PRD-040
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
            a product whose accounting setup is locked against deletes, leaving the product and its setup
            (DEF-ACT-0101)
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
          a product whose accounting setup is locked against deletes, leaving the product and its setup
          (DEF-ACT-0101)
  - id: ATS-ACC-PRD-006-07
    title: Cleanup failure leaves deletion committed
    level: unit
    proves:
      - BR-CAP-ACC-PRD-006-06
    preconditions: A product owns confirmation content.
    steps: Delete once with normal cleanup and once with Platform cleanup failure.
    expected: Normal cleanup removes content; failed cleanup is logged while deletion still stands.
    negative: false
    data_needs: A product owns confirmation content.
    bound_to:
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
        the delete standing when Platform cannot clear the template
      - >-
        services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#is
        cleared after the product is deleted
      - TST-ACC-PRD-039
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
      the delete standing when Platform cannot clear the template
    category: failure
    binding_scope:
      - suite: TST-ACC-PRD-039
        assertions:
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
            the delete standing when Platform cannot clear the template
          - >-
            services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#is
            cleared after the product is deleted
        provenance: test
        source: >-
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
          the delete standing when Platform cannot clear the template;
          services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#is
          cleared after the product is deleted
  - id: ATS-ACC-PRD-006-08
    title: Units remain while products depend on them
    level: api
    proves:
      - BR-CAP-ACC-PRD-006-07
    preconditions: A unit owns a product.
    steps: Request unit deletion.
    expected: The dependency preserves both records.
    negative: true
    data_needs: A unit owns a product.
    bound_to:
      - >-
        services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a business
        unit that still has products
      - TST-ACC-PRD-030
    provenance: test
    source: >-
      services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a business
      unit that still has products
    category: interaction
    binding_scope:
      - suite: TST-ACC-PRD-030
        assertions:
          - >-
            services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
            business unit that still has products
        provenance: test
        source: >-
          services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a
          business unit that still has products
    exercises:
      - CAP-ACC-PRD-006
  - id: ATS-ACC-PRD-006-09
    title: Deletion requires delete authority
    level: api
    proves:
      - BR-CAP-ACC-PRD-006-08
    preconditions: A reader can inspect the product.
    steps: Attempt product deletion.
    expected: The request is denied.
    negative: true
    data_needs: A reader can inspect the product.
    bound_to:
      - >-
        services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js#is refused deleting a
        product
      - TST-ACC-PRD-028
    provenance: test
    source: >-
      services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js#is refused deleting a
      product
    category: permission
    binding_scope:
      - suite: TST-ACC-PRD-028
        assertions:
          - >-
            services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js#is refused deleting a
            product
        provenance: test
        source: >-
          services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js#is refused deleting a
          product
  - id: ATS-ACC-PRD-006-10
    title: Removal works from each retained availability state
    category: transition
    level: api
    proves:
      - BR-CAP-ACC-PRD-006-03
      - BR-CAP-ACC-PRD-006-09
    preconditions: 'Active, inactive and retired products have no dependencies or locks.'
    steps: Delete each product and repeat each removal.
    expected: Every first removal clears the local aggregate; repeated removals return not found.
    negative: true
    data_needs: 'Active, inactive and retired products have no dependencies or locks.'
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
      its prices, components, accounting setup and the setup’s collections with it;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
      another tenant’s product as absent and leaves it
    binding_scope: []
  - id: ATS-ACC-PRD-006-11
    title: 'Setup protection, bundle references and template cleanup meet at removal'
    category: interaction
    level: api
    proves:
      - BR-CAP-ACC-PRD-006-01
      - BR-CAP-ACC-PRD-006-05
      - BR-CAP-ACC-PRD-006-06
      - BR-CAP-ACC-PRD-005-03
      - BR-CAP-ACC-PRD-011-03
      - BR-CAP-ACC-PRD-014-05
      - BR-CAP-ACC-PRD-015-09
    preconditions: A retired component has a protected setup and owned confirmation; another product includes it.
    steps: >-
      Reactivate it, request deletion, remove the bundle relationship, request deletion again, clear setup
      protection, and delete it.
    expected: >-
      Each remaining guard preserves the product; the final removal clears owned local data and attempts
      remote cleanup.
    negative: true
    data_needs: A retired component has a protected setup and owned confirmation; another product includes it.
    bound_to: []
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      deleting a product another product bundles, 409, and keeps it;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product whose accounting setup is locked against deletes, leaving the product and its setup
      (DEF-ACT-0101);
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
      the delete standing when Platform cannot clear the template;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#reactivates
      an inactive product;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#keeps
      a retired component the bundle already holds when a replacement resends it, and refuses a new retired
      one;
      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/product-accounting-setups.integration.spec.js#unlocks
      a setup locked against updates when the replacement states sys_locked null, then deletes it
    exercises:
      - CAP-ACC-PRD-006
      - CAP-ACC-PRD-005
      - CAP-ACC-PRD-011
      - CAP-ACC-PRD-014
      - CAP-ACC-PRD-015
    binding_scope: []
evidence:
  - 'react-console:acceptance/accounting/playwright/journeys/products/ACT-ACC-0121.spec.ts'
  - 'services-accounting:modules/billing/db/installment-schedule-lines.table.ts'
  - 'services-accounting:modules/products/services/persistence/product-refusals.ts'
  - 'services-accounting:modules/products/services/persistence/products.ts'
  - 'services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js'
  - 'services-accounting:modules/products/tests/e2e/products.e2e.spec.js'
  - 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - >-
    services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js
  - 'services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js'
  - 'services-accounting:modules/products/tests/unit/rules/product-rules.spec.js'
  - 'services-accounting:modules/transactions/db/invoice-lines.table.ts'
  - >-
    rhythm-v2-docs:specs/accounting/products/design/workflows/WF-ACC-PRD-003-delete-a-product-and-clear-its-confirmation-template.md
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-ACC-PRD-055'
  permission: covered
  edge: 'gap: FND-ACC-PRD-055'
  failure: covered
  boundary: 'gap: FND-ACC-PRD-055'
  concurrency: 'gap: FND-ACC-PRD-055'
  invariant: covered
  interaction: covered
coverage_notes:
  validation:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-055
  edge:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-055
  boundary:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-055
  concurrency:
    reason: No dedicated scenario isolates this category for the capability.
    provenance: unknown
    source: FND-ACC-PRD-055
  remaining_obligations:
    reason: >-
      Inactive and retired deletion, dependency-versus-delete races and unmapped financial dependency refusals
      need execution; cleanup tests double Platform. 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-055
  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-055
related_capabilities:
  - CAP-ACC-PRD-005
  - CAP-ACC-PRD-011
  - CAP-ACC-PRD-014
  - CAP-ACC-PRD-015
workflows:
  - WF-ACC-PRD-003
rule_coverage:
  - rule: BR-CAP-ACC-PRD-006-01
    scenarios:
      - ATS-ACC-PRD-006-01
      - ATS-ACC-PRD-006-11
  - rule: BR-CAP-ACC-PRD-006-02
    scenarios:
      - ATS-ACC-PRD-006-02
      - ATS-ACC-PRD-006-03
  - rule: BR-CAP-ACC-PRD-006-03
    scenarios:
      - ATS-ACC-PRD-006-04
      - ATS-ACC-PRD-006-10
  - rule: BR-CAP-ACC-PRD-006-04
    scenarios:
      - ATS-ACC-PRD-006-05
  - rule: BR-CAP-ACC-PRD-006-05
    scenarios:
      - ATS-ACC-PRD-006-06
      - ATS-ACC-PRD-006-11
  - rule: BR-CAP-ACC-PRD-006-06
    scenarios:
      - ATS-ACC-PRD-006-07
      - ATS-ACC-PRD-006-11
  - rule: BR-CAP-ACC-PRD-006-07
    scenarios:
      - ATS-ACC-PRD-006-08
  - rule: BR-CAP-ACC-PRD-006-08
    scenarios:
      - ATS-ACC-PRD-006-09
interaction_coverage:
  - scenario: ATS-ACC-PRD-006-01
    exercises:
      - CAP-ACC-PRD-006
      - CAP-ACC-PRD-011
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      deleting a product another product bundles, 409, and keeps it
  - scenario: ATS-ACC-PRD-006-08
    exercises:
      - CAP-ACC-PRD-006
    provenance: test
    source: >-
      services-accounting:modules/products/tests/e2e/products.e2e.spec.js#answers 409 to deleting a business
      unit that still has products
  - scenario: ATS-ACC-PRD-006-11
    exercises:
      - CAP-ACC-PRD-006
      - CAP-ACC-PRD-005
      - CAP-ACC-PRD-011
      - CAP-ACC-PRD-014
      - CAP-ACC-PRD-015
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      deleting a product another product bundles, 409, and keeps it;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product whose accounting setup is locked against deletes, leaving the product and its setup
      (DEF-ACT-0101);
      services-accounting:modules/products/tests/integration/services/persistence/products.features.integration.spec.js#leaves
      the delete standing when Platform cannot clear the template;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#reactivates
      an inactive product;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#keeps
      a retired component the bundle already holds when a replacement resends it, and refuses a new retired
      one;
      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/product-accounting-setups.integration.spec.js#unlocks
      a setup locked against updates when the replacement states sys_locked null, then deletes it
state_coverage:
  - model: STATE-ACC-PRD-001
    from: active
    to: inactive
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#answers
      the replaced record at version 2, the cleared fields left out and both collections replaced
  - model: STATE-ACC-PRD-001
    from: inactive
    to: active
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#reactivates
      an inactive product
  - model: STATE-ACC-PRD-001
    from: active
    to: retired
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#retires
      the product at version 2, changing nothing else
  - model: STATE-ACC-PRD-001
    from: inactive
    to: retired
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: 'services-accounting:modules/products/services/rules/product-rules.ts:retireProblem'
  - model: STATE-ACC-PRD-001
    from: retired
    to: active
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#reactivates
      the retired product at version 3
  - model: STATE-ACC-PRD-001
    from: active
    to: deleted
    scenarios:
      - ATS-ACC-PRD-006-04
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#takes
      its prices, components, accounting setup and the setup’s collections with it
  - model: STATE-ACC-PRD-001
    from: inactive
    to: deleted
    scenarios:
      - ATS-ACC-PRD-006-10
    finding: null
    provenance: proposed
    source: 'services-accounting:modules/products/services/persistence/products.ts:deleteProduct'
  - model: STATE-ACC-PRD-001
    from: retired
    to: deleted
    scenarios:
      - ATS-ACC-PRD-006-10
    finding: null
    provenance: proposed
    source: 'services-accounting:modules/products/services/persistence/products.ts:deleteProduct'
  - model: STATE-ACC-PRD-003
    from: not set up
    to: set up
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/product-accounting-setups.integration.spec.js#gives
      the product its accounting summary
  - model: STATE-ACC-PRD-003
    from: set up
    to: set up
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      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
  - model: STATE-ACC-PRD-003
    from: set up
    to: not set up
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: >-
      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
  - model: STATE-ACC-PRD-004
    from: 'off'
    to: product-owned
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    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: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    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: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    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: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    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: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    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: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: 'services-accounting:modules/products/services/persistence/products.ts:templateChangeOf'
  - model: STATE-ACC-PRD-004
    from: shared
    to: product-owned
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: 'services-accounting:modules/products/services/persistence/products.ts:templateChangeOf'
  - model: STATE-ACC-PRD-005
    from: handed over
    to: realised
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: FND-ACC-PRD-046
  - model: STATE-ACC-PRD-005
    from: handed over
    to: removed
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: 'services-accounting:modules/products/db/pricing-audience-handovers.table.ts:pricingAudienceHandovers'
  - model: STATE-ACC-PRD-005
    from: realised
    to: removed
    scenarios: []
    finding: FND-ACC-PRD-055
    provenance: unknown
    source: 'services-accounting:modules/products/db/pricing-audience-handovers.table.ts:pricingAudienceHandovers'
permission_coverage:
  - key: accounting.products.delete
    where_checked: api
    scope: tenant
    scenarios:
      - ATS-ACC-PRD-006-05
      - ATS-ACC-PRD-006-06
      - ATS-ACC-PRD-006-09
    finding: null
    provenance: proposed
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product locked against deletes;
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      a product whose accounting setup is locked against deletes, leaving the product and its setup
      (DEF-ACT-0101); services-accounting:modules/products/tests/e2e/products-security.e2e.spec.js#is refused
      deleting a product
invariant_coverage:
  - invariant: INV-DOM-ACC-PRD-001-10
    scenarios:
      - ATS-ACC-PRD-006-01
    finding: null
    provenance: test
    source: >-
      services-accounting:modules/products/tests/integration/services/persistence/products.integration.spec.js#refuses
      deleting a product another product bundles, 409, and keeps it
---

# Delete a product after its dependencies are removed: 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. Inactive and retired deletion, dependency-versus-delete races and unmapped financial dependency refusals need execution; cleanup tests double Platform. Workflow edges not named by a scenario remain in this finding rather than gaining a binding from shared workflow membership.

## Interactions With Related Capabilities

Setup protection, bundle references and template cleanup meet at removal. A retired component has a protected setup and owned confirmation; another product includes it. Reactivate it, request deletion, remove the bundle relationship, request deletion again, clear setup protection, and delete it. Each remaining guard preserves the product; the final removal clears owned local data and attempts remote cleanup.
