- A private ecommerce wishlist answers one simple question: “What might I buy later?” That model breaks down when a property team buys together.
- A maintenance technician may identify replacement parts during an inspection.
- If all of that lives in one shopper's personal favourites, collaboration happens through screenshots, messages and duplicated carts.
- We built property-level collaborative wishlists on Medusa to solve that operating problem.
The client problem
A private ecommerce wishlist answers one simple question: “What might I buy later?” That model breaks down when a property team buys together.
A maintenance technician may identify replacement parts during an inspection. A site manager may adjust quantities. A procurement manager may review the request before anything reaches a cart. The same property may keep a recurring turnover list, an emergency repair list and a renovation list at the same time.
If all of that lives in one shopper's personal favourites, collaboration happens through screenshots, messages and duplicated carts. Nobody knows which version is current, who changed a quantity or whether the items are still purchasable.
We built property-level collaborative wishlists on Medusa to solve that operating problem. A list belongs to the property, not to one browser session. It can be edited by authorised property users, moved from draft to a precise ready revision, copied safely into the correct cart and traced through later purchase events.
The capability turns a familiar consumer pattern into a lightweight procurement document.
The client problem is coordination, not bookmarking
In B2B purchasing, the person who notices the need is not always the person who checks out. A technician knows that a unit needs a faucet cartridge. A supervisor knows whether the work belongs to the current maintenance budget. A purchaser knows which property, cart and approval route should receive the order.
A conventional wishlist stores product IDs for a customer. That is useful for personal recall but misses the business object around the choice:
- the site for which the goods are intended;
- the purpose and name of the list;
- the requested quantity and selected variant;
- notes that explain the requirement;
- the people who contributed;
- the exact version approved for transfer;
- what happened after the hand-off.
We therefore treated the list as shared property context. The property is the collaboration boundary, while the authenticated customer remains the actor behind each change.
Let one property own several named lists
There is rarely one universal list per building. Teams plan different jobs on different timelines.
The data model allows multiple named wishlists to reference the same property. “Unit 204 turnover”, “Pool equipment” and “Q4 preventive maintenance” can coexist without overwriting one another. Each list carries its creator, current content revision and workflow state.
This sounds small, but it changes how people use the feature. A list has a business purpose that colleagues can recognise. A buyer can return to the same work package rather than searching through an undifferentiated collection of hearts.
Items are similarly explicit. They contain the product, chosen variant, quantity, note and the identities of the customers who created or most recently updated them. A line therefore communicates more than interest: it expresses a purchasing intention in context.
Make the property boundary authoritative
The active property is resolved on the server from the authenticated customer's allowed context. Routes do not accept an arbitrary property ID and then trust it.
Every list lookup and mutation checks that the list belongs to that property. The cart used later must belong to the same customer and carry the same property context. A user working at Property A cannot copy a list belonging to Property B into an unrelated cart simply by changing an identifier in the request.
This is essential in organisations where one account can access many sites. The interface may make property switching feel effortless, but the backend must treat the current site as part of every procurement decision.
The lesson extends beyond wishlists: tenancy in B2B commerce often lives below the organisation. Organisation membership proves who the customer works for; property scope determines which operational resources they may act on now.
Use revisions to prevent invisible overwrites
Collaboration creates a concurrency problem. Two people can open the same list. One changes a quantity while the other removes a product. If the second save blindly overwrites the first, the interface looks successful while somebody's work disappears.
The wishlist carries a monotonically advancing content revision. A mutation submits the revision the user saw. The backend locks the list and compares that expected value with the current one. If they differ, it returns a conflict and asks the client to reload instead of silently choosing a winner.
Each accepted item change records the actor and advances the revision. This gives the system a precise answer to “which contents are we talking about?”
It also lets notifications and cart transfers refer to a stable revision rather than to a list that may have changed between steps.
Separate drafting from the ready hand-off
During preparation, the list is a draft. Colleagues can add products, choose variants, change quantities and leave notes.
When the team decides that the request is complete, an authorised user marks a specific revision ready. The server checks that the expected revision is still current, that the list contains at least one item and that every line has a usable variant. Legacy lines can be repaired to the product's valid technical variant when that mapping is unambiguous.
The ready transition stores the revision, actor and timestamp together. A unique revision event prevents duplicate ready records. Relevant recipients can then be queued for notification from that durable transition.
This is not a heavyweight approval engine. It is a clear hand-off: “revision 12 of this property list is ready to be reviewed or purchased.” That small state change removes ambiguity from conversations around the list.
A later edit creates a new purchasing proposition
A ready list should not remain silently ready after its contents change. If someone adds two sinks or replaces a variant, the document presented to the buyer is no longer the one previously marked complete.
The revision model makes that distinction natural. Content changes advance the revision and return the list to a draft proposition. The team can review and mark the new revision ready again.
This avoids a dangerous shortcut in collaborative commerce: using one mutable flag as permanent approval. Readiness belongs to contents at a moment in time, not to the list's name forever.
The same reasoning explains why viewed, copied and purchased events include the revision. Operations can understand which exact proposal moved forward even after the list evolves for another maintenance cycle.
Recheck products before copying anything to a cart
A list can remain open for days or weeks. In that interval, a product may become hidden, a variant may disappear or the active property may lose access to the supplier.
The copy action therefore does not trust the earlier draft. It loads the exact ready revision and validates the current visibility of every selected product and variant. If an item is no longer available, the request returns a structured explanation and leaves the cart unchanged.
That behaviour protects the buyer from reaching checkout with a partially copied work order. It also keeps commercial truth where it belongs: in the current catalogue and market context, not frozen forever in a collaborative note.
The list preserves purchasing intent. Medusa's live commerce services decide whether that intent can still become an order.
Make copy-to-cart idempotent
Users double-click. Mobile connections retry. A browser may not receive a successful response even though the server completed the cart update.
Without an idempotency contract, retrying “copy this list” can double every quantity.
We built a durable import record keyed by cart, wishlist and revision. Before changing the cart, the backend locks the list, verifies that the requested revision is still ready and claims the import. It captures a source manifest containing each wishlist item, variant, requested quantity and the quantity already present in the cart.
If the same revision has already been committed to that cart, the endpoint returns an idempotent success rather than adding the lines again. If another copy is in progress, it reports a conflict. This makes retries explicit and safe.
The source manifest also gives a reconciler enough information to inspect a copy whose cart write succeeded but whose final ledger update was interrupted.
Preserve provenance after the cart takes over
Each cart line added from the list carries wishlist, revision, item and import identifiers in metadata. A copied revision event records the actor and cart.
That provenance matters later. When an order is created, the system can connect the purchase back to the shared request that initiated it. The list does not merely disappear into an anonymous cart.
It supports useful product questions: Was this ready list viewed? Was it copied? Did it produce an order? Which revision? Those facts can improve operations without turning the collaborative list into the source of truth for payment or fulfilment.
The order remains a Medusa order. The wishlist provides the human decision trail that led to it.
What the property team experiences
The technical controls produce a straightforward workflow for the users:
- A team member creates a named list for the active property.
- Colleagues add exact products, quantities and notes.
- Concurrent edits cannot silently overwrite a newer revision.
- Someone marks the completed revision ready.
- The buyer opens that precise version and copies it to a property cart.
- Current catalogue visibility is checked before the cart changes.
- Retrying the copy does not duplicate the request.
- The later order can retain the list's provenance.
The feature feels familiar because it uses the language of lists. Underneath, it respects the collaborative and financial consequences of B2B purchasing.
Why Medusa was the right foundation
Medusa already owns customers, products, variants, carts and orders. We did not replace those commerce primitives with a parallel procurement engine.
Instead, we extended the platform with property ownership, revisioned collaboration and durable hand-off records. The shared list captures intent; Medusa validates products and performs the cart mutation; the resulting order continues through the normal commerce lifecycle.
That is the architectural advantage of an extensible commerce engine. A generic consumer wishlist would not solve the client's workflow, but the core did not need to be abandoned. We could add the exact business capability around it.
For a commerce leader, that distinction affects both adoption and delivery risk. The team receives a workflow that matches how maintenance purchasing already happens, while catalogue, cart and order truth continue to use the platform's established primitives. People do not need to learn a separate procurement suite merely to prepare a recurring supply request. At the same time, the implementation does not create a shadow catalogue or a second checkout that must later be reconciled. The extension joins human collaboration to the existing transaction at a controlled, visible boundary.
If property teams still coordinate supply requests through screenshots and duplicated carts, WeAreSouk can design the shared-list, revision and cart-transfer workflow that makes the process dependable in Medusa.
