---
id: STATE-COM-ORD-002
title: Checkout item preparation
object: DOM-COM-ORD-001
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
states:
  - name: unvalidated
    meaning: The current selection has not yet received an application assessment.
  - name: advised
    meaning: Advice found no participant outcome blocking the selection.
  - name: problems
    meaning: 'Assessment recorded a blocker from the seller, pricing or purchase checks.'
  - name: prepared
    meaning: An authoritative hold preparation has been recorded.
  - name: stale
    meaning: The recorded hold lapsed and the selection needs fresh assessment.
  - name: frozen
    meaning: Placement captured the application's attestation and fixed the item.
transitions:
  - from: unvalidated
    to: advised
    trigger: The assessment obtains participant advice.
    guard: A timely response reports a placeable outcome.
    side_effects:
      - 'persist the seller-normalized details, delivery plan and price adjustments'
      - persist calculation and assessment history together
    who: Staff or portal buyer through preview
    provenance: observed
    source: 'services-commerce:modules/checkout/services/checkout/checkout-assessment.ts'
  - from: unvalidated
    to: problems
    trigger: 'Assessment records seller, price or eligibility blockers.'
    guard: Blockers are returned as part of preview rather than requiring a failed HTTP request.
    side_effects:
      - retain blockers in the selection assessment
    who: Staff or portal buyer through preview
    provenance: observed
    source: 'services-commerce:modules/checkout/services/checkout/checkout-assessment.ts'
  - from: advised
    to: unvalidated
    trigger: Selection editing or preprocessing changes the item.
    guard: Editing requires an open cart.
    side_effects:
      - increment cart version and append the edit event
    who: 'Staff, portal buyer or the store extension'
    provenance: observed
    source: >-
      services-commerce:modules/checkout/services/checkout/checkout-workflow.ts:changeItem;
      modules/checkout/services/checkout/checkout-preprocessing.ts
  - from: unvalidated
    to: prepared
    trigger: The seller answers an early reservation request.
    guard: This type supports holds and the seller grants capacity.
    side_effects:
      - associate the held reservation with its selection
      - append reservation-acquisition history
    who: Staff or portal buyer through the hold operation
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#acquires the hold: 200 with
      the reservation held, the item prepared with it, the participant’s row held, hold_acquired on the trail
  - from: prepared
    to: stale
    trigger: Reservation expiry discovers the item's elapsed hold.
    guard: The hold is still held and has no placed-line attachment.
    side_effects:
      - record elapsed reservation status
      - append reservation-expiry history
    who: System (hold sweep)
    provenance: test
    source: >-
      services-commerce:modules/checkout/tests/e2e/holds-and-claims.e2e.spec.js#expires the ledger’s row,
      marks the item stale with hold_expired on the trail, and counts it
  - from: advised
    to: frozen
    trigger: Placement captures newly prepared purchase details.
    guard: The placement commit succeeds.
    side_effects:
      - 'capture attestation, delivery plan and resources in the protected purchased-line snapshot'
    who: System within placement
    provenance: observed
    source: 'services-commerce:modules/orders/services/placement/place-order.ts:placeOrder'
invalid:
  - from: frozen
    to: unvalidated
    why: Placement ends cart editing.
  - from: problems
    to: frozen
    why: Current blockers are assessed afresh during authoritative placement preparation.
concurrency: >-
  Cart writes use locks and version checks. The reservation sweep records lapsed holds once per minute, while
  placement always obtains authoritative preparation.
invariants:
  - INV-DOM-COM-ORD-001-05
  - INV-DOM-COM-ORD-001-08
evidence:
  - >-
    services-commerce at c8b66a98: modules/checkout/db/checkout-items.table.ts (VALIDATION_STATES);
    services/checkout/checkout-assessment.ts, checkout-workflow.ts, checkout-preprocessing.ts;
    modules/orders/services/reservations/reservation-sweeper.ts.
---

# Checkout item preparation

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> unvalidated: item added or changed
  unvalidated --> advised: preview, nothing blocking
  unvalidated --> problems: preview, something blocking
  problems --> unvalidated: item changed
  advised --> unvalidated: item changed
  unvalidated --> prepared: early hold granted
  prepared --> stale: hold expired
  stale --> unvalidated: item changed or held again
  advised --> frozen: placed
  prepared --> frozen: placed
  frozen --> [*]
```

## Transitions Explained

Selections carry assessment results rather than an independently enforced state machine. Changes reset validation, preview records advice or blockers, holds record preparation and expiry marks stale. Placement reassesses the selection and captures fresh attestation as frozen.

## What Cannot Happen

A placed cart cannot be edited. Stored problems do not create a permanent refusal: placement's fresh preparation determines whether the item can proceed.

## Concurrency and Timing

Cart writes use locks and version checks. The reservation sweep records lapsed holds once per minute, while placement always obtains authoritative preparation.
