Skip to main content
Status Sign in

Dealer map

Every manufacturer, retail chain, and distributor in powersport needs a place on their storefront where customers find 'who carries this brand near me'. PowersportOS ships a structured Dealer record with full address + coordinates + contact info, plus a Shopify-theme widget that renders it as an interactive map. CSV import + bulk geocoding handle the typical onboarding case of 'here are 80 dealers in a spreadsheet'.

The data model

Every Dealer row is scoped to a single tenant. Required fields are name + city + country + postal code + street address. Optional fields are lat/lng, phone, website, and an opt-in linkedTenantId pointing at another PowersportOS tenant if the dealer is itself a customer (powers the reseller stock network).

Active flag
Inactive dealers don't appear on the storefront but stay in the database. Useful for seasonal closures, contract disputes, store renovations.
Lat/lng
Optional but recommended. Populated via the geocode button on the dealer detail page (Mapbox API), or via bulk-geocode on CSV import. Drives 'nearest dealer' sorting on the storefront widget.
linkedTenantId
Optional pointer to another PowersportOS tenant. When set, that dealer's stock for a queried part can be looked up live via the reseller stock network.

Storefront API

Two endpoints power the storefront widgets:

  • GET /api/t/dealers, full list of active dealers for the tenant. Used by the basic store-locator: render every dealer on a map with country filter.
  • GET /api/t/dealers/stock, manufacturer-side query for "nearest dealers with this part in stock". Two-path resolution: linked-tenant aggregation for manufacturer/reseller flows, own-DealerStock-row lookup for retail multi-location.

Full endpoint specs in the storefront dealers API doc.

Mapbox configuration

The map renders via Mapbox GL JS on the storefront side. Each tenant configures their own Mapbox public token in the customer portal under Settings → Mapbox. The token is exposed via /api/t/config to the theme, which uses it to authenticate the Mapbox tile service.

CSV import flow

Most customers arrive with a spreadsheet of 30–300 dealers. The portal's dealer CSV importer accepts:

  • Standard column shape: name, address, city, postal_code, country, phone, website, lat, lng, active.
  • Country values as ISO 2-letter codes or full English names, the importer normalises.
  • Geocode-on-import: rows without lat/lng get queued for Mapbox forward-geocoding using the address. Result rate is typically 90+% for well-formed addresses; failures get flagged for manual lookup.

Importer is idempotent: re-running the same CSV with updated values updates the existing rows, doesn't duplicate.

Country filtering

Storefront widget supports country filter chips at the top of the map. Drives a smaller-list, country-specific view useful for tenants operating across multiple Nordic + Baltic markets where customers want their own country's dealers prioritised.

For retail tenants: the same widget, different mental model

RETAIL tenants run dealers as their own physical stores (multi-location retail). The data model is identical; the UI labels say "Locations" instead of "Dealers" in the portal sidebar, and the storefront widget can be framed as a store-locator for their own branches. The stock-locator widget then reads from each location's DealerStock table to show real-time availability per branch.

Same widget, three audiences: manufacturers find dealers, retailers find branches, distributors find resellers. One data model handles all three.