PhoenixKitEcommerce. Catalogue. ShopStatusColumn
(PhoenixKitEcommerce v0.5.11)
Copy Markdown
View Source
The catalogue admin's "Shop status" extension column — surfaces
data["ecommerce"]["shop_status"] next to the catalogue's OWN
status on the item/category tables.
The owner's complaint: the catalogue's status and the shop's
shop_status are two independent signals — an item can be a live
catalogue entry that is deliberately not for sale — and only the
catalogue's own status showed on screen, so an item could be
invisible on the storefront (or, worse, reachable when it shouldn't
be — see below) for a reason the admin screen never surfaced. This
column does NOT synchronize the two (that would destroy the
distinction the owner wants to keep); it shows both, side by side,
and never warns — see "No warnings" below for why there is no
combination left that is an actual hazard.
Why item and category are two different rules (item_columns/0
vs. category_columns/0 return DIFFERENT column definitions)
Items and categories share neither their shop_status value domain
nor their storefront-visibility rule:
- Item
shop_status—draft/active/archived(PhoenixKitEcommerce.Catalogue.ItemCommerce). Listing visibility (ProductSource.Catalogue.Query.active_visibility/1) requiresitem.status == "active"ANDCOALESCE(shop_status, 'active') == "active"— an absentshop_statusdefaults to whateveritem.statusalready says (View.product_status/2's exact fallback), so it never disagrees with the catalogue by itself. - Category
shop_status—active/unlisted/hidden(CategoryCommerce). Onlyhiddenremoves a category's items from listings (Query.exclude_hidden_categories/2);unlistedonly hides the category's own nav entry — its page and items stay directly reachable. An absentshop_statusdefaults UNCONDITIONALLY to"active"(View.category_view/2:Map.get(ecommerce, "shop_status") || "active"— no fallback toc.statusat all).
No warnings — the reachability leak is closed on both sides
An earlier version of this column warned on the one combination
that was a real hazard: the shop reporting something as visible
while the catalogue had retired or soft-deleted it, so that it was
excluded from every listing, count and facet
(ProductSource.Catalogue.Query.active_visibility/1 unconditionally
requires item.status == "active" / c.status != "deleted") yet
still reachable by direct link, because the single-record pages
resolved the status from shop_status alone.
That leak is now closed at the source for both record types, so there is nothing left to warn about:
- Items —
View.product_status/2checksitem.statusFIRST and forces"archived"on any non-active catalogue status regardless ofshop_status(phoenix_kit_ecommercePR #53), soCatalogProduct.do_mount/3(which redirects on any resolved status!= "active") cannot be fooled by a stale explicitshop_status: "active". - Categories —
View.category_status/2forces"hidden"for a catalogue-deleted category no matter whatshop_statussays (commit af9308b;catalog_category_catalogue_status_test.exsproves the page redirects), soCatalogCategory.do_mount/3's block-list gate (redirect only on literal"hidden") is reached with the forced value, never the stale one.
What remains is a catalogue/shop DISAGREEMENT (a discontinued item
with shop_status: "active"; a deleted category with "unlisted")
— display-only information the admin may want to see, but not a
hazard, and every other disagreement (catalogue active while the shop
says draft/archived/hidden/unlisted) is simply how the owner
deliberately keeps something out of the shop while it stays a live
catalogue entry. All of them render with no warning. An absent
shop_status is shown as the value it effectively resolves to (per
the fallbacks above), marked "(default)" rather than as an alarming
"Unknown" — it is not a misconfiguration, just a namespace the Shop
section has never written.
Reached only through PhoenixKitEcommerce.Catalogue.Extension's
item_columns/0/category_columns/0 — see that module's moduledoc
for the discovery contract, and PhoenixKitCatalogue.Extension's
typedoc (in the optional phoenix_kit_catalogue dependency) for the
exact %{id:, label:, render:} shape this returns. Written
duck-typed on purpose: nothing here references a PhoenixKitCatalogue
module, so it compiles and behaves identically whether or not that
dependency, or the extension-column slot it implements, is present at
all.
Badge colours
Core's PhoenixKitWeb.Components.Core.Badge.status_badge/1 has no
case for unlisted/hidden/an unrecognized value — all three fall
through to the same grey badge-ghost, which would render three
semantically different category shop-statuses identically. Rather
than edit core, this module picks its own explicit badge class per
status (see item_shop_badge/1, category_shop_badge/1,
catalogue_badge/1) instead of delegating to status_badge/1.
Summary
Functions
The category_columns/0 entry — see this module's moduledoc.
The item_columns/0 entry — see this module's moduledoc.
Functions
@spec category_columns() :: [map()]
The category_columns/0 entry — see this module's moduledoc.
@spec item_columns() :: [map()]
The item_columns/0 entry — see this module's moduledoc.