---
id: STATE-COM-CAT-001
title: Checkout policy activation and default designation
object: DOM-COM-CAT-001
product_area: commerce
module: catalog
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
  - name: active
    meaning: New selling contexts may select this policy.
  - name: active default
    meaning: Workspace or application defaults currently select this active policy.
  - name: inactive
    meaning: New checkout use is refused; retained order snapshots stay independent.
  - name: deleted
    meaning: The policy record has been removed.
transitions:
  - from: active
    to: active default
    trigger: 'Creation establishes the first default, or staff select this policy in the defaults document.'
    guard: The selected policy must be active in this workspace.
    side_effects:
      - The transaction transfers the previous workspace designation.
    who: Policy administrator (update permission for the defaults document)
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#makes
      a second profile no default, and one stating is_tenant_default the default in place of the first, in one
      transaction
  - from: active default
    to: active
    trigger: Staff transfer the workspace designation or remove the remaining application selections.
    guard: Workspace default removal requires another active policy to receive the designation.
    side_effects:
      - The saved defaults map drops omitted applications.
    who: Policy administrator
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#removes an application
      default left out of the document, the tenant default kept when null
  - from: active
    to: inactive
    trigger: A replacement disables policy activity.
    guard: 'The read version must match, full protection must be absent and no default may retain the policy.'
    side_effects:
      - New context selection excludes the disabled policy.
    who: Policy administrator
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/integration/services/persistence/ordering-profiles.integration.spec.js#refuses
      making an application default inactive, 409 profile_is_default naming the application, and deactivates
      it once no default names it (D31)
  - from: inactive
    to: active
    trigger: A replacement enables policy activity.
    guard: The policy version must match and update protection must allow the write.
    side_effects: []
    who: Policy administrator
    provenance: observed
    source: 'services-commerce:modules/configuration/services/persistence/ordering-profiles.ts'
  - from: active
    to: deleted
    trigger: An authorized delete requests removal.
    guard: 'Protection, default selection and retained store or sale references must all permit removal.'
    side_effects: []
    who: Policy administrator (delete permission)
    provenance: test
    source: >-
      services-commerce:modules/configuration/tests/e2e/ordering-profiles.e2e.spec.js#answers 409 naming the
      store while a store sells under the profile, then 200 once the store is gone
  - from: inactive
    to: deleted
    trigger: An authorized delete requests removal.
    guard: No protection or retained reference may block removal.
    side_effects: []
    who: Policy administrator (delete permission)
    provenance: observed
    source: 'services-commerce:modules/configuration/services/persistence/ordering-profiles.ts'
invalid:
  - from: active default
    to: inactive
    why: Defaults must remain usable; refusal identifies the retaining default selections.
  - from: active default
    to: deleted
    why: A default reference blocks policy removal.
  - from: inactive
    to: active default
    why: A default selection cannot designate an inactive policy.
concurrency: >-
  Row locking and read-version comparison reject competing stale edits. Default transfer clears and assigns
  the flag in one transaction; a partial unique index prevents two workspace defaults.
invariants:
  - INV-DOM-COM-CAT-001-02
  - INV-DOM-COM-CAT-001-03
  - INV-DOM-COM-CAT-001-04
  - INV-DOM-COM-CAT-001-05
evidence:
  - >-
    services-commerce at c8b66a98: modules/configuration/services/persistence/ordering-profiles.ts
    (setTenantDefaultOrderingProfile, profileIsDefaultRefusal, lockProfile); db/ordering-profiles.table.ts
    (ordering_profiles_tenant_default_uidx); docs/decisions/ordering-profiles.md.
---

# Checkout policy activation and default designation

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> active_default: first policy of the workspace
  [*] --> active: later policies
  active --> active_default: made workspace or application default
  active_default --> active: default moved elsewhere
  active --> inactive: switched off
  inactive --> active: switched on
  active --> deleted: nothing names it
  inactive --> deleted: nothing names it
  deleted --> [*]
```

## Transitions Explained

Active: New selling contexts may select this policy. Active default: Workspace or application defaults currently select this active policy. Inactive: New checkout use is refused; retained order snapshots stay independent. Deleted: The policy record has been removed.

## What Cannot Happen

Defaults must remain usable; refusal identifies the retaining default selections. A default reference blocks policy removal. A default selection cannot designate an inactive policy.

## Concurrency and Timing

Row locking and read-version comparison reject competing stale edits. Default transfer clears and assigns the flag in one transaction; a partial unique index prevents two workspace defaults.
