shopify-admin-dead-stock-identifier

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Purpose

用途

Identifies SKUs that have positive inventory on hand but have not sold any units in a configurable lookback window. Dead stock ties up capital, warehouse space, and carrying costs. Read-only — no mutations. Provides the data foundation for a markdown or clearance decision.
识别现有库存为正,但在可配置的回溯窗口期内没有售出任何单位的SKU。滞销库存会占用资金、仓库空间并产生持有成本。本工具为只读模式——无任何数据修改操作,为降价或清仓决策提供数据基础。

Prerequisites

前置条件

  • Authenticated Shopify CLI session:
    shopify store auth --store <domain> --scopes read_products,read_orders,read_inventory
  • API scopes:
    read_products
    ,
    read_orders
    ,
    read_inventory
  • 已完成身份验证的Shopify CLI会话:
    shopify store auth --store <domain> --scopes read_products,read_orders,read_inventory
  • API权限:
    read_products
    read_orders
    read_inventory

Parameters

参数

ParameterTypeRequiredDefaultDescription
storestringyesStore domain (e.g., mystore.myshopify.com)
days_backintegerno90Sales lookback window — SKUs with no sales in this period are flagged
min_quantityintegerno1Minimum on-hand quantity to include (exclude truly zero-stock)
vendor_filterstringnoOptional vendor to scope the audit
formatstringnohumanOutput format:
human
or
json
参数类型必填默认值描述
storestring店铺域名(例如 mystore.myshopify.com)
days_backinteger90销量回溯窗口期——此时间段内无销量的SKU会被标记
min_quantityinteger1纳入统计的最低库存数量(排除实际库存为0的商品)
vendor_filterstring可选参数,限定审计范围为指定供应商
formatstringhuman输出格式:
human
(可读格式)或
json

Safety

安全说明

ℹ️ Read-only skill — no mutations are executed. Safe to run at any time.
ℹ️ 只读技能——不会执行任何数据修改操作,可随时安全运行。

Workflow Steps

工作流步骤

  1. OPERATION:
    productVariants
    — query Inputs:
    first: 250
    ,
    query: <vendor_filter if set>
    , select
    sku
    ,
    inventoryQuantity
    ,
    inventoryItem { id }
    , pagination cursor Expected output: All variants with stock levels; paginate until
    hasNextPage: false
  2. Filter to variants with
    inventoryQuantity >= min_quantity
  3. OPERATION:
    orders
    — query Inputs:
    query: "created_at:>='<NOW - days_back days>'"
    ,
    first: 250
    , select
    lineItems { variant { id }, quantity }
    , pagination cursor Expected output: All line items sold in the window to build a "sold variant IDs" set
  4. OPERATION:
    inventoryItems
    — query Inputs: Batch of
    inventoryItemIds
    for stocked variants Expected output: Inventory item cost data for dead stock value calculation
  5. Cross-reference: variants in step 2 that are NOT in the sold set from step 3 → dead stock
  1. 操作:
    productVariants
    — 查询 输入:
    first: 250
    query: <如设置了供应商筛选则传入>
    ,选择
    sku
    inventoryQuantity
    inventoryItem { id }
    、分页游标 预期输出: 所有带库存水平的变体;分页查询直到
    hasNextPage: false
  2. 筛选出
    inventoryQuantity >= min_quantity
    的变体
  3. 操作:
    orders
    — 查询 输入:
    query: "created_at:>='<当前时间 - days_back 天>'"
    first: 250
    ,选择
    lineItems { variant { id }, quantity }
    、分页游标 预期输出: 窗口期内所有售出的订单项,用于构建「已售变体ID」集合
  4. 操作:
    inventoryItems
    — 查询 输入: 有库存变体的
    inventoryItemIds
    批量列表 预期输出: 库存商品成本数据,用于计算滞销库存价值
  5. 交叉比对:步骤2中不在步骤3已售集合内的变体 → 即为滞销库存

GraphQL Operations

GraphQL 操作

graphql
undefined
graphql
undefined

productVariants:query — validated against api_version 2025-01

productVariants:query — 已针对 api_version 2025-01 验证

query VariantsWithStock($query: String, $after: String) { productVariants(first: 250, after: $after, query: $query) { edges { node { id sku inventoryQuantity product { id title vendor status } inventoryItem { id } } } pageInfo { hasNextPage endCursor } } }

```graphql
query VariantsWithStock($query: String, $after: String) { productVariants(first: 250, after: $after, query: $query) { edges { node { id sku inventoryQuantity product { id title vendor status } inventoryItem { id } } } pageInfo { hasNextPage endCursor } } }

```graphql

orders:query — validated against api_version 2025-01

orders:query — 已针对 api_version 2025-01 验证

query OrderLineItemsInPeriod($query: String!, $after: String) { orders(first: 250, after: $after, query: $query) { edges { node { lineItems(first: 50) { edges { node { quantity variant { id } } } } } } pageInfo { hasNextPage endCursor } } }

```graphql
query OrderLineItemsInPeriod($query: String!, $after: String) { orders(first: 250, after: $after, query: $query) { edges { node { lineItems(first: 50) { edges { node { quantity variant { id } } } } } } pageInfo { hasNextPage endCursor } } }

```graphql

inventoryItems:query — validated against api_version 2025-01

inventoryItems:query — 已针对 api_version 2025-01 验证

query InventoryItemCosts($ids: [ID!]!) { nodes(ids: $ids) { ... on InventoryItem { id unitCost { amount currencyCode } tracked } } }
undefined
query InventoryItemCosts($ids: [ID!]!) { nodes(ids: $ids) { ... on InventoryItem { id unitCost { amount currencyCode } tracked } } }
undefined

Session Tracking

会话追踪

Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║  SKILL: Dead Stock Identifier                ║
║  Store: <store domain>                       ║
║  Started: <YYYY-MM-DD HH:MM UTC>             ║
╚══════════════════════════════════════════════╝
After each step, emit:
[N/TOTAL] <QUERY|MUTATION>  <OperationName>
          → Params: <brief summary of key inputs>
          → Result: <count or outcome>
On completion, emit:
For
format: human
(default):
══════════════════════════════════════════════
DEAD STOCK REPORT  (no sales in <days_back> days)
  SKUs with stock:       <n>
  SKUs with zero sales:  <n>  (<pct>%)
  Est. dead stock value: $<amount>

  Top dead stock by value:
    "<product>"  SKU: <sku>  Qty: <n>  Value: $<n>
  Output: dead_stock_<date>.csv
══════════════════════════════════════════════
For
format: json
, emit:
json
{
  "skill": "dead-stock-identifier",
  "store": "<domain>",
  "period_days": 90,
  "stocked_skus": 0,
  "dead_stock_skus": 0,
  "dead_stock_pct": 0,
  "estimated_value": 0,
  "currency": "USD",
  "output_file": "dead_stock_<date>.csv"
}
Claude 必须在每个阶段输出以下内容,此为强制要求。
启动时输出:
╔══════════════════════════════════════════════╗
║  SKILL: Dead Stock Identifier                ║
║  Store: <store domain>                       ║
║  Started: <YYYY-MM-DD HH:MM UTC>             ║
╚══════════════════════════════════════════════╝
每步完成后输出:
[N/TOTAL] <QUERY|MUTATION>  <OperationName>
          → Params: <brief summary of key inputs>
          → Result: <count or outcome>
完成时输出:
format: human
(默认格式)时输出:
══════════════════════════════════════════════
DEAD STOCK REPORT  (no sales in <days_back> days)
  SKUs with stock:       <n>
  SKUs with zero sales:  <n>  (<pct>%)
  Est. dead stock value: $<amount>

  Top dead stock by value:
    "<product>"  SKU: <sku>  Qty: <n>  Value: $<n>
  Output: dead_stock_<date>.csv
══════════════════════════════════════════════
format: json
时输出:
json
{
  "skill": "dead-stock-identifier",
  "store": "<domain>",
  "period_days": 90,
  "stocked_skus": 0,
  "dead_stock_skus": 0,
  "dead_stock_pct": 0,
  "estimated_value": 0,
  "currency": "USD",
  "output_file": "dead_stock_<date>.csv"
}

Output Format

输出格式

CSV file
dead_stock_<YYYY-MM-DD>.csv
with columns:
variant_id
,
sku
,
product_title
,
vendor
,
quantity_on_hand
,
days_since_last_sale
,
unit_cost
,
total_cost_value
CSV 文件
dead_stock_<YYYY-MM-DD>.csv
,包含以下列:
variant_id
sku
product_title
vendor
quantity_on_hand
days_since_last_sale
unit_cost
total_cost_value

Error Handling

错误处理

ErrorCauseRecovery
THROTTLED
API rate limit exceededWait 2 seconds, retry up to 3 times
No orders in windowNew store or very slow periodAll stocked SKUs will be flagged — expected
Variant without inventory itemBundle or virtual productSkip inventory cost, include in list
错误原因解决方案
THROTTLED
API 触发限流等待2秒,最多重试3次
窗口期内无订单新店铺或销量非常低迷的时段所有有库存的SKU都会被标记,属于预期行为
变体无对应库存条目组合商品或虚拟商品跳过库存成本计算,仍纳入列表

Best Practices

最佳实践

  • Use
    days_back: 90
    for seasonal products;
    days_back: 180
    or
    days_back: 365
    for evergreen catalog.
  • Sort by
    total_cost_value
    descending to prioritize markdown decisions by capital impact.
  • Cross-reference with
    stock-velocity-report
    to distinguish truly dead stock from slow movers that still sell occasionally.
  • Use results as input for a discount campaign: apply a markdown tag using
    product-tag-bulk-update
    and then create a clearance collection.
  • 季节性商品使用
    days_back: 90
    ;常青款商品使用
    days_back: 180
    days_back: 365
  • total_cost_value
    降序排序,可根据资金占用优先级制定降价决策。
  • stock-velocity-report
    交叉比对,区分完全滞销的库存和仍有零星销量的慢动销商品。
  • 可将结果作为折扣活动的输入:使用
    product-tag-bulk-update
    批量添加降价标签,再创建清仓商品集合。