---
id: TST-ACC-PRD-031
title: Product storage constraints
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/db/products.table.integration.spec.js
implements:
  - ATS-ACC-PRD-001-01
  - ATS-ACC-PRD-002-01
  - ATS-ACC-PRD-002-03
  - ATS-ACC-PRD-002-04
  - ATS-ACC-PRD-002-05
  - ATS-ACC-PRD-002-06
  - ATS-ACC-PRD-002-07
  - ATS-ACC-PRD-002-08
  - ATS-ACC-PRD-003-02
  - ATS-ACC-PRD-006-01
  - ATS-ACC-PRD-006-04
  - ATS-ACC-PRD-008-03
  - ATS-ACC-PRD-015-11
  - ATS-ACC-PRD-015-13
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/db/products.table.integration.spec.js'
assertion_bindings:
  - scenario: ATS-ACC-PRD-001-01
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        the application role an INSERT
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        the application role an UPDATE
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        the application role a DELETE
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-01
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        an id longer than 63 characters
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-03
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        second product under the same id, of another type: the id is unique across every type
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-04
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#turns a
        blank name into null and refuses it
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-05
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        pricing model other than its type’s
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-06
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        change of business_unit_id (RHF01)
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        change of product_type_id (RHF01)
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        change of id (RHF01)
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-07
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        sale window that ends the instant it starts
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-002-08
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        negative cancellation fee
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        negative restocking fee
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-003-02
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        bundle of tenant B including a product only tenant A has
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-006-01
    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/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-006-04
    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/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-008-03
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        percent_of_standard row without its percent, and a set row with one
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-015-11
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        deleting a GL account a setup names as its revenue account
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        deleting a department a setup names
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses
        deleting a merchant account a setup names
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
  - scenario: ATS-ACC-PRD-015-13
    assertions:
      - >-
        services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js#refuses a
        change of product_id (RHF01)
    provenance: test
    source: 'services-accounting:modules/products/tests/integration/db/products.table.integration.spec.js'
coverage_note: Scenario references name existing assertion evidence; broader unexecuted variants remain findings.
---

# Product storage constraints

## Verification Boundary

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

## What This Suite Proves

Database constraints protect product identity, pricing, owned collections and setup ownership; application-role register mutations are refused.

## 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.
