# `PhoenixKitEcommerce.Catalogue.Extension`
[🔗](https://github.com/BeamLabEU/phoenix_kit_ecommerce/blob/0.5.10/lib/phoenix_kit_ecommerce/catalogue/extension.ex#L1)

Structurally implements `PhoenixKitCatalogue.Extension` — the catalogue
item/category form "extension slot" (spec §2 principle 8). `phoenix_kit_catalogue`
is an optional dependency, so this module does NOT declare `@behaviour
PhoenixKitCatalogue.Extension`; that would force it to be loaded at
compile time. Discovery is duck-typed, the same pattern as
`PhoenixKitEcommerce.AITranslatable` / `ai_translatables/0`: catalogue
finds this module via `PhoenixKitEcommerce.catalogue_extensions/0` and is
responsible for checking it is actually usable before calling it.

# `cast_category`

```elixir
@spec cast_category(map(), map()) :: {:ok, map()} | {:error, [{atom(), String.t()}]}
```

Validates and shapes `category["ecommerce"]` — see `CategoryCommerce.cast/2`.

# `cast_item`

```elixir
@spec cast_item(map(), map()) :: {:ok, map()} | {:error, [{atom(), String.t()}]}
```

Validates and shapes `item["ecommerce"]` — see `ItemCommerce.cast/2`.

# `category_columns`

```elixir
@spec category_columns() :: [map()]
```

Same as `item_columns/0`, for the catalogue category table — categories carry their own `shop_status` too (`CategoryCommerce`).

# `category_section`

```elixir
@spec category_section(map()) :: Phoenix.LiveView.Rendered.t()
```

Renders the Shop section inside the catalogue category form.

# `duplicate_data`

```elixir
@spec duplicate_data(:item | :category, map()) :: map()
```

The shop fields a copied item or category keeps (catalogue's Duplicate,
a whole catalogue's copy included). A copy leaves out what ties the
original to other records: on an item the whole Shopify sub-map (product
id and handle, which the collection and media syncs match items by — two
rows claiming one product would both be synced to it — plus the
`image_ids` and `set_slugs` bookkeeping of that sync) and the legacy
product it was migrated from; on a category the Shopify
collection id the collection sync writes. Everything else is the copy's
to keep; a featured item inside the copied rows is re-pointed by the
catalogue itself.

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

Whether the Shop section should be shown / absorbed.

# `item_columns`

```elixir
@spec item_columns() :: [map()]
```

Extra column for the catalogue item table's Columns modal — surfaces
the shop's own `shop_status` next to the catalogue's `status` so the
two stop contradicting each other invisibly. See `ShopStatusColumn`.

# `item_section`

```elixir
@spec item_section(map()) :: Phoenix.LiveView.Rendered.t()
```

Renders the Shop section inside the catalogue item form.

# `key`

```elixir
@spec key() :: String.t()
```

Namespace under `data` this extension owns.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
