Bare Necessities
Preorder & Backorder Sync / Architecture & Scenarios
Executive Shareout & Architecture

How a preorder becomes a real order

Four scenarios covering how Movex, Barrett, Techsera, Shopify, and STOQ stay in sync — from a purchase order landing in the ERP to customer delivery.

1
Movex
ERP
2
Barrett
Warehouse / Physical
3
Techsera
Integration / Bridge
4
Shopify
Storefront & Holds
5
STOQ
Preorder Limits
Scenario 01 — The Metafield & The Flow

MoveX recalculates and pushes a new snapshot

TRIGGER: any state change MoveX cares about — a new PO created, stock received at Barrett, or a PO cancelled/reduced.
1
MOVEX
MoveX (via QlikView) recalculates available_to_sell_qty internally in response to any of: a new PO created, stock received at Barrett, or a PO cancelled/reduced. There is no per-PO event — MoveX pushes the fully recalculated snapshot total (available to sell qty for that SKU, landing in the next 4 weeks) every time.
2
TECHSERA
Relays this number, unchanged, to the variant's backorder.available_to_sell_qty metafield (JSON) via metafieldsSet. Techsera does not calculate this figure — it only relays what MoveX already computed. This is the same single metafield used for every trigger; there is no separate "incoming PO" metafield.
Shopify — metafieldsSet Mutation Metafield Def ID: TBD (Pending Creation)
View JSON GraphQL Payload (available_to_sell_qty)
# Definition ID: TBD (Pending creation in Shopify — ProductVariant)
mutation SetAvailableToSellQty($metafields: [MetafieldsSetInput!]!) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      id
      namespace
      key
      value
      type
    }
    userErrors {
      field
      message
      code
    }
  }
}

# GraphQL Variables (Type: json with timestamp uniqueness):
{
  "metafields": [
    {
      "ownerId": "gid://shopify/ProductVariant/{{variant_id}}",
      "namespace": "backorder",
      "key": "available_to_sell_qty",
      "value": "{\"last_updated\":\"2026-09-15T10:32:00Z\",\"available_to_sell_qty\":300}",
      "type": "json"
    }
  ]
}
3
SHOPIFY FLOW (THE FLOW)
Triggered when backorder.available_to_sell_qty changes (via Workflow Trigger Extensions app). Extracts available_to_sell_qty from the JSON payload and reads native committed — the same single Flow regardless of which of the three MoveX triggers caused the push.
4
STOQ
Current preorder_count is read for that variant from STOQ.
STOQ — Read Variant Limit API
5
STOQ
New absolute limit is written: new_limit = preorder_count + available_to_sell_qty − committed — the same universal formula used for every trigger.
STOQ — Update Variant Settings PATCH
Interactive Math Simulator Edit numbers
Preorder Count
Available to Sell Qty
Committed
180
New STOQ Limit
Why JSON? Snapshot Uniqueness

The trigger compares against a stored snapshot and only fires when the value differs from the last recorded one — a plain repeated number would risk being silently dropped, which is why the JSON value includes a last_updated timestamp or execution ID (confirmed with Workflow Trigger Extensions support). There's no per-PO event to key off anymore, just a periodic recalculated push.

⚠️ Baseline snapshot note: The trigger needs an existing snapshot to compare against. The very first write after enabling the trigger can be absorbed into that baseline instead of firing — a one-time initial setup consideration for testing.

Scenario 02 — The Metafield & The Flow

Stock arrives, covers preorders & leaves surplus

TRIGGER: Physical stock arrives at Barrett and exceeds held preorders (leaves real surplus inventory).
1
BARRETT
Receives physical shipment into warehouse storage.
2
TECHSERA
1) Pushes received inventory delta to Shopify via inventoryAdjustQuantities.
2) MoveX (via QlikView) recalculates the variant's available to sell qty landing in the next 4 weeks internally and pushes the fully recalculated snapshot total. Techsera relays that number, unchanged, to Metafield 2: backorder.available_to_sell_qty (JSON) via metafieldsSet. Techsera does not calculate this figure — it only relays what MoveX already computed.
Known Limitation: Hourly Refresh & Oversell Risk

⚠️ MoveX currently recalculates and pushes this value on an hourly schedule (not real-time transactional), meaning available-to-sell data can be stale for up to an hour after a state change. The team has explicitly accepted this as a known short-term risk, with plans to reduce the refresh interval to 15–30 minutes. During that window, STOQ's limit could be temporarily overstated, creating a small oversell risk.

Shopify — inventoryAdjustQuantities Mutation Metafield Def ID: TBD (Pending Creation)
View JSON GraphQL Payload (available_to_sell_qty)
# Definition ID: TBD (Pending creation in Shopify — ProductVariant)
{
  "metafields": [
    {
      "ownerId": "gid://shopify/ProductVariant/{{variant_id}}",
      "namespace": "backorder",
      "key": "available_to_sell_qty",
      "value": "{\"last_updated\":\"2026-09-15T10:32:00Z\",\"available_to_sell_qty\":300}",
      "type": "json"
    }
  ]
}
3
SHOPIFY
Available turns positive natively. Committed does NOT drop automatically — orders stay on hold until explicitly released.
4
SHOPIFY FLOW (HOLDS)
Triggered by inventory change (prior <= 0 and current > 0). Filters specifically by heldByApp.id (STOQ holds only) and releases them.
Shopify — fulfillmentOrderReleaseHold Mutation
Clarification — release order is FIFO, handled by our Flow, not by native Shopify/STOQ behavior: Neither Shopify nor STOQ automatically enforces oldest-first release on their own; confirmed directly with STOQ support that no native FIFO mechanism exists. To handle this, our own Shopify Flow orders held fulfillment orders by creation date and releases holds accordingly, based on available inventory. This automates the FIFO logic. What remains manual is only the physical fulfillment step (picking, packing, shipping) once a hold is released, not the decision of which orders get released first.
5
SHOPIFY FLOW (FLOW 2 — RECALCULATE)
Triggered by backorder.available_to_sell_qty JSON update:
• Extracts available_to_sell_qty from payload and reads native committed.
• Reads preorder_count from STOQ.
• Calculates: new_limit = preorder_count + available_to_sell_qty − committed.
• Writes new_limit to STOQ via PATCH (equivalent to count 0, limit = available_to_sell_qty − committed).
6
STOQ (DISPLAY)
Flips storefront CTA from "Preorder" to "Add to Cart" automatically once available > 0.
Surplus Recalculation Example Confirmed Model
• Initial: Limit = 180, Count = 50 (50 preorders held)
• Arrival: PO of 100 units arrives (covers 50, leaves 50 surplus)
• Remaining Committed: 0 waiting
• Available to Sell Qty: 80 (MoveX's recalculated snapshot for the next 4 weeks)
• Formula: 50 (count) + 80 (available_to_sell_qty) − 0 (committed) = 130
• Open Preorder Spots: 130 − 50 = 80 (excludes 50 surplus units now selling as regular stock).
PRECONDITION: Split Fulfillments must be enabled on the STOQ offer so multi-line orders can release this variant independently without prematurely releasing other items on backorder.
Metafield 2 & Snapshot Uniqueness

The unique identifier in the JSON value is now a timestamp (last_updated) or execution ID from MoveX/Techsera's periodic push, not a po_number/shipment_id pair — there's no per-PO event anymore, just a periodic recalculated snapshot. This still guarantees each write is unique, preventing the trigger from silently dropping consecutive identical totals.

⚠️ Baseline snapshot note: As with any Workflow Trigger Extension, the very first write after enabling the trigger establishes the comparison baseline snapshot.

Scenario 03 — The Metafield & The Flow

Stock arrives & is fully absorbed (no surplus)

TRIGGER: Partial shipment arrives at Barrett and is fully absorbed by held preorders (units < committed orders).
1
BARRETT
Receives fewer physical units than the currently committed preorder volume.
2
TECHSERA
1) Pushes received quantity delta to Shopify via inventoryAdjustQuantities.
2) MoveX (via QlikView) recalculates the internal available-to-sell snapshot in response to the receipt at Barrett and pushes the new total. Techsera relays it, unchanged, to Metafield 2: backorder.available_to_sell_qty (JSON).
Shopify — metafieldsSet Mutation Metafield Def ID: TBD (Pending Creation)
View JSON GraphQL Payload (available_to_sell_qty)
# Definition ID: TBD (Pending creation in Shopify — ProductVariant)
{
  "metafields": [
    {
      "ownerId": "gid://shopify/ProductVariant/{{variant_id}}",
      "namespace": "backorder",
      "key": "available_to_sell_qty",
      "value": "{\"last_updated\":\"2026-09-15T11:05:00Z\",\"available_to_sell_qty\":40}",
      "type": "json"
    }
  ]
}
3
SHOPIFY
Available remains 0 because all incoming units are allocated to existing held orders.
4
SHOPIFY FLOW (HOLDS)
Releases fulfillment holds for exactly the number of orders covered by the arrived batch (filtered by heldByApp.id). Pending orders remain held.
Clarification — release order is FIFO, handled by our Flow, not by native Shopify/STOQ behavior: Neither Shopify nor STOQ automatically enforces oldest-first release on their own; confirmed directly with STOQ support that no native FIFO mechanism exists. To handle this, our own Shopify Flow orders held fulfillment orders by creation date and releases holds accordingly, based on available inventory. This automates the FIFO logic. What remains manual is only the physical fulfillment step (picking, packing, shipping) once a hold is released, not the decision of which orders get released first.
5
SHOPIFY FLOW (FLOW 2 — RECALCULATE)
Extracts available_to_sell_qty from JSON and runs the universal formula: new_limit = preorder_count + available_to_sell_qty − committed.
Because all arrived units were absorbed by waiting preorders, remaining open spots accurately reflect unarrived supply without overselling.
6
STOQ (DISPLAY)
Variant correctly stays in Preorder mode on storefront because available inventory remains 0.
Partial Split Simulator Edit numbers
Committed
Units Arrived
10
Still Pending
Universal Formula Consistency

The Flow executes the exact same mathematical formula (preorder_count + available_to_sell_qty − committed) on every trigger — new PO, receipt, or cancellation.

*Uses JSON with a last_updated timestamp to guarantee trigger change-detection on every recalculated push.

Scenario 04 — Resolved

PO registered on an in-stock item

STATUS: RESOLVED — Fully covered by the unified model (limit sits inert while stock > 0).
1
MOVEX
PO is created for a variant that currently has positive available inventory in Shopify. MoveX recalculates its internal available-to-sell snapshot to include it, same as any other trigger.
2
TECHSERA
Relays MoveX's recalculated snapshot, unchanged, to backorder.available_to_sell_qty metafield (JSON) via Shopify GraphQL (metafieldsSet) — the same single metafield used for every trigger.
3
SHOPIFY FLOW (THE FLOW)
Triggered via Workflow Trigger Extensions, calls STOQ API to update the variant limit in the background using the same universal formula.
4
STOQ (INERT)
Limit is updated in background. The storefront button stays "Add to Cart" while stock > 0 — zero customer UX impact.
5
STOQ (ACTIVATION)
When regular sales deplete stock to 0, STOQ auto-switches to Preorder mode with the limit already pre-staged and accurate!
Unified Model Handles Both Sequences

• If stock sells out first: Transitions seamlessly into preorder with the staged limit ready.
• If PO arrives first: the same Flow (triggered via JSON available_to_sell_qty) recalculates upon receipt, stripping arrived units and preventing inflation.

No Special Case Needed
The general formula automatically accommodates both orderings of events without custom conditional logic.
Comparison Matrix

Summary of the 4 Scenarios

A single JSON metafield (available_to_sell_qty) feeds one unified Flow, fed by MoveX's recalculated snapshot regardless of which of the three triggers caused the push.

SCENARIO 1 PO Arrives →

Metafield: available_to_sell_qty (JSON)

New PO in Movex → MoveX recalculates its internal snapshot, Techsera relays {last_updated, available_to_sell_qty} → the Flow writes preorder_count + available_to_sell_qty − committed.

The Flow: Unified Recalculation
SCENARIO 2 Surplus Stock →

Metafield: available_to_sell_qty (JSON)

Barrett arrival → MoveX recalculates its internal snapshot, Techsera relays {last_updated, available_to_sell_qty} → the Flow recalculates: count + available_to_sell_qty − committed.

The Flow: Surplus Recalculation
SCENARIO 3 Partial Stock →

Metafield: available_to_sell_qty (JSON)

Partial arrival → MoveX recalculates its internal snapshot, Techsera relays {last_updated, available_to_sell_qty} → the Flow runs the universal formula; all units absorbed with 0 surplus.

The Flow: Absorbed Recalculation
SCENARIO 4 In-Stock PO →

Metafield: available_to_sell_qty (JSON)

PO on in-stock item → the Flow stages the limit in STOQ in the background (sits inert until stock reaches 0).

The Flow: Pre-staged Limit (Resolved)
Interactive Sandbox

Live Preorder Event Simulator

Simulate real-world PO creations, customer preorders, and inventory arrivals to watch the 5 core system variables and Flows react in real time.

Storefront: PREORDER MODE (CTA: Preorder)
STOQ Limit
0
STOQ preorder_max_count (via API)
Shopify Available
0
Shopify native
STOQ Preorders
0
STOQ preorder_count (via API)
Shopify Committed
0
Shopify native
Available to Sell Qty
0
backorder.available_to_sell_qty (Shopify metafield)
⚠️ available_to_sell_qty is a fully recalculated snapshot from MoveX (via QlikView), not a running total Techsera assembles from individual POs. MoveX currently recalculates and pushes this value on an hourly schedule (not real-time transactional), meaning available-to-sell data can be stale for up to an hour after a state change. This is an accepted known short-term risk, with plans to reduce the refresh interval to 15–30 minutes — during that window, STOQ's limit could be temporarily overstated, creating a small oversell risk.
Demo Scenarios:
# Event Storefront CTA Limit Available Count Committed Avail-to-Sell System Reaction & Formula Calculation
Editing Mode Active

Slide Deck Overview