---
id: WF-COM-CAT-007
title: Build a storefront page or product page
trigger: >-
  Shopper pages assemble admitted product presentations, price display and availability. Staff diagnostics
  explain why candidate products do not appear.
product_area: commerce
module: catalog
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: observed
inference: []
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
implements:
  - CAP-COM-CAT-008
  - CAP-COM-CAT-013
crosses:
  - SVC-COM-CAT-catalog
  - SVC-COM-CAT-pricing
  - SVC-COM-CAT-merchandise
idempotency: 'Page reads do not persist results. Repeats reflect current catalog, price and availability inputs.'
concurrency: >-
  Input reads are independent short transactions, so a concurrent configuration or stock change may appear
  only on a later page request.
hops:
  - 'n': 1
    actor_or_service: Catalog service
    action: 'Load the store and distinguish missing, closed and diagnostic staff contexts.'
    anchor: 'services-commerce:modules/catalog/services/storefront/storefront-listings.ts:readStorefrontPage'
    seam: sync
    on_failure: Return not found for an unknown store.
    left_inconsistent: No saved record changes.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/integration/services/storefront/storefront-listings.integration.spec.js#opens
      an unlisted product by its page, and is answered 404 for a draft and for a product another store does
      not sell
  - 'n': 2
    actor_or_service: Catalog service
    action: >-
      Load listing and Accounting product candidates, applying visibility, assortment, category, search and
      sort restrictions.
    anchor: 'services-commerce:modules/catalog/services/persistence/storefront-listings.ts'
    seam: sync
    on_failure: Fail the page request if candidate loading fails.
    left_inconsistent: No saved record changes.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/integration/services/storefront/storefront-listings.queries.integration.spec.js#answers
      the published listings that sell now, featured first then in sort order, under the rule `all`
  - 'n': 3
    actor_or_service: Catalog service to Platform eligibility
    action: >-
      Batch member purchase-binding checks at display consistency; do not evaluate anonymous subjects and mark
      possible changes after sign-in.
    anchor: 'services-commerce:modules/catalog/services/storefront/purchase-bindings.ts'
    seam: sync
    on_failure: 'Retain indeterminate candidates with reasons, and remove candidates explicitly judged ineligible.'
    left_inconsistent: No saved record changes.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/integration/services/storefront/storefront-listings.integration.spec.js#is
      not evaluated for eligibility: a bound product is shown, flagged that signing in may change its
      availability
  - 'n': 4
    actor_or_service: Catalog service to pricing quote
    action: 'Quote the page in the shopper’s currency, including public audience display amounts for visitors.'
    anchor: 'services-commerce:modules/pricing/services/quotes/price-quotes.ts:priceQuote'
    seam: sync
    on_failure: >-
      Preserve the page without amounts on quote failure; remove not-sold products and flag prohibited
      currencies.
    left_inconsistent: The page can lack reliable price display.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/e2e/storefront.e2e.spec.js#shows the audiences marked for public
      display beside the Standard price (D10): the Members price 2000, with its audience
  - 'n': 5
    actor_or_service: Catalog service
    action: >-
      Translate participant advice into availability and optional remaining counts, returning no more than
      sixty page entries.
    anchor: 'services-commerce:modules/catalog/services/storefront/storefront-listings.ts:availabilityOf'
    seam: sync
    on_failure: Display unknown availability when advice cannot establish it.
    left_inconsistent: No saved record changes.
    observer: The requesting person or service receives the result and any returned refusal.
    provenance: test
    source: >-
      services-commerce:modules/catalog/tests/unit/storefront/storefront-availability.spec.js#shows the units
      on hand when the listing shows its remaining count
branches:
  - Public requests use the workspace addressed by the route and ignore handed-in signed context.
  - Staff responses include the reason for each removed listing.
waits: []
evidence:
  - >-
    services-commerce at c8b66a98: modules/catalog/services/storefront/storefront-listings.ts,
    storefront-visibility.ts, purchase-bindings.ts; services/persistence/storefront-listings.ts;
    aws/api/storefront.routes.ts; docs/milestones/COMM-M1-set-up-what-you-sell.md (D8, D10).
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-CRY-001, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-LOG-004, TC-LOG-005, TC-AVL-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PRV-001, TC-PRV-002]
---

# Build a storefront page or product page

## What It Does

Shopper pages assemble admitted product presentations, price display and availability. Staff diagnostics explain why candidate products do not appear.

## The Flow

```mermaid
sequenceDiagram
  participant B as Shopper or member
  participant K as Catalog service
  participant E as Platform eligibility
  participant P as Pricing quote
  B->>K: list or product page
  K->>K: store, listings, assortment, product rules
  opt signed-in member with bound products
    K->>E: batch evaluation (display)
    E-->>K: eligible, ineligible, indeterminate
  end
  K->>P: batched quote in the shopper's currency
  P-->>K: prices, refusals, availability advice
  K-->>B: page (at most sixty)
```

## When Something Fails

Return not found for an unknown store. No saved record changes. Fail the page request if candidate loading fails. No saved record changes. Retain indeterminate candidates with reasons, and remove candidates explicitly judged ineligible. No saved record changes. Preserve the page without amounts on quote failure; remove not-sold products and flag prohibited currencies. The page can lack reliable price display. Display unknown availability when advice cannot establish it. No saved record changes.

## Open Design Questions

The implemented recovery and concurrency behaviour above defines the current boundary. Any change to transaction scope or product authority requires a recorded decision.
