DEV Community

Tom
Tom

Posted on

Keep Store Order References Distinct When Two Shops Both Send 00123

Two stores can send the same visible order reference. A fulfillment adapter that indexes both as 00123 can attach an update to the wrong order even when each upstream payload is valid.

Treat the source account and its order reference as separate parts of the identity. Keep the reference as a string unless the source contract explicitly defines another representation. In particular, converting 00123 to a number discards information that this example deliberately preserves.

I work with YX Fulfillment. Its published integration workflow calls for testing incoming orders and tracking return against the systems used by the account. The code below is a small routing model for one part of that test, not a description of YX's production software.

Make the collision visible

Joining two strings with a separator only works if the contract excludes that separator or defines an unambiguous encoding. For unrestricted strings, shop|north plus 00123 collides with shop plus north|00123 when both are joined with |.

A nested Map keeps the two fields separate in this in-memory example. JavaScript maps compare string keys by their value, so a repeated pair reaches the existing entry. See the Map reference for key semantics.

Save the following as order-routing.cjs and run node order-routing.cjs. It uses Node's built-in strict assertion module.

const assert = require('node:assert/strict');

function reference(value) {
  if (typeof value !== 'string' || value.length === 0 ||
      value.trim() !== value) {
    throw new TypeError('Expected an exact nonblank string reference');
  }
  return value;
}

function createRouter() {
  const stores = new Map();
  return {
    add(store, order, dispatch) {
      store = reference(store);
      order = reference(order);
      dispatch = reference(dispatch);
      let orders = stores.get(store);
      if (orders?.has(order)) throw new Error('Order already registered');
      if (!orders) {
        orders = new Map();
        stores.set(store, orders);
      }
      orders.set(order, dispatch);
    },
    resolve(store, order) {
      store = reference(store);
      order = reference(order);
      return stores.get(store)?.get(order);
    }
  };
}

const joined = (store, order) => `${store}|${order}`;
assert.equal(joined('shop|north', '00123'),
             joined('shop', 'north|00123')); // Demonstrate the bad key.

const router = createRouter();
router.add('north', '00123', 'dispatch-A');
router.add('south', '00123', 'dispatch-B');
router.add('north', '123', 'dispatch-C');
router.add('shop|north', '00123', 'dispatch-D');
router.add('shop', 'north|00123', 'dispatch-E');

for (const [store, order, expected] of [
  ['north', '00123', 'dispatch-A'],
  ['south', '00123', 'dispatch-B'],
  ['north', '123', 'dispatch-C'],
  ['shop|north', '00123', 'dispatch-D'],
  ['shop', 'north|00123', 'dispatch-E']
]) {
  assert.equal(router.resolve(store, order), expected);
}
assert.equal(router.resolve('unknown', '00123'), undefined);
assert.throws(() => router.add('north', '00123', 'replacement'));
assert.equal(router.resolve('north', '00123'), 'dispatch-A');
assert.throws(() => router.resolve('north', 123), TypeError);
assert.throws(() => router.resolve('north', ' 00123'), TypeError);
console.log('All order-routing checks passed');
Enter fullscreen mode Exit fullscreen mode

The five lookups exercise distinct orders, including the pair that the joined key would merge. The duplicate registration check also proves that a second write cannot silently replace the dispatch reference already associated with that pair. It does not implement a retry policy; a real adapter needs an explicit rule for a repeated request with the same or conflicting content.

Preserve identity at the boundaries

The store value should be the stable, trusted source-account identity established by the integration. It should not come from an unchecked display name or from a caller claiming another seller's identity. Routing separation does not supply authentication or authorization.

The example rejects surrounding whitespace rather than silently trimming it. That is an example contract. If an upstream system defines normalization or case folding, apply its documented rule consistently at intake and lookup, and test the consequences. A CSV spreadsheet step that has already turned 00123 into 123 cannot be repaired by choosing a better map afterward.

This router is memory-only and loses all entries when the process stops. It provides no transaction, concurrent-worker coordination or durable uniqueness. A persistent implementation needs to preserve the same source-account and order-reference pair in storage, with the appropriate uniqueness enforcement and access checks.

Before connecting live orders, send matching visible references from two test stores and return a different dispatch reference to each. Then test a leading-zero reference, an unknown pair and a repeated registration. Inspect the destination order as well as the adapter's success response. The practical outcome to verify is that each store receives information for its own order.

Two mailing parcels with different reference cards beside a laptop

Keeping two order records distinct at dispatch. Illustrative scene.

Top comments (0)