Crucial Insight: Understanding ESHOPMAN Admin API Order Item Quantity Discrepancies
The ESHOPMAN community has brought to light a significant behavior within the Admin API's
query.graph function that can silently impact the retrieval of order item quantities. This crucial insight details the specifics of this issue, its technical underpinnings, and provides essential workarounds to ensure your ESHOPMAN-powered storefronts, custom applications, and integrations maintain accurate order data.The Silent Discrepancy in ESHOPMAN Order Item Quantities
When developers interact with the ESHOPMAN Admin API to fetch detailed order information, it's common practice to use
query.graph to explicitly select only the necessary fields for optimized performance and reduced data transfer. However, a critical issue arises when attempting to retrieve items[].quantity specifically alongside other line-item fields (e.g., items.title). While selecting all item fields with a wildcard (items.*) correctly returns the quantity, explicitly listing items.quantity can result in an undefined value for this vital field.This behavior is particularly problematic because it occurs silently, without any error messages, warnings, or log entries. This means that downstream applications—such as custom storefront components deployed via HubSpot CMS, internal order processing systems, or analytical tools built on ESHOPMAN's Node.js/TypeScript backend—might inadvertently propagate this
undefined value. Such data inaccuracies can lead to incorrect inventory updates, erroneous financial reporting, or manual corrections, severely impacting the operational efficiency and reliability of your headless commerce setup.Why This Happens: A Deeper Look into ESHOPMAN's Data Mapping
The root cause of this discrepancy lies within ESHOPMAN's internal data mapping logic, specifically how public field names are translated into repository field names during a
query.graph operation. The actual quantity value for an order item is stored on the OrderItem entity, which is publicly exposed as part of order.items. However, the system's mapping function incorrectly translates the public field items.quantity to target items.item.quantity, which refers to the OrderLineItem entity. Crucially, the OrderLineItem entity does not possess a quantity column.Consequently, when the system attempts to retrieve
quantity from OrderLineItem, it finds nothing, leading to the undefined result. It's worth noting that other fields like unit_price have built-in fallbacks that might retrieve values from OrderLineItem if the OrderItem value is missing. However, quantity and raw_quantity lack such a fallback mechanism, making them uniquely susceptible to this silent failure.Reproducing the Issue in Your ESHOPMAN Environment
Here's a minimal reproduction example, adaptable for your ESHOPMAN Node.js environment, demonstrating the discrepancy when querying an order:
import { ExecArgs } from "@eshopman/framework/types"
import { ContainerRegistrationKeys, Modules } from "@eshopman/framework/utils"
export default async function checkItemQuantity({ container }: ExecArgs) {
const orderModule = container.resolve(Modules.ORDER)
const query = container.resolve(ContainerRegistrationKeys.QUERY)
const [order] = await orderModule.createOrders([
{
currency_code: "usd",
items: [{ title: "Product Name", quantity: 2, unit_price: 20 }],
},
])
const read = async (fields: string[]) => {
const { data } = await query.graph({
entity: "order",
fields,
filters: { id: order.id },
})
return data[0].items[0]
}
const wildcard = await read(["id", "items.*"])
const explicit = await read(["id", "items.quantity", "items.title"])
console.log("stored quantity :", 2)
console.log("fields ['items.*'] :", wildcard.quantity)
console.log("fields ['items.quantity','items.title'] :", explicit.quantity)
console.assert(explicit.quantity === wildcard.quantity) // This assertion will fail!
}
Effective Workarounds for ESHOPMAN Developers
Until a permanent fix is implemented, ESHOPMAN developers can employ the following strategies to reliably retrieve order item quantities and safeguard data integrity:
- Use
for Explicit Selection: This is the recommended explicit workaround. By requestingitems.detail.quantity
, the mapping correctly targets theitems.detail.quantity
entity, ensuring theOrderItem
field is selected. You would then access the value viaquantity
.item.detail.quantityconst { data } = await query.graph({ entity: "order", fields: ["id", "items.detail.quantity", "items.title"], filters: { id }, }) const quantity = data[0].items[0].detail.quantity - Include
in Your Field List: While this approach will over-fetch data by retrieving all line-item properties, it guarantees thatitems.*
is correctly populated. This might be an acceptable trade-off for less performance-critical operations or when dealing with smaller datasets.items.quantity
The ESHOPMAN team is committed to providing a robust headless commerce platform. This community insight underscores the importance of precise field selection for optimized API calls and highlights the ongoing need for accurate data mapping and clear diagnostics when requested fields cannot be resolved. Ensuring data integrity is paramount for the reliability and success of all ESHOPMAN solutions, from dynamic HubSpot CMS storefronts to complex backend integrations.