SeriesPart 25 of Building a property procurement platform on MedusaView the cluster →
Medusa & ArchitectureArticle

The product is in stock at three supplier sites. Which one should serve the property?

How we connected property context, viable supplier stock, route-distance reuse and Elasticsearch to filter and rank Medusa products by nearest location.

We Are Souk article cover: The product is in stock at three supplier sites. Which one should serve the property?
Souk EngineeringCommerce architectureAug 2026·10 min read
Key takeaways
  • A buyer finds the right product.
  • Which location should the platform show?
  • That was the client problem in a multi-vendor property-procurement marketplace built on Medusa.
  • We built a property-to-stock-location distance capability around the commerce engine.

The client problem

A buyer finds the right product. The marketplace says it is available. But the supplier holds it at three different sites: one nearby, one farther away and one configured for pickup.

Which location should the platform show? Which distance should it attach to the product? And how can it answer without calling a mapping provider for every product on every search?

That was the client problem in a multi-vendor property-procurement marketplace built on Medusa. Buyers were not shopping for an abstract account. They were buying for a real property, while suppliers fulfilled from several stock locations.

We built a property-to-stock-location distance capability around the commerce engine. It first identifies locations that can genuinely fulfil the product, reuses distance records while both addresses remain unchanged, selects the nearest viable location and applies radius filters before search pagination.

The result is a catalogue that can answer a useful business question: not simply “is this product in stock?”, but “where can this property actually obtain it from?”

The client problem: availability has a location

Standard product availability usually answers whether stock exists somewhere.

That answer is not sufficient for a marketplace whose suppliers operate several warehouses, stores or branches. A product can be available at several sites, yet those sites are not interchangeable for the buyer.

One may be seven miles from the property. Another may be forty miles away. A third may hold stock but offer no active pickup option. Two sellers may offer equivalent products from different territories. The buyer needs a credible local result, and the marketplace needs a deterministic way to produce it.

The hard part is not drawing a distance on a product card. It is deciding which product-location pairs are eligible before comparing them.

We therefore treated proximity as a fulfilment decision. Stock, seller ownership, location and property context establish the candidates. Routing ranks the candidates that remain.

Start with stock that can actually fulfil the product

A distance to an empty warehouse is commercially useless.

The resolver starts from published products, their variants, inventory items and seller-linked stock locations. A location is eligible only when the inventory available after reservations satisfies the quantity required by the variant.

That distinction matters for products assembled from several inventory items. Checking one positive stock line would create false availability if another required component were missing. The query guards the complete inventory requirement at the location.

Pickup is an additional rule, not an assumption. Ordinary proximity search considers viable supplier stock locations. When the storefront explicitly asks for pickup distance, the resolver keeps only locations connected to an active pickup fulfilment option.

This gives each surface the right answer. A nearby warehouse can support delivery-oriented discovery without pretending to be a collection point. A pickup card only shows a site where the buyer can actually collect.

Make the property the origin of the decision

The same buyer can purchase for several properties. A location that is nearest to the head office may be irrelevant to a project site in another city.

The platform therefore resolves distance from the active property address, not from a generic customer postcode or browser location. The property context is also tied to the customer organisation. If the requested property belongs to another organisation, the resolver returns no distance data.

This boundary protects more than privacy. It keeps the business meaning stable: every mileage value shown in the catalogue refers to the property currently driving the procurement journey.

The address can use stored latitude and longitude when available. Otherwise, it is formatted from street, city, state, postal code and country. State and postal values are normalised before routing so equivalent address forms do not create avoidable mismatches.

Cache the question, not just the answer

Calling a route service for every product card would make search slower and turn an external API into a recurring cost centre.

We persist distance by property, stock location, travel mode, provider and hashes of both addresses. Before calculating anything, the service asks whether an approved record already exists for the same question.

The address hashes are the important part. If neither the property nor the supplier location has changed, the previous route remains reusable. If either address changes, its hash changes and the old record no longer matches.

This avoids a fragile time-only cache. A distance does not become wrong because it is one day old; it becomes questionable when one of its endpoints changes or the routing contract changes.

The platform can therefore reuse durable work across catalogue requests while still reacting automatically to an updated delivery address or relocated supplier site.

Prefer road distance and keep a practical fallback

Where the route provider is configured, the service requests driving distance and duration between the property and the stock location. Coordinates are used directly when present; otherwise, the provider receives a normalised address.

The request has a bounded timeout. Product discovery should not wait indefinitely because a mapping service is slow.

If no usable road route comes back, the service can fall back to a postal-code distance for supported US addresses. That fallback supplies an approximate distance rather than a driving duration. It is useful for keeping location-aware discovery available when precise routing cannot be resolved.

The product does not pretend those two answers are identical. The stored record identifies its provider, and duration remains empty when the fallback cannot support it.

This is a practical resilience choice: preserve a useful proximity signal when possible, while retaining enough provenance for the platform to understand how it was produced.

Select the nearest viable location for each product

Once eligible locations have a distance, the marketplace needs one clear answer per product.

The resolver compares all successful location candidates and keeps the shortest distance. If two locations have the same mileage, the stock-location identifier provides a stable tie-breaker. The same input therefore produces the same selected site.

This is especially valuable in a marketplace. A product may be linked to one seller with several stores, or availability may be spread across different supplier relationships. The buyer should not have to understand that topology simply to read a catalogue result.

The returned evidence remains useful to the interface: mileage, selected location, location name, postal code and address can accompany the product. Pickup responses round the mileage for a simpler customer-facing display while preserving the chosen site.

The business rule is straightforward: among the locations that can fulfil this product under the requested mode, show the closest successfully resolved option.

Do not let one failed route erase the whole result

External routing can fail for a single address. A location may have incomplete data, a provider call may time out or no route may be returned.

The platform resolves locations in bounded parallel groups. Each location is isolated: if one calculation fails, that candidate is skipped while successful candidates remain available.

Suppose a product exists at two supplier sites. The farther site times out, but the nearer site resolves correctly. The product can still receive a valid nearest-location answer. The storefront does not lose every proximity result because one branch of the calculation failed.

This behaviour is covered by a focused test. It is a small implementation detail with a large product effect: partial infrastructure failure becomes a partial answer, not a blank catalogue.

When no candidate produces a usable distance, the result stays absent rather than inventing a number. The interface can then fall back to ordinary availability without presenting false precision.

Filter by radius before paginating the catalogue

A “within 25 miles” filter must be applied before pagination.

Filtering the 20 products returned on the current page would produce broken navigation. Page one might contain three eligible products while relevant products remain hidden on later pages. Counts and ordering would no longer describe the filtered catalogue.

The distance capability first collects candidate product identifiers from the search index in stable batches. It can continue beyond the normal result window with search_after, and it stops at an explicit safety ceiling rather than creating an unbounded request.

The platform then resolves or reuses the nearest distance for those candidates and builds a product-ID filter for the requested radius. Elasticsearch applies that filter before rendering the requested page.

If no product is eligible, the query deliberately matches nothing. If products are eligible, their identifiers become the search constraint. Pagination, totals and catalogue visibility now describe the same radius-filtered set.

Sort the catalogue using the same distance evidence

Radius answers “is it close enough?” Sorting answers “which useful option should appear first?”

The search layer receives the selected mileage for each product and applies a numeric distance sort. Products with a known shorter distance rise first. A product identifier provides the stable secondary order when distances are equal.

The same evidence is attached to the returned product as distanceMiles, so the displayed value and the ordering come from one decision rather than two separate calculations.

For an unconstrained closest search, the platform can also read a bounded set of already-persisted property-to-location distances from PostgreSQL. Elasticsearch still controls catalogue visibility and product rendering; the relational store supplies only the proximity inputs needed for ranking.

This division keeps search responsible for search while avoiding a fresh routing fan-out every time a buyer selects “nearest”.

Keep distance and delivery territory as separate capabilities

Distance is not permission to deliver.

A supplier may serve a state through scheduled freight even when its warehouse is far away. Another may decline an address just outside a defined territory despite a short straight-line distance. Pickup has its own fulfilment requirement.

The marketplace therefore keeps two related questions separate:

  • supplier service zones decide whether a location is intended to serve the property;
  • property-to-location distance ranks or filters viable stock locations.

This distinction prevents a convenient number from silently rewriting the supplier's commercial rules. Distance enriches availability; it does not replace fulfilment eligibility.

It also lets the operator evolve each capability independently. Territorial rules can follow real delivery operations, while routing can improve precision, caching and resilience without changing where the supplier has agreed to serve.

Why Medusa was the right foundation

Medusa already gave the project products, variants, inventory reservations, stock locations and fulfilment primitives. The client problem lived in the relationships between those capabilities and a property-centred marketplace.

We extended the engine with a dedicated distance record, seller-location availability queries, organisation-aware property context, routing adapters and Elasticsearch controls for filtering and sorting.

That is the value of choosing an extensible commerce foundation. We did not have to rebuild catalogue, inventory or fulfilment. We could add the exact decision the marketplace needed: which viable supplier location is most relevant to this property?

On a rigid platform, this often becomes a detached postcode widget that cannot see live reservations, seller ownership or search pagination. Here, proximity participates in the commerce model instead of sitting beside it.

A practical design checklist

Before adding location-aware product discovery, answer these questions:

  1. Is distance calculated from the active delivery property?
  2. Is that property authorised for the current organisation?
  3. Which stock locations can satisfy the complete variant requirement?
  4. Is pickup required for this particular surface?
  5. Are both endpoint addresses normalised before routing?
  6. Does the cache key change when either address changes?
  7. Is the distance provider and calculation time retained?
  8. Is the external request bounded by a timeout?
  9. Can successful locations survive another location's failure?
  10. How is the nearest location chosen when distances tie?
  11. Is a radius applied before search pagination?
  12. Does sorting use the same mileage shown to the buyer?
  13. Is there an explicit ceiling for large candidate searches?
  14. Are delivery territory and proximity kept as separate rules?

These decisions turn a mapping call into an operable marketplace capability.

The broader lesson

The client did not need a badge saying “seven miles away”.

They needed the marketplace to understand property, supplier, stock and fulfilment together. Only then could distance become useful to catalogue discovery.

We started with locations that could genuinely fulfil the product, resolved distance from the authorised property, reused records while both addresses remained unchanged and selected the nearest successful candidate. Radius filtering happens before pagination, sorting uses the same evidence displayed to the buyer and one failed location does not erase the rest.

For the buyer, the catalogue becomes locally relevant. For the supplier, stock remains connected to the site that can serve it. For the marketplace, proximity becomes a dependable commerce decision rather than a decorative map feature.

Read next
Keep the useful ideas coming

One practical commerce field note at a time.

Join the WeAreSouk journal for grounded stories about Medusa, Shopify, AI, integrations and the systems behind serious commerce.

Working on a similar problem?Bring us the business constraint. We’ll help map the system behind it.Talk to Souk →
Souk AI · online now

Turn the article into an implementation plan.

Ask how this applies to your store, your stack, or your current bottleneck.

01 Describe your current setup.02 Name the workflow or signal that feels unreliable.03 Get a practical first architecture back.
I can help map this article to your stack. Tell me what you sell, what platform you use, and where the medusa & architecture question hurts.
Continue the cluster

Building a property procurement platform on Medusa

Start a conversation

Tell us what commerce needs to do for your business.

No scheduling maze. Send the context, the constraint or the idea. We will read it and come back to you directly.