Skip to content

Features

All features are gated by environment flags. When disabled, routes are not registered and Filament resources are hidden.

Inventory Per Location

Flag: SHOPIFY_FEATURE_INVENTORY

Exposes product stock levels per physical location through the App Proxy.

How It Works

  1. Theme JS calls GET /apps/lamashopi/inventory/{productHandle}
  2. The app checks Redis cache for the product's inventory data
  3. On cache miss, queries the Shopify Admin API for inventory levels per location
  4. Returns stock data grouped by location (with optional slug mapping)

Cache Invalidation

Stock data is cached in Redis with a configurable TTL (SHOPIFY_INVENTORY_CACHE_TTL). When Shopify sends an inventory_levels/update webhook, the cache is invalidated for the affected product.

Location Slugs

Map Shopify location GIDs to URL-friendly slugs via SHOPIFY_LOCATION_SLUGS in .env. This lets the theme display clean location names instead of Shopify's internal identifiers.

Key Classes

  • ShopifyInventoryService — cache-aside inventory fetching
  • InventoryController — proxy endpoint
  • InventoryItemMapping — model for product-to-inventory-item mappings

Wishlists

Flag: SHOPIFY_FEATURE_WISHLISTS

Full wishlist functionality for both anonymous and authenticated shoppers.

Proxy Endpoints

MethodPathDescription
GET/wishlistsGet wishlist items
POST/wishlistsAdd item
DELETE/wishlists/{id}Remove item
POST/wishlists/checkCheck if items are in wishlist
POST/wishlists/mergeMerge anonymous wishlist into customer wishlist
GET/wishlists/share/{token}Get shared wishlist

Anonymous vs Authenticated

  • Anonymous wishlists are identified by a session/device identifier
  • Authenticated wishlists are tied to a Shopify customer ID
  • On login, the theme should call the merge endpoint to combine anonymous items into the customer's wishlist

Filament Resource

Wishlists are viewable in the Agency panel for support and debugging.


Out-of-Stock Notifications

Flag: SHOPIFY_FEATURE_OOS

Lets shoppers subscribe to back-in-stock alerts for specific product variants.

Flow

  1. Shopper subscribes via POST /apps/lamashopi/oos
  2. Confirmation email is sent (double opt-in)
  3. Shopper confirms via GET /oos/confirm/{token}
  4. When inventory_levels/update webhook fires and stock is now > 0, the DispatchBackInStockNotifications job sends notifications
  5. Shopper can unsubscribe via GET /oos/unsubscribe/{token}

Klaviyo Integration

When KLAVIYO_OOS_ENABLED=true, OOS events are synced to Klaviyo and email flows are handled by Klaviyo Flows instead of the built-in mailer.

Filament Resource

OOS subscriptions are manageable in the Agency panel.


Bundles

Flag: SHOPIFY_FEATURE_BUNDLES

Configurable product bundles with automatic Shopify discount creation.

Concepts

  • Bundle — a named group of product slots that can be purchased together
  • Bundle Slot — a position in the bundle that accepts specific products
  • Bundle Slot Item — a product/variant that can fill a slot
  • Bundle Anchor — the product(s) that trigger the bundle on PDP
  • Bundle Discount — a Shopify automatic discount or discount code created for the bundle

Pricing Types

TypeEnumDescription
PercentageBundlePricingType::PercentagePercentage off the bundle total
Fixed AmountBundlePricingType::FixedAmountFixed amount off the bundle total
Fixed TotalBundlePricingType::FixedTotalBundle sells for a fixed total price

Discount Lifecycle

The BundleDiscountService creates Shopify discounts via GraphQL. It first attempts an automatic discount; if that fails (e.g., limit reached), it falls back to a discount code.

Scheduled commands manage discount health:

  • bundles:cleanup — removes orphaned or expired discounts
  • bundles:health — monitors discount status and alerts on issues
  • bundles:refresh-anchors — refreshes cached anchor-product mappings

Proxy Endpoints

MethodPathDescription
GET/bundles/for-product/{handle}Get bundles for a product
GET/bundles/for-productsGet bundles for multiple products
GET/bundles/{id}/slots/{slotId}/productsGet products for a slot
POST/bundles/add-to-cartAdd bundle to cart

Filament Resource

Bundles are fully manageable in the Agency panel with a form for slots, items, anchors, and pricing.


Store Locator

Flag: SHOPIFY_FEATURE_STORE_LOCATOR

Physical store directory with geocoding and category filtering.

Features

  • Store CRUD in Filament with address, coordinates, hours, and category
  • Automatic geocoding via NominatimGeocodingService (dispatched as a job)
  • CSV import via StoreImporter
  • Store categories for filtering
  • Proxy endpoint: GET /apps/lamashopi/stores

Filament Resources

  • Stores — full CRUD with geocoding
  • Store Categories — category management

Free Shipping Bar

Flag: SHOPIFY_FEATURE_FREE_SHIPPING_BAR

Provides shipping threshold data from Shopify's shipping profiles.

Proxy Endpoint

GET /apps/lamashopi/shipping/thresholds — returns free shipping thresholds via ShopifyShippingService.

The theme uses this data to display a progress bar showing how much more the shopper needs to add for free shipping.

Internal developer documentation