mcpField
L
low-stock-alerts

low-stock-alerts

github.com/finsilabsその他6083 回インストール6 日前に更新
リポジトリ

low-stock-alerts について

ECの在庫低下アラートを設定するためのスキルです。標準通知、拡張アプリ、カスタムのバックグラウンドジョブから方式を選び、発注点や仕入先通知、アラート管理を扱います。

主な機能

  1. 01Shopify、WooCommerce、BigCommerce の方式比較
  2. 02全体・商品別の在庫しきい値設定
  3. 03販売速度と納期に基づく発注点計算
  4. 04仕入先への通知フロー設定
  5. 05重複通知と季節別しきい値への対応

活用シーン

  1. 01予期しない欠品による販売機会の損失削減
  2. 02手動の在庫確認からアラートへの移行
  3. 03仕入先の納期を考慮した発注計画
  4. 04複数倉庫の商品に拠点別アラートを設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill low-stock-alerts

インストール後、Claude Code で/low-stock-alertsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

tile.json
evals/alert-data-model-and-deduplication-logic/
criteria.json
task.md
evals/dynamic-reorder-point-and-demand-forecas/
criteria.json
task.md
evals/supplier-notifications-and-alert-managem/
criteria.json
task.md

詳細

在庫僅少アラート

概要

在庫僅少アラートは、在庫がしきい値を下回ったときに通知し、在庫切れになる前に再注文できるようにします。主要なプラットフォームには、いずれもこの機能が組み込まれています。Shopify、WooCommerce、BigCommerce はすべて、在庫が設定したレベルを下回るとメールで通知します。需要に応じたしきい値、サプライヤーへの発注書(PO)の自動化、Slack でのチーム通知など、より高度なニーズには、専用アプリを使うことでカスタムコードを追加せずに機能を拡張できます。

このスキルを使用する状況

  • 商品が予期せず在庫切れになり、販売機会を逃している場合
  • 現在の在庫管理ワークフローが、自動アラートではなく手動確認に依存している場合
  • 固定のしきい値ではなく、需要に応じた再注文ポイントを設定したい場合
  • 再注文のタイミングにサプライヤーのリードタイムを考慮する必要がある場合

基本手順

ステップ 1:プラットフォームを特定し、適切なツールを選ぶ
プラットフォーム組み込みアラート推奨拡張機能
Shopify在庫がゼロになると Shopify がメール通知を送信しますが、しきい値の制御は非常に限られていますしきい値の設定と発注書の自動化には Stocky(無料、Shopify 提供)、顧客への通知には Back in Stock
WooCommerce在庫が設定済みの在庫僅少しきい値を下回ると、WooCommerce がストア管理者にメールを送信します商品ごとのしきい値、サプライヤーへのメール、再注文の提案には ATUM Inventory Management
BigCommerce商品ごとに、しきい値を設定できる在庫僅少通知が組み込まれていますロケーションごとのアラートには Multi-Location Inventory アプリ
カスタム/ヘッドレス再注文ポイントと在庫レベルを照合するバックグラウンドジョブを構築しますプラットフォームに標準のアラート機能がない場合や、サプライヤーへのメールを自動化する必要がある場合に必要です

ステップ 2:プラットフォーム固有の設定

Shopify

組み込みの在庫僅少通知:

Shopify は在庫がゼロになるとストア管理者にメールを送信しますが、標準機能ではしきい値を設定できません。

  1. 設定 → 通知 → スタッフ向け注文通知までスクロールを開きます
  2. 管理者のメールアドレスが設定されていることを確認します。在庫が 0 になると、Shopify がこのアドレスに通知します

Stocky でバリエーションごとのしきい値を設定する:

  1. Shopify App Store から Stocky をインストールします(無料)
  2. Stocky を開き、商品に移動します
  3. 商品ごとに 再注文ポイント(アラートを発生させる在庫レベル)を設定します
  4. 再注文数量(アラート発生時に注文する数量)を設定します
  5. Stocky は再注文ポイントを下回った商品をダッシュボードに表示し、下書きの発注書を自動生成できます

顧客への「再入荷」通知:

  • App Store から Back In Stock(有料)または Klaviyo をインストールします
  • これらのアプリは、在庫切れの商品に「入荷したら通知」ボタンを表示します
  • 在庫が補充されると、通知を希望した顧客に自動でメールを送信します

WooCommerce

グローバルな在庫低下しきい値を設定する:

  1. WooCommerce → 設定 → 商品 → 在庫に移動します
  2. 在庫低下しきい値に値を入力します(例:10)
  3. 通知先メールアドレスに通知用メールアドレスを入力します。複数のメールアドレスはカンマで区切ります
  4. 商品の在庫数がこのしきい値以下になると、WooCommerce からメールが送信されます

商品ごとにしきい値を設定する:

  1. WooCommerce → 商品 → [商品] → 在庫タブに移動します
  2. **在庫を管理しますか?**を有効にします
  3. この商品専用の在庫低下しきい値を入力します(グローバル設定より優先されます)

ATUM による高度なアラート:

  1. ATUM Inventory Management for WooCommerce(無料)をインストールします
  2. ATUM のダッシュボードでは、発注点以下のすべての商品を一覧で確認できます
  3. 商品ごとの発注点はATUM → 商品設定で設定します
  4. 商品の再発注が必要になったとき、ATUM から仕入先に直接メールを送信することもできます(有料機能)

需要に基づくしきい値:

  • Inventory Planner(Shopify/WooCommerce)をインストールすると、販売速度に基づいた再発注の提案を受けられます
  • Inventory Planner は販売履歴を分析し、リードタイム × 1 日あたりの販売速度 + 安全在庫に基づいて発注点を提案します

BigCommerce

商品ごとに在庫低下しきい値を設定する:

  1. 商品 → [商品] → 在庫タブに移動します
  2. 在庫低下レベルのフィールドに値を設定します
  3. 在庫数がこのしきい値を下回ると、BigCommerce からストア管理者に自動メール通知が送信されます

アラートの受信者を設定する:

  1. ストア設定 → ストア設定 → その他に移動します
  2. 在庫低下メールアドレスに購買チームのメールアドレスを設定します

ロケーションごとのアラートを設定する場合:

  • Multi-Location Inventoryアプリをインストールします
  • ロケーションごとにしきい値を設定します。同じ SKU を複数の倉庫で保管している場合に便利です

カスタム/ヘッドレス

カスタムプラットフォームでは、設定済みの発注点に照らして在庫レベルを確認するバックグラウンドジョブを実装します:

// jobs/checkStockLevels.ts — run every 15-30 minutes via cron
export async function checkStockLevels() {
  const levels = await db.inventoryLevels.findMany({
    include: { reorderConfig: true, variant: { include: { product: true } }, location: true },
    where: { reorderConfig: { isNot: null } },
  });

  const newAlerts = [];

  for (const level of levels) {
    const config = level.reorderConfig!;
    const available = level.onHand - level.reserved;

    // Dynamic reorder point based on sales velocity and lead time
    let reorderPoint = config.reorderPoint;
    if (config.useDynamicReorderPoint) {
      const velocity = await calculateDailySalesVelocity(level.variantId, 30); // 30-day rolling average
      reorderPoint = Math.ceil(velocity * config.leadTimeDays * 1.2); // 20% safety stock buffer
    }

    const alertType = available === 0 ? 'out_of_stock' : available <= reorderPoint ? 'low_stock' : null;
    if (!alertType) continue;

    // Only create a new alert if the previous one is resolved
    const existingAlert = await db.stockAlerts.findFirst({
      where: { variantId: level.variantId, locationId: level.locationId, alertType, resolvedAt: null },
    });

    if (!existingAlert) {
      newAlerts.push({ level, config, available, reorderPoint, alertType });
      await db.stockAlerts.create({ data: {
        variantId: level.variantId, locationId: level.locationId,
        alertType, triggeredAt: new Date(), availableAtTrigger: available,
      }});
    }
  }

  if (newAlerts.length > 0) await sendAlertNotifications(newAlerts);
}

// Calculate daily sales velocity from order history
async function calculateDailySalesVelocity(variantId: string, windowDays: number) {
  const since = new Date(Date.now() - windowDays * 86400000);
  const result = await db.orderLineItems.aggregate({
    where: { variantId, order: { createdAt: { gte: since }, status: { in: ['completed', 'shipped'] } } },
    _sum: { quantity: true },
  });
  return (result._sum.quantity ?? 0) / windowDays;
}

// Send consolidated alerts — group by supplier to avoid email spam
async function sendAlertNotifications(alerts: Alert[]) {
  const bySupplier: Record<string, Alert[]> = {};
  for (const alert of alerts) {
    const key = alert.config.supplierId ?? 'merchant';
    if (!bySupplier[key]) bySupplier[key] = [];
    bySupplier[key].push(alert);
  }

  for (const [supplierId, supplierAlerts] of Object.entries(bySupplier)) {
    const to = supplierId === 'merchant' ? process.env.MERCHANT_ALERT_EMAIL : (await db.suppliers.findById(supplierId))?.email;
    if (!to) continue;
    await emailService.send({ to, template: 'low-stock-alert', data: { alerts: supplierAlerts } });
  }
}

ステップ 3:動的な発注点を計算する(任意)

固定しきい値(例:「在庫が 10 個になったらアラート」)はシンプルですが、適切でない場合があります。1 日に 50 個売れる商品には、週に 2 個売れる商品よりもはるかに高いしきい値が必要です。

計算式:

Reorder Point = (Daily Sales Velocity × Lead Time Days) × 1.2 (20% safety buffer)

例:商品は 1 日に 5 個売れ、仕入先のリードタイムは 7 日です

  • リードタイム中の需要:5 × 7 = 35 個
  • 安全バッファーを加えた発注点:35 × 1.2 = 42 個

Shopify の場合: Inventory Plannerアプリを使用します。販売履歴から、販売速度に基づく発注点を自動計算します。

WooCommerce の場合: ATUM Inventory Management では仕入先のリードタイムを設定でき、販売速度に基づいて発注点を提案します。


ステップ 4:仕入先への再発注通知を自動化する

アラートが発生したら、購買チームまたは仕入先に自動で通知できるようにします。

Shopify + Stocky: 在庫が発注点を下回ると、Stocky は購入注文書の下書きを作成します。チームで内容を確認し、Stocky 内から PO を仕入先に送信します。

WooCommerce + ATUM(有料): 商品の再発注が必要になると、ATUM から設定済みの仕入先に直接メールを送信できます。メールには推奨数量も含められます。

メールのワークフロー(すべてのプラットフォーム): 在庫低下通知メールの宛先に、仕入先の発注受付用メールアドレスを直接設定します。通知テンプレートには SKU、商品名、推奨再発注数量を含めます。

ベストプラクティス

  • リードタイムと販売速度に基づいて発注点を設定します — 10 個という固定しきい値は、売れ行きの遅い商品には適切でも、売れ行きの速い商品には危険なほど低い可能性があります。上記の式を出発点として使用してください
  • アラートの重複をなくします — プラットフォームやカスタムソリューションは、在庫が減るたびにアラートを送るのではなく、インシデントごとに SKU あたり 1 件だけ送信するようにしてください。在庫が補充されたら、古いアラートを解決してください
  • 仕入先へのメールをまとめます — 同じ仕入先の商品で在庫が少ない SKU を 5 件まとめたメールを 1 通送るほうが、個別のメールを 5 通送るよりも通知が大幅に少なくなります
  • 商品レベルだけでなく、バリエーションレベルでしきい値を設定します — XL の残りが 3 着で M の残りが 50 着のシャツの場合、XL のみアラートを送信してください
  • 季節ごとにしきい値を見直して更新します — 通常は 1 日に 2 個売れる商品が、繁忙期には 1 日に 20 個売れることがあります。需要が高まる時期の前にしきい値を調整してください

よくある落とし穴

問題解決策
同じ SKU に対してアラートが繰り返し送信される在庫が補充されるまで、プラットフォームがインシデントごとに 1 件だけアラートを送信するようにしてください。Shopify と WooCommerce はデフォルトで正しくこの処理を行います。カスタム構築の場合は resolvedAt ガードが必要です
オフシーズンに動的な発注点が高くなりすぎる販売速度の計算には、直近 30 日間の移動期間を使用してください。季節変動が大きい商品については、季節ごとに別の設定を検討してください
仕入先へのメールが迷惑メールに振り分けられるアラートメールには認証済みの送信ドメイン(SPF、DKIM、DMARC)を使用してください。トランザクションメールプロバイダー(SendGrid、Postmark)を使うと、メールの到達率が向上します
アラートのしきい値が低すぎて誤報が多い仕入先への通常の発注数量の 2 倍をしきい値として設定し、発注品が届く前に実際に在庫切れになる頻度に応じて調整してください

関連スキル

  • @inventory-tracking
  • @multi-warehouse
  • @catalog-import-export

コメント