Product.DetailMode is a presentation preference, not page-publication authority. Its stored enum values remain Auto = 0, ProductDetailPage = 1, QuickView = 2, and Inline = 3.
Product.IsDetailsPageEnabled is nullable: null inherits WebshopProductDetailsPageEnabled (default true), true permits a page, and false disables it. Deletion, templates, child/fee product types, publication/activity and campaign eligibility still constrain availability. Product access is checked by the existing catalog and page entrypoints; the flag grants no purchasing or account authority.
HasDetailsPageEnabled enforces page eligibility independently of DetailMode. A popup or inline preference can coexist with a page. A page preference with no eligible/resolvable page falls back to quick view without enabling the page.
The owning product schema adds nullable is_details_page_enabled in product-1.82.7.sql. The separate DML migration product-1.82.8.sql sets existing explicit QuickView/Inline products to false when the new value is null, preserving their former page restriction. Other existing products and newly created products inherit the shop default. Run the normal complete migration plan before serving the changed module.
The common OnDemand/Repeat catalog product includes presentation:
detail_mode: the explicit product preference, including auto.default_detail_mode: the shop preference, including auto.automatic_detail_mode: quick_view, product_detail_page, or inline, derived from product content/configuration and actual page availability.detail_page_url: the Shop router's eligible product page URL, or null; consumers must not invent a route from the product ID.has_external_choices: additional configuration outside the variant-group projection, such as subscription choices. This prevents treating an incomplete configuration surface as a simple direct addition.Wire modes use product_detail_page, not detail_page. PageApp defaults fit between an explicit product preference and the shop preference; auto continues that inheritance chain. The SDK resolves view/add actions independently and accepts only same-origin HTTP(S) detail navigation relative to the supplied application base URL.
| Effective preference | Title/image | Plus without a customer decision | Plus with a customer decision |
|---|---|---|---|
| Auto | Automatic detail surface | Direct addition | Configure in the automatic surface |
| QuickView | Quick view | Quick view | Quick view |
| ProductDetailPage | Eligible page, otherwise quick view | Direct addition | Eligible page, otherwise quick view |
| Inline | No normal detail action | Direct addition | Quick-view configuration exception |
The SDK evaluates visibility/default selections with the existing variant evaluator. Meaningful optional choices remain discoverable. Hidden-only groups and a valid single forced default with no editable quantity/input need not interrupt addition; editable alternatives, quantities, text/image input, invalid defaults and external choices require configuration. Minimum/default product quantity alone is not a customer configuration decision. Direct additions retain evaluated fixed defaults. Server cart/checkout validation remains authoritative, including unsupported source-backed variants and authentication requirements.
Legacy Shop retains its existing configuration-dialog exception for Inline products. Its automatic server resolver and JavaScript fallback do not use minimum product quantity alone as a popup trigger. The richer SDK view/add action table applies to the ordering PageApp surfaces, not every legacy storefront control.
evaluateOrderingCatalogVariantSelections supplies visibility/default-selection validation without product money; the financial variant evaluator reuses the same selection rules. Unpriced source products remain viewable without a fabricated dialog total. Source enrichment preserves the independent presentation projection and retains its own ordering/price restrictions.
ProductPresentationTest covers nullable inheritance, restrictions, precedence and the shared projection.CheckoutPaymentHandoffMigrationTest.ProductPageAvailabilityUpgradeUsesTheExistingProductSchema checks normal migration discovery/order and DDL/DML separation.node platform/piranya-platform-shop/Piranya.Platform.Server.Modules.Shop.Test/Content/ProductPresentationTest.cjs exercises the actual legacy add method with controlled module loading.piranya-js, the SDK presentation tests and OnDemand catalog add-mode controls exercise the shared policy; normal package-export checks must include product-presentation.js.A scratch module build or controlled synthetic browser does not verify a running installation. Full selected-solution build, normal migrations and the actual site's product-page templates remain separate integration checks.