Docs

Shop catalog

uticms.shop.catalog · verified 2026-07-14

Overview

Scope
Shop product-domain data and read/indexing services; excludes basket/order lifecycle

Key concepts

Catalog Tree
Adjacency-list catalog hierarchy materialized into lft, rgt, and depth values for nested-set reads.
Offer
Purchasable product variation with stock/pricing participation.
Facet Entry
Denormalized index row used to filter storefront catalog products.
Facet Index Version
Versioned facet representation produced by the indexer.

Structure

  • Catalog Domain
    • Tables
      • shop_catalogs
      • shop_catalog_translations
      • shop_brands
      • shop_brand_translations
      • shop_units
      • shop_unit_translations
      • shop_products
      • shop_product_translations
      • shop_catalog_product
      • shop_offers
      • shop_offer_translations
      • shop_product_relations
  • Commercial Data
    • Tables
      • shop_price_types
      • shop_prices
      • shop_warehouses
      • shop_stock
  • Indexes
    • Search
      • shop_search_index
      • shop_search_trigrams
    • Facetsshop_facet_entries
  • Services
    • Catalog TreeModules/Shop/Services/Catalog/CatalogNestedSetService.php
    • Search
      • SearchService
      • SearchIndexer
    • FacetsModules/Shop/Services/Facet/

Facts

  • Shop migrations create separate catalog, brand, unit, product, offer, translation, product-catalog pivot, and product-relation tables. authoritative
  • Shop migrations create price types, prices, warehouses, and stock tables as distinct commerce data structures. authoritative
  • CatalogNestedSetService rebuilds lft, rgt, and depth from catalog parent_id and sort within a database transaction. authoritative
  • Catalog nested-set rebuilding has suspension and re-entrancy guards for bulk operations. authoritative
  • The facet migration adds is_filterable to Shop custom fields and creates shop_facet_entries. authoritative
  • FacetIndexer rebuilds active products in chunks, removes entries for missing/inactive products, and can rebuild a full or catalog-specific scope. authoritative
  • FacetIndexer can defer product reindexing while its global enabled flag is false, supporting bulk import workflows. authoritative
  • CatalogTreeFacetHelper::descendantIds reads anchor lft/rgt and selects descendant catalog ids with nested-set bounds instead of loading the full catalog tree into memory. authoritative

How-to guides

Rebuild Catalog Indexes

  1. finish catalog/product mutations
  2. rebuild nested-set boundaries when parentage or sort changed
  3. run the appropriate Shop search/facet index rebuild
  4. verify inactive products no longer have queryable facet rows

Rules

Architectural rule

Do not mutate parent_id or sort in bulk and assume nested-set boundaries remain valid; rebuild or deliberately control automatic rebuild behavior.

Architectural rule

Rebuild/remove facet entries when a product becomes inactive or when its filterable catalog data changes.

Examples

Index Rebuild Commands

php artisan shop:facet-index --fresh
php artisan shop:search-index

modules/Shop/Console/Commands/RebuildFacetIndexCommand.php

Catalog Facet Filter

$ids = app(CatalogTreeFacetHelper::class)->descendantIds($catalogId, includeSelf: true);

modules/Shop/Services/Catalog/CatalogTreeFacetHelper.php