Skip to main content
Status Sign in

Internal YMM Lookup

The storefront YMM widget answers the customer's question: 'which parts fit my bike?' The same question shows up on the operator side a dozen times a day, phone calls, email inquiries, label printing for incoming stock, coverage checks for new brands. PowersportOS exposes the same YMM resolution as a portal page so operators get the answer without leaving the platform.

The workflow problem this solves

Without an internal YMM surface, operators end up doing one of three things to answer a vehicle-driven question:

  • Open the customer-facing storefront, pick Year/Make/Model, copy the SKU back into the portal. Works but feels backwards, using your own storefront as an internal tool.
  • Search the catalog by part number, only works if you already know the SKU.
  • Look up the part in Shopify admin or an Excel sheet, a context-switch into a different domain.

None of these scale. The internal YMM lookup is the same resolution layer the storefront uses, exposed at /lookup in the portal sidebar.

How it works

Four cascading dropdowns: Year → Make → Model → Submodel. Each fills as you pick the previous, scoped to vehicles that have at least one part visible in your catalog. If only one submodel variant exists for the chosen year+model, it auto-selects so the operator doesn't have to click a one-option dropdown.

Pick a vehicle, get back the same parts payload the storefront API returns: part number, OEM ref, brand, name, category, your price, and stock. Each result row has three actions:

Print label
Opens the same one-click print dialog used on My Catalog and My Parts. Uses tenant-level defaults from Settings → Labels. Bulk-print for a vehicle is on the roadmap; today it's one-click per row.
Open manual
Shown only when the part has a manualUrl set. Opens the PDF in a new tab. Lets a customer-support call become a 'I'll email you the manual right now' moment without any extra hops.
Open part
Routes to My Catalog filtered to this part number. Editable price / stock / bin, full part context.

Same resolution layer as the storefront

The portal endpoint /api/app/lookup/* and the storefront endpoint /api/t/* share one shared library (apps/api/src/lib/ymm). Auth context differs, session cookie for the portal, X-API-Key for the storefront, but the business logic is identical. Any new access path (parent-tenant TenantParts via TenantParentItem in Multi-Store children, future tenant types, etc.) gets added once and both surfaces pick it up automatically.

This matters because divergence between "what the operator sees" and "what the customer sees" is the kind of bug that erodes trust. One source of truth, zero drift.

Multi-Store: parent catalog merges in

For a Multi-Store child tenant (a Shopify store running under a parent brand's catalog), the lookup automatically merges the child's direct activations with the parent's TenantParts that the child has activated via the Group page. The operator sees exactly what their own store sells, no other children's catalogs, no parent-only items the child hasn't activated.

See the Multi-Store doc for the full hierarchy semantics.

Why this matters strategically

What's planned (not v1)

  • Saved searches per user. Returning to a frequent vehicle pre-fills the dropdowns.
  • Bulk-select for batch label printing. Pick a vehicle, select 12 of its parts, print all labels in one shot.
  • Tire dimension search. Parallel surface to YMM for tire-sized parts. ATV/UTV tire numbering (25x8-12) and motorcycle metric (120/70-17) are orthogonal to vehicle data.
  • Universal search bar. Free-text + YMM + alias-lookup + barcode-scan input as one entry point at the top of the portal. Internal YMM lookup is the first step toward this.