Skip to content

Powered by Grav CMS + Helios Theme

Catalog index, types and relations

The denormalised index behind listings and facets, the synonym table, product types and related products.

The denormalised index behind listings, facet counts, sorting and the sql search rung, plus the merchant's synonym table, the store's product types and the curated related-products list. What the index holds and when it is joined at all is on The catalog index.

Catalog index status

GET /api/v1/kahunacart/catalog/index Permission kahunacart.products.manage

What the denormalised catalog index holds and whether the storefront is actually reading it. in_use false with built true is normal, not broken: in the default auto mode the index is only joined when a sale, a price list or a search term needs it, so a store running no promotions answers its listings with live queries on purpose. Read this before rebuilding, and read pending to see how many products are waiting for the next background tick. A store that sells in more than one currency also gets a currencies object: state is ready, off, unbuilt or missing, missing lists the currencies added since the last full rebuild (shoppers in those cannot sort or filter by price until one is run), and rows counts the prices the index holds across every extra currency.

Rebuild the catalog index

POST /api/v1/kahunacart/catalog/index/rebuild Permission kahunacart.products.manage

Rebuild the denormalised index every listing, facet count, sort and search reads. Without full it drains only the products already marked dirty, which is what you want after saving a sale and not wanting to wait for the next background tick. With full it throws the index away and rebuilds it from the catalog — the right call after a bulk import that wrote products around the API, or after restoring a database. Chunked and resumable; complete false means the catalog is larger than one call can walk and bin/plugin kahunacart index --rebuild should finish it.

Parameters

Name Type Description
full optional boolean Throw the index away and rebuild it, instead of draining what is dirty
Default: false
max optional integer Most products to walk in this call

List search synonyms

GET /api/v1/kahunacart/search/synonyms Permission kahunacart.products.manage

The merchant's own search vocabulary: each row is a word shoppers type and the words it should also find. Expansion is one-way and applied at query time, so a row saying jumper finds sweater does not also make a search for sweater find jumpers — add that row too if you want it — and a new row takes effect on the next search rather than after a catalog rebuild.

Replace the search synonyms

PUT /api/v1/kahunacart/search/synonyms Permission kahunacart.products.manage

Replace the whole synonym table with the rows you send. A whole-table write rather than per-row edits, because that is what the screen is: omitting a row deletes it. Terms and synonyms are folded the same way the search index folds product text, so case, accents and punctuation do not matter. Validated before anything is written, so one bad row leaves the merchant's table exactly as it was.

Parameters

Name Type Description
synonyms required array of object Every row the table should hold after this call. Keys: `term`, `synonyms`

List product types

GET /api/v1/kahunacart/product-types No permission

Every kind of thing this store can sell: the four core types (physical, digital, grouped, external) plus any an installed add-on registers. Each carries what the cart does with it — whether it ships, whether it holds stock, whether it can be bought on its own, and whether adding it adds itself or its declared children — plus the extra product fields the type asks for and how many products currently wear it. A type with registered: false is one whose plugin is switched off: its products are still in the catalog and still editable, and they are refused at the cart door until it comes back. Call this before setting a product's type_code, because a code no type declares is refused.

List curated related products

GET /api/v1/kahunacart/products/{id}/relations Permission kahunacart.products.manage

List the products a merchant hand-picked to sit beside this one, in the order they picked them, split into the three kinds: related ("you might also like"), cross_sell ("goes well with this") and up_sell ("consider this instead"). Nothing here is derived from categories or tags — an empty list means nobody has curated one.

Parameters

Name Type Description
id required integer The product whose lists to read.

Set curated related products

PUT /api/v1/kahunacart/products/{id}/relations Permission kahunacart.products.manage

Replace one product's curated lists. Send each kind as a list of product ids in the order they should render; a kind you leave out is left exactly as it was, and a kind you send as an empty list is cleared. Ids naming no product are dropped, and the answer says what was actually stored. This replaces rather than appends — send the whole list.

Parameters

Name Type Description
id required integer The product being curated.
related optional array of integer Product ids for the "you might also like" block, in render order.
cross_sell optional array of integer Product ids for the "goes well with this" block, in render order.
up_sell optional array of integer Product ids for the "consider this instead" block, in render order.

Rebuild the relation cache

POST /api/v1/kahunacart/products/relations/rebuild Permission kahunacart.products.manage

Orphan every cached relation block in the store and delete relation rows pointing at products that no longer exist. Cached blocks hold product ids only, never prices, so this is about which products appear rather than what they cost. Use it after bulk changes to the catalogue.

List bulk-edit fields

GET /api/v1/kahunacart/products/bulk/fields Permission kahunacart.products.manage

List what a bulk edit can change, which modes and units each field accepts, the values the enumerated fields allow, and the store's admin.bulk.max_rows limit. On a store that sells in more than one currency the answer also lists the two instructions about another currency's price (currency_price and currency_fill), currencies and the roundings a fill accepts. Call this before bulk_update_products if you do not already know the vocabulary.

A rebuild is chunked by catalog.index.chunk and can also be run from the CLI with bin/plugin kahunacart index.

Relations are stored rather than computed per request, so a change is a write and POST /kahunacart/products/relations/rebuild is what recomputes the derived side.

A product type is changed with an ordinary product update. Changing it is reversible: the fields the old type used are kept, not deleted, so switching back restores them.