Step 1 β Autocomplete (optional)
GET /api/bonsai/suggest?q=coffee
As the user types, the API queries Bonsai aggregations for matching categories and brands,
and concurrently fetches live completions from Woolworths + Coles (merged and deduplicated internally β sources not exposed).
The dropdown shows up to 12 term suggestions + 8 categories + 6 brands.
Step 2 β Bonsai Search (Elasticsearch)
POST /api/bonsai/search { query, size, offset, filter? }
Runs a function_score query across product_name (Γ5), ai_keywords (Γ3), product_category2 (Γ2), searchable_text (Γ1).
Boosted by brand_boost_factor and priority_score stored per document.
Results are collapsed on product_name so each product appears once even if indexed for multiple supermarkets.
Pinned products are injected at their fixed ranks before the response is returned.
Returns { total, hits: [{ product_id, product_name, product_brand, supermarkets, pinned? β¦ }] }
Step 3 β CockroachDB Price Lookup
POST /api/products/details { product_ids, store_ids, store_map }
Takes the product_ids from Step 2 and queries CockroachDB across four joined tables:
product_details Β· product_attributes Β· product_categories Β· product_price.
Products are grouped by EAN (same physical product across chains), so Woolworths + Coles variants of the same item appear on one card.
For each selected store_id, the response includes a price row (or a null row if not available at that store).
Results are re-sorted client-side to match Bonsai relevance order before rendering.
Featured / Default Products
GET /api/bonsai/featured
Returns up to 20 curated products ordered by rank. Bonsai document metadata is merged with live prices from CockroachDB.
Suitable for use as a homepage or "default" product list by external clients β no internal fields exposed.
Manage via the Featured Products section below (add from search results using β Feature).