For the complete documentation index, see llms.txt. This page is also available as Markdown.

Changelog

2026-10-09 — v138: 顧客注文照会が注文番号と明細を返し、分かれた受注を 1 注文にまとめる

変更

  • POST /api/customer-orders/list の orderNumber を、routing に渡した注文番号(orderName。例 BJP1001)にしました。これまではカート側の注文識別子(externalOrderRef)で、刻印の注文では …-engraved のような値になっていました。識別子は新しい externalOrderRef で返します。

  • 1 つの買い物が複数の受注レコードに分かれていても(刻印 / 出荷元の分割 / 予約分)、同じ取込元・同じ注文番号のレコードを 1 行にまとめて返します。totalCount もまとめた後の数です。これまでは分かれたレコードがそれぞれ 1 行になり、-engraved のレコードは明細と突合できず itemCount / total が null でした。

  • list の各注文に items[](detail と同じ形の明細。商品名は商品マスターの値)を足しました。

  • POST /api/customer-orders/detail も同じまとめ方になり、orderId がまとめた受注レコードのどれでも、同じ買い物として明細・出荷元を返します。

2026-10-08 — v137: 棚の数を、引き当て済みの数より少なくできない

変更

  • POST /api/shelf/inventory/adjust と POST /api/shelf/inventory/move(barcode を付け替える場合)は、減らした結果その商品の棚の合計が注文に引き当て済みの数を下回るとき 409 shelf_qty_below_active を返すようになりました。何も変更されません。数を増やす操作と、同じ商品を別の棚へ移すだけの操作、すでに下回っている在庫を実数に直す操作はこれまでどおりです。

  • POST /api/shelf/inventory/move と POST /api/shelf/inventory/adjust のページを足しました(これまでも使えていました)。

2026-10-08 — v136: 店舗(スマレジ / Shopify が在庫の正の拠点)でも棚卸ができる

追加

  • Stocktake — 棚卸 を店舗でも開けるようにしました(mode: "location"。MFC は従来どおり shelf)。数え方は同じで、shelfCode に売場 / バックヤードなどのエリアのコードを入れます。提出(transition: submit)で商品ごとの帳簿数(取り込み元の生の在庫数 + 注文に引き当て済みで未確保の数)を固定し、承認(commit)で差分を外部システムへの調整として貯めます(在庫同期の向きが双方向の拠点だけ。取り込みのみの拠点は差異の記録まで)。帳簿にあるのにどのエリアでも読まれなかった商品は 0 と数えた行(uncounted)になり、includeUncounted: true で通せます。数えている間に動いた商品は保留になり、includeMoved: true で通せます(承認のたびに開始〜提出の窓で見直します)。帳簿数の取り込み元が当てる先のコネクタと違う商品は book_source_mismatch で保留します。生の在庫数が一度も届いていない拠点は 422 book_quantity_unavailable で承認しません。

  • Inventory Adjustments — 外部システムへの在庫調整: POST /api/routing/inventory-adjustments/claim(コネクタが自分の分を取りに来る)/ result(当てた結果を返す)。差分は相対値で、claimed のまま 30 分結果が返らない行は取り直せます。

  • 読み取り view agent_read.stocktake_location_lines / inventory_external_adjustments。

  • GET /api/operator/stocktake/current に locationMode(この拠点で開く形)と syncMode(在庫同期の向き)を足しました。

2026-10-08 — v135: 旧の商品状態の仕組み(販売可能数の内訳・分類 API・隔離移動)を撤去

削除

  • POST /api/ingest/inventory-classification(販売可能数を状態別に色分けする)と POST /api/operator/inventory/block / unblock(非販売品を隔離拠点へ移す)を削除しました。本番で使われていませんでした。商品状態は 棚ごとの状態の数 に置き換わっています(良品以外は販売可能数に入りません)。旧ページは Shelf Inventory へリダイレクトします。

  • 読み取り view agent_read.inventory_balances を削除しました。商品状態の一覧 agent_read.inventory_condition_codes と取り置きの履歴 agent_read.inventory_ledger は残ります。

2026-10-08 — v134: 棚のピックと MFC 在庫取込でも、引き当て済みの数を下回れない

変更

  • POST /api/shelf/inventory/pick と POST /api/ingest/mfc-inventory(absolute の減らし・adjust の -)は、減らした結果その商品の棚の合計が注文に引き当て済みの数を下回るとき 409 shelf_qty_below_active を返すようになりました。何も変更されません。現場アプリの集荷・確保は止まりません。同じ商品の棚移動(-1 / +1)もこれまでどおりです。

2026-10-08 — v133: 棚卸を「棚ごとに数える → 差異を見る → 承認して反映」の形に

追加

  • Stocktake — 棚卸 を作り直しました。POST /api/operator/stocktake/open(セッションを開く)/ shelf-start(棚を数え始める)/ shelf-submit(数えた数をまとめて送って締める。帳簿数を固定し差異を返す)/ transition(提出・取消・取り下げ)/ commit(承認して反映)。商品状態ごとに数えられます。反映は締めた時点との差分を当てるので、締めたあとの出荷・入庫と二重になりません。良品の合計が引き当て済みの数を下回る商品と、負になる行は保留にして残りを反映します。

  • 読み取り view agent_read.stocktake_sessions / stocktake_shelves / stocktake_counts を作り直しました。

削除

  • POST /api/ingest/stocktake と旧 POST /api/operator/stocktake/commit(stocktake_key で確定するもの)を削除しました。本番で使われていませんでした。旧ページは新ページへリダイレクトします。

2026-10-08 — v132: 棚ごとに良品以外の商品状態の数を持てる / 棚マスタ

追加

  • POST /api/shelf/inventory/condition-move を追加しました。同じ棚・同じ商品の数を、商品状態(良品 ⇄ アウトレット・展示用・不良品・検品中など)の間で動かします。良品以外の数は販売可能数に入りません(注文の引き当て対象外)。良品を減らすときは、注文に引き当て済みの数を下回る移動を止めます。

  • POST /api/shelf/master/upsert を追加しました。棚の一覧(棚マスタ)に、空の棚の登録・売場 / バックヤードなどの区分・有効 / 無効を持てます。棚在庫に新しい棚が現れると自動で登録されます。

  • 読み取り view agent_read.shelf_stock(棚 × 商品 × 状態の数)と agent_read.shelves(棚の一覧)を追加しました。

2026-10-08 — v131: 棚の在庫の行は MFC の拠点にだけ作れる

変更

  • 棚の在庫の行は、MFC(location_type が mfc、または mfc_enabled の拠点)にだけ作れるようになりました。POST /api/shelf/inventory/receive・move・adjust、POST /api/ingest/mfc-inventory で MFC ではない拠点に棚の行を作ろうとすると 422 not_self_inventory_location を返します。既にある行を減らす操作と、MFC の拠点への操作はこれまでどおりです。

2026-10-08 — v130: 商品マスターを sku でも引ける

変更

  • GET /api/ingest/products に skus を追加しました。barcodes と skus のどちらかを送ります。sku は一意とは限らないので一致した行をすべて返します。取込元の商品コードから barcode を決めるときに、受け取った側で「ちょうど 1 件か」を確かめて使ってください。

2026-10-08 — v129: 商品マスターを barcode で引く

追加

  • GET /api/ingest/products を追加しました。barcodes にカンマ区切りで渡した barcode のうち、商品マスターにあるものとその sku を返します。取込元(EC モール等)から取れた barcode が登録済みかを、受注を送る前に確かめるときに使います。

2026-10-08 — v128: 在庫移動の送り状の出し方を作成のときに決められる

追加

  • POST /api/routing/stock-transfer/create-request に labelMethod を追加しました。"issue" は出庫のときに配送ラベルを発行して印刷し、追跡番号を箱に記録します。"manual" は手書きの送り状で、出庫のときに追跡番号が必須になります。省略した移動はこれまでどおりです。

  • POST /api/routing/stock-transfer/label-options を追加しました。配送ラベルを発行できる出庫元と、宛先にできる入庫先(住所が入っている拠点)を返します。

  • POST /api/routing/stock-transfer/print-label を追加しました。発行済みの配送ラベルをもう一度印刷します(追跡番号は変わりません)。

変更

  • POST /api/routing/stock-transfer/ship の trackingNumber / carrierCode をページに載せました(箱の追跡番号。これまでも受け付けていました)。labelMethod を決めた移動では、出庫の前に送り状を用意します(発行に失敗・追跡番号が無いときは出庫しません)。

2026-10-07 — v127: 現場アプリにメールの確認コードでログインできる

追加

  • POST /api/operator/login/otp/request と POST /api/operator/login/otp/verify を追加しました。スタッフのメールアドレスに確認コードを送り、そのコードでログインできます。パスワードも Google / Apple のアカウントも使わないスタッフ向けです。アカウントは作られません(すでにあるアカウントだけが対象)。

2026-10-06 — v126: 商品と出荷元の組み合わせで在庫連携を止められる

追加

  • POST /api/ingest/products に inventory_push_disabled_source_ids を追加しました。商品ごとに、在庫連携を止める出荷元を拠点 id の配列で指定します。指定した出荷元については、出荷元在庫の通知 の availableTotal が 0 になります。販売チャネルでその出荷元から売りたくない商品に使います。設定を変えた出荷元には、在庫の変動を待たずに 1 回通知します(止めた出荷元は 0、再開した出荷元は最新の合算)。

2026-10-06 — v125: まとめて 1 箱で出す出荷にも追跡番号を入れられる

変更

  • POST /api/routing/shipment/ship で、複数店舗分を 1 箱にまとめる MFC 集約グループの出荷にも trackingNumber を指定できるようにしました。これまでは 400 で拒否していたため、配送ラベルを自動発行しない出荷元では箱に追跡番号を付けられず、出荷済みにできませんでした。指定した番号はグループ先頭の出荷に保存し、出荷ステータス通知にも載ります。carrierCode だけを trackingNumber なしで指定した場合は引き続き 400 です。

2026-10-05 — v124: 確保済みを解除できる

追加

  • POST /api/routing/shipment/unsecure を追加しました。誤って確保済みにした単位を、確保前へ戻せます。戻せるのは集荷前の単位だけです。

2026-10-04 — v123: 在庫行が無い商品にも販売チャネルの販売可能数を反映する

変更

  • POST /api/ingest/channel-available で、その拠点に在庫行がまだ無い商品(倉庫から一度も在庫数が届いていない新商品など)を unresolved[](level_not_found)で返すのをやめ、在庫 0 の行を作って反映するようにしました。再送は不要です。

2026-10-01 — v122: 引き当ての前に出荷元を確認できる

追加

  • POST /api/routing/orders で、出荷元を引き当ての前に確認するアプリを登録したストアでは、アプリが答えた出荷元で引き当てるようになりました。確認が取れないときは引き当てずに 202(status: received / pending: "source_decision")を返し、確認が取れた時点で自動で引き当てます。再送は不要です。アプリを登録していないストアの動きは変わりません。

2026-09-29 — v121: 出荷準備中にするときに手書きの送り状の追跡番号を送れる

追加

  • POST /api/routing/shipment/collect に trackingNumber / carrierCode / trackingCompany / trackingUrl を追加しました。配送ラベルを発行しない出荷で、送り状を箱に付ける段階の追跡番号を保存できます。保存した番号は、出荷済みにするときに追跡番号を送らなければそのまま使われます。

  • 配送ラベルを発行済みの出荷に追跡番号を送ると 409 label_already_issued を返します。

2026-09-27 — v120: 外部倉庫の拠点で、販売チャネルで売れない商品を販売可能在庫 0 に

追加

  • POST /api/ingest/channel-available を追加しました。在庫数を外部倉庫が送ってくる拠点で、販売チャネル(Shopify など)での販売可能数を伝えます。0 以下を送った商品は、倉庫に現物があってもその拠点の販売可能在庫が 0 になります。1 以上を送ると通常の計算に戻ります。倉庫から届いた在庫数は書き換えず、受注の引き当ても止まりません。

2026-09-25 — v119: 配達希望日を遅らせたときの遅延のお知らせ

追加

  • POST /api/routing/shipment/delivery に notifyDelay を追加しました。配達希望日を遅らせる(または指定なしにする)ときに true を送ると、購入者へ遅延のお知らせメールを送ります。レスポンスに delayed(遅延だったか)と delayNotice(お知らせの送信結果)を追加しました。

  • 配達希望日を遅らせると、購入者のお届け状況ページに「遅延」と変更前 → いまの予定が出ます。

2026-09-25 — v118: 予約納期の "*" キーを受け付けない

変更

  • POST /api/ingest/products の preorder_delivery_dates に "*" のキーを送ると 400 invalid_input になるようにしました。v117 の移行期間が終わったためです。キーには出荷元の拠点 ID を使ってください。保存済みのデータに "*" のキーはありません。

2026-09-25 — v117: 予約納期を出荷元ごとに

変更

  • POST /api/ingest/products の preorder_delivery_dates は、出荷元の拠点 ID → その出荷元から出荷できるようになる日の対応表になりました。配送先の国コードと "*"(全マーケット)のキーは使いません。行のある出荷元だけが商品を出荷でき、行の無い出荷元は候補から外れます。到着予定日はこの日から出荷元の作業日数と配送日数を積んで出します(配送先までの日数は計算が足すので、国ごとに日付を分ける必要はありません)。

  • 移行: 既存の "*" の値は、そのショップの出荷元すべてに同じ日付として展開しました。キーに拠点 ID 以外を送ると 400 invalid_input になります("*" は移行中のみ受け付けます)。

2026-09-24 — v116: 送信先 URL は https のホスト名だけに

変更

  • 配送・連携先の設定と各 webhook 設定の destinationUrl は、https:// で始まるホスト名の URL だけを受け付けるようにしました。IP アドレス・localhost・.internal・.local を指定すると 422 invalid_destination_url になります。保存済みの設定がこの条件を満たさない場合は、送信せずに失敗として記録します。

2026-09-24 — v115: 送信先を変えたときの認証情報の扱い

変更

  • 配送・連携先の設定と各 webhook 設定で、destinationUrl か authHeaderName を変えるときに authSecret を省略すると、保存済みの認証情報を消すようにしました。以前の送信先の認証情報が新しい送信先に送られないようにするためです。送信先を変えるときは authSecret も送り直してください。

2026-09-24 — v114: 出荷済みにするとき配送業者の名前と追跡 URL を渡せるように

追加

  • POST /api/routing/shipment/ship に trackingCompany / trackingUrl を追加しました。手書きの送り状などで出荷したときに、追跡番号と一緒に配送業者の名前と追跡ページの URL を渡せます。

  • 出荷ステータス通知の payload に同じ 2 項目を載せます。指定が無ければ null です。

2026-09-18 — v113: 振り分けで購入者への通知・店舗での印刷を止められるように

追加

  • POST /api/routing/orders に suppressCustomerMail を追加しました。true にすると、その注文では購入者にお届け状況メールを送りません。

  • 同じく suppressStorePrint を追加しました。true にすると、その振り分けでは店舗で商品ラベル(統合QR)を自動印刷しません。引き当ての通知は通常どおり送ります。

  • レスポンスの customerMailSuppressed / storePrintSuppressed で、指定を受け付けたかを確認できます。

2026-09-17 — v112: API キーを画面で発行できるように

変更

  • API キーを Last Mile のコンソール(設定 > API キー)で自分で発行・失効できるようになりました(認証)。キーは発行時に 1 回だけ表示されます。

  • 各エンドポイントのページで、shop が省略できることを分かるようにしました。

2026-09-17 — v111: API キーだけで呼べるように

変更

  • API キーが 1 つのアカウントにひも付いている場合、リクエストの shop を省略できるようになりました。省略すると、キーのアカウントとして処理します(認証)。

  • shop を送る既存の連携はそのまま動きます。キーと違う shop を送った場合は、これまでどおり 403 を返します。

2026-09-16 — v110: 在庫の取り置き

追加

  • POST /api/inventory/hold を追加しました。拠点の在庫の一部を参照 ID ごとに取り置き、販売可能在庫から外します。取り置き分は受注の引き当てに使われず、Shopify の販売可能在庫からも減ります。

  • 参照 ID を省略すると LastMile が生成して返します。期限(expires_at)を付けると、過ぎた時点で自動で解除されます。

  • 取り置きは在庫の取込とは別に保存されます。POS・倉庫から在庫の絶対値が届いても消えません。

  • POST /api/inventory/release を追加しました。参照 ID の取り置きをまとめて解除します。

修正

2026-09-14 — v109: 商品を付帯サービスとして登録できるように

追加

  • POST /api/ingest/products に is_accessory_service を追加しました。当日出荷チケットや刻印サービスのように、それだけでは出荷する荷物にならない明細の印です。

  • true にした商品は在庫の引き当て対象から外れ、出荷指示の serviceLines に入ります。

  • false を送ると通常の商品に戻ります。省略すると既存値を維持します。

  • GET /api/ingest/accessory-services を追加しました。付帯サービスにした商品の一覧を返します。

2026-09-12 — v108: 商品タイプとメタフィールドを商品マスターに持てるように

追加

  • POST /api/ingest/products に product_type を追加しました。到着予定日の商品区分を判定するための項目です。カテゴリ(category_l1)とは別に持ちます — カテゴリにはカテゴリ体系の名前が入るため、商品タイプが失われていました。省略すると既存値を維持します。

  • 同じく class_metafields を追加しました。商品区分をメタフィールドで判定している場合に、その値を渡すための項目です。商品側とバリエーション側を分けて送ります。省略すると既存値を維持します。

2026-09-11 — v107: SKU 対応表に商品マスターの SKU を添える

追加

  • GET /api/ingest/sku-mappings の各行に sku(その barcode の商品マスター上の SKU)を追加しました。倉庫など、商品マスターの SKU で商品を識別する相手に渡すときに使えます。商品マスターに無い barcode は null です。既存の項目は変わりません。

2026-09-10 — v106: ピッキング・出荷準備中・出荷済みの操作で、お届け状況メールをその段だけ止められるように

追加

  • POST /api/routing/secure・POST /api/routing/shipment/collect・POST /api/routing/shipment/ship に任意の suppressCustomerMail を追加しました。true で送ると、その操作に対応するお届け状況メール(在庫確保 / 出荷準備 / 発送完了)を送りません。

  • 止まるのはその段だけです。以降の段は店舗の通知設定どおり送られます。

  • 送る方向には指定できません。店舗の通知設定で送らない段は、指定が無くても送りません。

  • 3 つのレスポンスに customerMailSuppressed(指定を受け付けたか)を追加しました。

2026-09-10 — v105: 予約納期を商品マスターで持てるように

追加

  • POST /api/ingest/products に preorder_delivery_dates を追加しました。配送先の国コード → お届け予定日(YYYY-MM-DD)の対応表で、"*" が全マーケットの既定です。設定した商品は、チェックアウトと購入者ページの到着予定日が在庫や出荷元の計算ではなくこの日付になります。省略すると既存値を維持し、{} で外します。

  • 配達日時指定(/api/routing/delivery-window)と配送予定日プレビュー(/api/routing/delivery-estimate-preview)に任意の countryCode(配送先の国)を追加しました。予約納期のマーケット別の値を引くのに使います。省略時は "*" の値だけを見ます。

2026-09-09 — v104: WMS 出荷指示は倉庫の様式ではなく「注文の中身」を送る形に

変更

  • POST /api/routing/wms-shipping-request が受け取るのは、倉庫の様式に組み上げた本文ではなく instruction(注文の中身) になりました。宛先・明細・金額・お届け希望を Shopify から取れた値のまま送ると、倉庫ごとの様式への変換(項目名・日時や電話の書式・姓名の並び・住所の分割・送料按分・税の逆算・手数料)はサーバー側で行います。

  • 送る側で整形しないでください。null は null のまま、金額は文字列のまま、日時は ISO のまま、姓と名は分けたまま、住所は分割せずに送ります。整形を前倒しすると倉庫に渡る内容が変わります。

  • 出荷指示か取り下げかは、ボディ直下の action(SHIPPING_REQUEST / SHIPPING_CANCEL)で指定します。取り下げの instruction は伝票番号だけです。

  • 旧形式(組み上げ済みの本文を payload で渡す)は受け付けません。

記述の訂正

  • 「同じ注文番号で送り直すと WMS 側で上書きされる」は誤りでした。WMS は伝票番号ごとに 1 伝票を持ち、2 回目以降を無視します。初回に送った内容がそのまま出荷されるので、送る前に内容を確定させてください。あとから変えたい場合は取り下げてから別の伝票として作り直すか、倉庫へ直接連絡してください。

2026-09-02 — v103: 発送完了メールを送るかは店舗の通知設定で決まるように

変更

  • POST /api/routing/shipment/ship の sendShippedMail を廃止しました。発送完了メール(お届け状況の更新メール)を送るかは店舗の通知設定が決めます。送り続けても無視するだけなので、呼び出し側の修正は不要です。

  • 提携倉庫から出る注文にお届け状況メールを送る設定の店舗では、その出荷について販売チャネル側の発送通知を送りません(notifyCustomer: true でも抑止します)。同じ出荷で 2 通届くのを避けるためです。

  • この 2 つを 1 つの設定から決めるようにしたので、「どちらの通知も送られない」状態は起きません。以前は「通知を止める」が店舗の設定、「メールを送る」がリクエストの項目という別々の指定で、両方が off になると出荷の連絡が 1 通も届きませんでした。

2026-08-28 — v102: ピッキングリストと配送ラベルを 1 つの PDF で受け取れるように

追加

  • Picking List(バッチ) に labelShipmentIds を追加しました。指定した出荷の発行済み配送ラベルを ピッキングリストの後ろに綴じた 1 つの PDF を返します。1 注文の画面から「作業指示 + 送り状」をまとめて開いて印刷する用途を想定しています。

  • 綴じた枚数は labelsIncluded、綴じられなかった出荷(ラベル未発行 / 破棄済み)は labelsSkipped で返します。ラベルが 1 枚も無くてもピッキングリスト単体として成功で返るので、綴じられたかは labelsIncluded で判定してください。

  • バッチの locale(帳票の表示言語 ja / en)をドキュメントに明記しました(挙動の変更はありません)。

2026-08-17 — v101: 集荷(オンコールピックアップ)を API から依頼できるように

追加

  • Carrier Pickup(POST /api/routing/pickup / POST /api/routing/pickup/cancel)を追加しました。配送ラベルを発行済みの出荷をまとめて、キャリアの集荷(オンコールピックアップ)を依頼できます。対応キャリアは UPS です。集荷は「この拠点に、この日、この時間帯に、この個口数を取りに来てもらう」1 回の訪問なので、複数の出荷を 1 リクエストにまとめて送ります(個口数と宛先国は出荷から自動で決まります)。依頼が成功すると集荷受付番号(PRN)が返り、取消に使えます。

  • 一度依頼した出荷は、取り消すまで別の依頼に入れられません(409)。同時に 2 か所から依頼しても受付番号は 1 つしか立たず、同じ荷物への二重手配になりません。

  • 集荷先の住所・キャリア認証情報・既定の時間帯は、出荷元拠点ごとの設定(Dispatch Config の action: "pickup")から読みます。設定が無い拠点への依頼は、エラーではなく requestable: false と理由を返します。

  • 集荷先住所は依頼のたびに pickupAddress で上書きできます(その 1 回の依頼にだけ効き、設定は書き換わりません)。上書きした住所も設定側と同じ検証を通ります。

  • キャリアが集荷を受け付けたあとで記録に失敗した場合は、受付番号をレスポンスに載せて 500 を返します(出荷は依頼済みのまま残します)。受付番号が記録されていない依頼は既定では取り消せません(409)— キャリアに集荷が残っているのにこちらだけ未依頼に戻すと二重手配になるためです。

2026-08-17 — v100: 出荷元への入荷転送を登録できるように(移動中を追跡)

追加

  • Transfer Inbound(POST /api/routing/transfer/inbound)を追加しました。在庫のある拠点と出荷する拠点が違い、現物を出荷元へ運んでから出荷する注文(刻印加工のための倉庫送り、海外発送のための国内 MFC 集約など)で、その移動区間を拠点間移動として登録できます。送るのは「すでに発送した便の追跡番号」で、配送ラベルは発行しません。登録した注文は移動が終わるまで移動中として扱われ、荷物が出荷元に届いた時点で自動的に出荷準備中へ進みます(受け取りの登録は不要。倉庫アプリのスキャン受領はこの移動には使えません)。同じ出荷に再送しても二重に登録されません。

  • 返送ラベルを発行する 返送バルク とは別の種別です。

変更

  • 拠点間移動の配送状況の確認間隔を 4 時間から 1 時間 に短縮しました。届いてから出荷準備中になるまでの待ち時間が縮まります。

  • 配送状況を確認するたびに現在の状況を記録するようになりました(配達完了以外も)。「いまどこまで運ばれているか」を参照できます。発送直後はキャリア側にまだ反映されておらず状況が取れないことがありますが、これは異常ではありません。24 時間を超えても取れない場合や、いったん進んだあとに異常が出た場合だけ警告として記録します。

  • 配送状況の語彙を拡張し、pre_transit / returned / exception / not_found / other を区別するようになりました(従来はこれらがすべて「取得できなかった」に丸められていました)。発送完了メールの送信条件は変わりません。

2026-08-16 — v99: 発送完了メールを配送業者の実集荷後に送信(有効化)、集荷までお届け状況は発送前表示

変更

  • 発送完了メール(お届け状況)を、出荷確定の瞬間ではなく 配送業者が実際に集荷した後 に送るようにしました(v83 で追加した保留の仕組みを有効化)。集荷前に「発送完了」を案内してしまい、追跡番号を照会しても配送業者側にデータが無い、という状態を避けます。

  • 集荷検知の照会間隔を 1 時間 に変更しました。集荷から最大 1 時間でメールが届きます。

  • 購入者向けお届け状況ページも、集荷を検知するまでは 「発送準備中」表示 に揃えました(発送完了の到達時刻と追跡番号は集荷まで表示しません)。集荷を検知した時点で「発送完了」と追跡番号が表示されます。

  • 対象は配送ラベルを Ship&Co で発行し、配送業者が佐川急便 / ヤマト運輸の出荷です。それ以外(外部倉庫からの出荷、DHL など)の顧客通知は従来どおりです。Shopify の発送通知(notifyCustomer)も変更ありません。

2026-08-12 — v98: 出荷ステータス通知の宛先を取込元(sourceSystem)ごとに設定可能に

変更

  • Fulfillment Status Webhook の設定(POST /api/routing/status-webhook-config)に任意項目 sourceSystem(取込元)を追加しました(LM-1375)。取込元ごとに宛先を分けられます。sourceSystem 指定なしの設定はその shop の既定宛先で、既存の設定はそのまま既定宛先として動き続けます(後方互換・再登録不要)。イベントは自分の取込元と一致する設定があればそちらへ、なければ既定宛先へ届きます。レスポンスに source_system(既定宛先は null)が加わりました。

2026-08-10 — v97: 出荷準備中への一括集荷 API を追加、出荷報告に sendShippedMail を追加

追加

  • Shipment Collect(POST /api/routing/shipment/collect)を追加しました。出荷(shipment)配下の全単位をスキャン操作なしでまとめて集荷済みにし、出荷を出荷準備中へ進めます。issueLabel: true で配送ラベルの発行を同時に行えます(発行済みは再発行しない / MFC 集約グループはグループ全レグ集荷後に先頭の出荷へ 1 枚 / 発行失敗でも集荷は成立し label.error で返す)。MFC 自己在庫の単位は集荷と同時に保管棚の在庫を 1 つ減らします(減らせなかった数は shelf.markedWithoutDecrement で返す)。再送は冪等で、未集荷の単位だけを前進させます。

変更

  • POST /api/routing/shipment/ship に任意項目 sendShippedMail(既定 true)を追加しました。false で発送完了メール(お届け状況の更新メール)を送信しません(後から送られることもありません)。出荷ステータス通知の webhook と notifyCustomer は従来どおりです。

2026-08-10 — v96: 在庫移動に入庫希望日 (receivingDesiredDate) を追加

追加

  • Stock Transfer の create / create-request に任意項目 receivingDesiredDate(入庫希望日・YYYY-MM-DD)を追加しました。入庫先で受け取りたい日付を移動に記録できます。形式が不正な場合は invalid_payload で拒否します。

2026-08-07 — v95: WMS 出荷指示の取り下げ (SHIPPING_CANCEL) に対応

変更

  • WMS Shipping Request の payload.action に "SHIPPING_CANCEL"(出荷指示の取り下げ)を追加しました(LM-1351)。キャンセルされた注文の出荷指示を WMS 側で取り消す用途で、{"action": "SHIPPING_CANCEL", "order_no": "..."} をそのまま転送します。order_detail の配列必須は SHIPPING_REQUEST のときのみです。

2026-08-05 — v94: WMS 出荷指示送信 API を追加

追加

  • WMS Shipping Request(POST /api/routing/wms-shipping-request)を追加しました(LM-1321)。生成済みの出荷指示 JSON(action: "SHIPPING_REQUEST")を記録した上で外部 WMS 連携へそのまま転送します(payload はキー順・値とも無変換のパススルー)。転送せず記録だけを行う shadow モードがあり、移行前の旧経路との突合検証に使えます。冪等キーは持たず、未出荷の間に内容が変わった際は最新内容での再送(WMS 側は注文番号単位の上書き受理)で反映します。転送は 1 発のみ(この API 自身はリトライしない)で、失敗は error_kind(lambda_http_error / lambda_timeout 等)で機械判別できます。

2026-07-28 — v93: 外部フルフィルメント連携 API を追加

追加

  • 出荷を外部フルフィルメントサービス(例: Amazon マルチチャネルフルフィルメント)が実行する出荷元向けの External Fulfillment API を追加しました(LM-1262)。連携アプリが 1) GET /api/routing/shipment/fulfill-job で発注に必要な情報(配送先・明細・外部システム SKU)を取得し、2) 外部サービスへ発注して 3) POST /api/routing/shipment/fulfill-result で受理 / 失敗を書き戻し(受理は再送に冪等・以後の fulfill-job は alreadyAccepted: true で二重発注を skip 可能)、4) GET /api/routing/shipment/fulfill-pending の受理済み・未出荷一覧をポーリングして出荷完了時に POST /api/routing/shipment/ship で出荷済みを報告する流れです。外部システム SKU は barcode との事前登録された明示マッピングのみで解決し(SKU 名からの自動マッピングなし)、未登録 barcode は seller_sku_unmapped で発注に進めません。対応表は GET /api/ingest/sku-mappings で読み取れます。

  • 出荷完了報告 POST /api/routing/shipment/ship(1 出荷を出荷済みにする。既 shipped は noop の冪等 no-op)をドキュメントに掲載し、任意入力 trackingNumber / carrierCode を追加しました。外部フルフィルメントのように追跡番号が出荷完了時に初めて確定するケース向けで、指定時は出荷済みへの遷移と同一の書き込みで保存し、出荷ステータス通知にも載ります(未指定は従来どおりラベル発行時に保存済みの値を使用)。MFC 集約グループ(1箱=1ラベル)の出荷では追跡番号はグループ先頭の出荷が保有するため、指定すると 400 で拒否します。

2026-07-14 — v92: 引き当て順を「在庫数の多い拠点優先」へ変更

変更

  • Routing の引き当て順位を変更しました。出荷元自身の在庫を最優先で使い切った後は、販売可能在庫(available)の多い在庫ロケーションから引き当てます(旧: メンバーの priorityRank 順)。在庫数が同じ場合は配送先と同じ地域の拠点 → priorityRank 昇順で決定します。committed は順位に影響せず、引き当て可否と配分数にのみ使われます。

  • SKU 拠点オーバーライドの force_first は常に最上位で適用されるようになりました(従来はメンバー優先順位に劣後して実質効かないケースがありました)。force_only / avoid の除外は従来どおりです。

  • 判定根拠の理由コードに stock_ranking / source_self_stock が加わりました(旧 top_score は過去の記録にのみ残ります)。拠点優先度(channel × region 設定)と各スコアは判定記録として保存されますが、順位の決定には使われません。引き当て済みの既存注文には影響しません(新規ルーティング・注文更新・再引き当てから適用)。

2026-07-13 — v91: 在庫変動通知に発売日時 (releasedAt) を追加

追加

  • Source Inventory Webhook の各イベントに releasedAt(商品の発売日時・ISO 8601、未設定は null)を追加しました。発売前に在庫を公開しない運用では、受け手側で releasedAt が未来のイベントの在庫を 0 として反映してください。発売日時を過ぎると通常の合算値が流れます。既定の payload テンプレートに含まれます(独自テンプレート利用時は {{releasedAt}} を追加してください)。

2026-07-13 — v90: 商品マスターに発売日時 (released_at) を追加

追加

  • Products の products[] に released_at(発売日時・ISO 8601)を追加しました。タイムゾーンオフセット付き(例 2026-07-15T10:00:00+09:00)を推奨します(オフセット無しは UTC として解釈)。省略すると既存値を維持するため、released_at を送らない取込元(Shopify 同期等)が既に設定された発売日時を消すことはありません。

2026-07-09 — v89: 拠点間在庫移動 (Stock Transfer) API を追加

追加

  • 拠点間で商品を 数量ベースで移動する Stock Transfer API を追加しました(作成 →(承認)→ 出庫 → 入庫のライフサイクル)。ステータスは 3 軸(進捗 progress / 承認 approval / 修正依頼 modificationRequest)で管理し、Shopify InventoryTransfer 相当の派生フェーズ(shopifyPhase)も返します。作成は create(承認なし・すぐ出庫可)と create-request(承認が要る出庫依頼)の 2 系統です。承認(approve)は既定で承認と同時に出庫まで実行します(スマレジの「承認=出庫」に準拠。autoShip: false で承認のみ)。実数量(棚・販売可能在庫)が動くのは自社在庫(MFC 自己在庫)の拠点だけで、外部システム(Shopify / スマレジ)が在庫を管理する拠点は移動を記録するのみです(実在庫は外部が正)。出庫時は 移動可能量(棚合計 − 引き当て済み)を超える出庫を insufficient_transferable_qty で拒否し売越を防ぎます。入庫検品中の 修正依頼(起票 / 完了 / 取消)で受領更新をロック・再開できます。認証は x-ingest-secret または operator JWT。既存の返送バルク(Transfer API・注文 unit の返送)とは別機能です。

2026-07-09 — v88: 在庫内訳ビューの拡張・block の分類協調・新規店舗の condition 初期化

追加

  • agent_read.inventory_balances に在庫の一望用の列を追加しました: is_overflow(非デフォルト condition の合計が販売可能在庫を超過している=要確認)/ is_sellable_location(その拠点が出荷元として販売可能か。隔離ロケーションは false =売れない)/ location_available・location_on_hand(拠点在庫の文脈)。「どこに・どのグレードが・売れる/売れない」を1ビューで確認できます。

  • 新しく登録された店舗にも品質グレード(condition)マスタ(A/B/C/UNKNOWN)が自動で初期化されるようになりました(拠点作成時に seed)。

変更

  • 在庫の block 実行時、隔離した数量ぶんだけ源拠点の condition 内訳を自動で減算し、内訳合計が販売可能在庫を超える不整合(overflow)を出さないようにしました。

  • 棚卸し・分類・block の quantity に上限(1,000,000)を設けました(極端な値による内部エラーを防止)。

2026-07-09 — v87: 在庫の block / unblock(非販売品を隔離して販売可能在庫から外す)

追加

  • 非販売品(C品・検品中・破損など)を隔離ロケーションへ移動して販売可能在庫から外す POST /api/operator/inventory/block(と戻す /unblock)を追加しました。しくみは拠点間移動(Stock Transfer)の再利用:源拠点 → 隔離ロケーションへ移すことで源の販売可能在庫(available)が自動的に下がります(自己在庫の移動可能量ガードで売越を防止・在庫変動通知も発火)。隔離ロケーションを出荷元(source member)にしなければ、そこの在庫は販売可能として扱われません(=売れない)。対象は自社在庫。unblock は逆に隔離在庫を元拠点へ戻し available を復帰します。

2026-07-09 — v86: 棚卸しの確定 (commit) で自社在庫を実棚数へ反映

追加

  • 記録した棚卸しを承認確定する POST /api/operator/stocktake/commit を追加しました。自社在庫(MFC 自己在庫)の在庫数を実棚数へ合わせ、変化分を販売可能在庫として反映します(在庫変動通知で Shopify にも伝わります)。外部システムが在庫を管理している拠点は対象外(skipped)、実棚数 < 引き当て済み数は rejected(物理不足の発覚・棚も引き当ても動かさない=売越を作らない)、確定済みの再確定は安全な no-op(already_committed)。認証は x-ingest-secret または operator JWT。棚卸しの記録(Stocktake)自体は従来どおり在庫を動かしません。

2026-07-09 — v85: 在庫の品質グレード (condition) 内訳 API を追加 (別軸・在庫合計は不変)

追加

  • 既存の販売可能在庫(available)を品質グレード(condition_code:A品/B品/C品)で色分けする POST /api/ingest/inventory-classification を追加しました。「available 10 のうち B=2, C=1(残り 7 は A)」のように内訳を記録します。在庫の合計は変えません(数量増減ではなく分類)。しくみは residual モデル:非デフォルト condition(B/C/UNKNOWN)の数量だけを絶対値で保存し、デフォルト(A)は available − Σ(非デフォルト) の残差として自動計算します(外部の在庫更新で available が動いても分類は保持され A 数量だけ追従)。上限ガード「Σ(非デフォルト) ≤ available」を満たさない行は rejected[] で返します。販売可能在庫・在庫スナップショットには影響せず(Source Inventory Webhook も非発火)、内訳の可視化用途です(read は agent_read.inventory_balances)。C品を実際に売れないようにする(販売可能数の減算)は将来対応です。

2026-07-08 — v84: 棚卸し (実棚数) の取込 API を追加 (既存在庫と別軸・在庫は不変)

追加

  • 現場で数えた実棚数を取り込む POST /api/ingest/stocktake を追加しました。実棚数を商品(barcode)× 拠点 × 品質グレード(condition_code:A品/B品) × **業務状態(inventory_status)の単位で記録し、システムが持つ現在庫との差分(variance)**を返します。「実棚数を送るだけで差分はシステムが算出」する形(Square Inventory API の PHYSICAL_COUNT を参照)で、同一 SKU 内の品質グレードを在庫バケットとして持てます(NetSuite Inventory Status を参照)。stocktake_key で棚卸イベントに束ねて冪等に再送でき、同じ barcode × condition × status は新しい occurred_at が勝ちます。このエンドポイントは販売可能在庫・在庫スナップショットを一切変更しません(現在庫は差分算出のため読み取るだけ・Source Inventory Webhook も発火しません)。在庫を実棚数へ合わせる反映は棚卸しとは別の操作です。

2026-07-07 — v83: 発送完了メールを佐川実集荷後に送信 (Ship&Co tracking webhook・flag gated)

追加

  • 発送完了メール(お届け状況)を、オペレーターが出荷確定した瞬間ではなく 佐川が実際に集荷した後(Ship&Co tracking の collected/transit/delivered 検知後)に送る仕組みを追加しました(LM-1183)。検知は Ship&Co tracking webhook(POST /api/webhooks/shipandco/tracking・HMAC 署名検証)を主経路、30 分間隔のバックストップ poll を副経路とします。対象 shop の設定フラグ delay_shipped_until_collected(既定 off)で有効化し、off の間は挙動不変(従来どおり出荷時に即送信)です。複数箱の注文は全箱集荷後にメール 1 通、24h 未集荷は自動送信せずエラー候補として可視化します。Shopify の発送通知(notifyCustomer)は変更しません。

2026-07-07 — v82: 即時切替 (mode: switch) のガード強化と WMS/通知パリティ

変更

  • POST /api/routing/change-source の mode: "switch" にレグ整合性ガード 2 つを追加しました: 同一レグに他の active 単位がある場合は 409 shipment_has_siblings、MFC 集約グループ(1箱=1注文)に属するレグは 409 consolidation_group_member(いずれも返送フローで扱ってください)。あわせて切替時に新出荷元 WMS への create dispatch と切替先の確保待ち通知イベント(store_secure_pending_assigned)の発火を追加し、返送フローの受領と同じパリティにしました。レスポンスに createDispatches が追加されます。

2026-07-07 — v81: 出荷元変更に即時切替モード (mode: switch) を追加

追加

  • POST /api/routing/change-source に mode: "switch"(即時切替) を追加しました。返送フロー(ケース起票 → 返送 → 受領)を使わず、同一の出荷レグ・単位のまま出荷元と引当ロケーションだけを新拠点へ更新します(旧レグの取消・新レグの作成をしません)。単位が secured なら確保を解除し、旧拠点の棚紐付け解放・旧出荷元 WMS への cancel dispatch・新旧両拠点の自己在庫 available 再計算・割当保管棚の再分配まで一括で行います。対象は未ピックの allocated / secured 単位のみ。発行済み配送ラベルが載っている場合は requiresLabelReissue: true を返します(旧出荷元の契約のため再発行が必要)。既定(mode 省略 / transfer)の返送フローは従来どおりです。

2026-07-06 — v80: 非在庫サービス品 (同梱品) を現場照会と出荷済み反映に対応

追加

  • GET /api/operator/shipments/by-tracking のレスポンス order に serviceLines[]({barcode, sku, productName, variantName, quantity})を追加しました(LM-1172)。非在庫サービス品(products.is_non_inventory = true。ショッパーバッグ等の同梱品)は在庫引き当ての対象外で unit を持たないため(LM-527)、これまで現場アプリからは見えませんでした。梱包時に同梱すべき品を追跡番号スキャン時点で明示し、同梱漏れを防ぎます。適用中の routing decision(selected_reason = 'non_inventory_service')から注文単位で集計します。同梱品が無い注文は空配列で、既存クライアントへの影響はありません。

変更

  • Fulfillment Status Webhook の shipped 遷移の lines に、注文の非在庫サービス品の barcode / 数量を合流するようにしました(LM-1173)。routing に送られた明細は出荷済み反映の対象、という契約の明確化です。これまで unit を持たない同梱品の明細が lines に載らず、受け手(Shopify 連携等)で注文が「一部発送済み」のまま残っていました。受け手が明細を残数ベースで冪等に反映していれば、分割出荷でも最初の出荷 1 回だけに反映されます。shipped 以外の遷移は従来どおりです。

2026-07-06 — v79: 出荷追跡照会の集約フィールド公開 + 返送バルクの配送完了自動受領

追加

  • GET /api/operator/shipments/by-tracking のレスポンスフィールドをドキュメントに追記しました: consolidationShelfCode(集約棚)/ consolidationLabelPlacedAt(「③ ラベルを置く」の配置完了時刻・LM-1157)/ consolidationGroupId(同一 MFC 複数店舗分割の集約グループ id・LM-1144。head ヒット時の units[] は箱全体の union)/ labelVoidedAt・labelVoidReason(ラベル void 情報)/ order.orderName(表示用注文番号)。あわせて units[].shelfCode の説明を unit 単位の永続割当(引当時の FIFO 分配・LM-1101)に基づく現行仕様へ更新しました。

変更

  • 倉庫間移動バルク: dispatched のバルクは返送ラベルの配送完了(キャリアの delivered)検知でステータスのみ received に自動遷移するようになりました(LM-1159)。サーバーが約 1 時間ごとに配送状況をポーリングし、received_at と所属単位の受領時刻を記録します(中止済み単位には付与しません)。受領照合が行う単位の再フルフィルメント等の副作用は伴いません。

2026-07-03 — v78: 在庫 ingest の as-of 逆行ガード(幽霊在庫防止)

追加

  • /api/ingest/inventory-snapshot / /api/ingest/inventory-available の lines[] に任意の as_of(読み値のソース時刻・ISO 8601)を追加しました(LM-1154)。既存行の inventory_as_of より古い行は適用せず、レスポンスの stale_skipped[]({ barcode, as_of, current_as_of })と lines_stale_skipped で明示します。バッチ同期の古い読み値がリアルタイム更新(webhook 等)済みの値を後勝ちで上書きする事故(幽霊在庫 → 二重引当・売越)を防ぎます。as_of 省略時は従来どおり inventory_as_of(→ 現在時刻)で、既存の送信側は挙動不変です。

2026-07-03 — v77: 出荷元変更ケースの shipmentId 解決

追加

  • GET /api/operator/source-changes に shipmentId パラメータを追加しました(LM-1152)。統合QR(barcode|shipmentId)の shipment uuid から注文を解決してその注文のケースに絞ります。出荷元変更で unit が relink された後の旧 shipment(cancelled)でも解決できるため、同一 barcode の返送予定が複数あってもスキャンしたラベルの注文を一意に特定できます(iOS 集荷チェックの別注文誤記録 LM-1146 の恒久対策)。指定時はレスポンスに resolvedRoutingOrderId を echo します(クライアントはこれが返った場合のみ解決を信頼)。レスポンスに collectedCheckedAt(集荷チェック記録日時)も追加。

2026-07-02 — v76: 店舗→EC送客(Share Analytics)取り込み

追加

  • 店舗スタッフの商品共有(LINE / メール / QR)とその追跡イベント(開封・カート追加・購入等)を投入する /api/ingest/share-analytics を追加しました(LM-1148)。送信元は source(slug)で識別する汎用エンドポイントで、sot.lm_share_analytics_shares / _items / _events に冪等 upsert します(UNIQUE (source, source_*_id))。

    • PII 遮断: raw の共有トークン・スタッフメール・LINE ユーザー id・顧客 id は保存せず、受信時に HMAC-SHA-256 の hash 列へ変換します。イベント payload / 共有 metadata も PII キーを strip した残りのみ保存します。

    • 行単位の不備(必須欠落・許可外 event_type・不正/未来 occurred_at)は skipped[](reason 付き)で返し silent skip しません。テーブル単位の upsert 失敗は HTTP 207 で部分失敗を明示します。

    • shares / items / events 間に FK を張らないため、分割送信でイベントが先に届いても失敗しません。

2026-06-26 — v75: 配達希望日・時間帯の更新エンドポイント

追加

  • 出荷作業の注文に配達希望日・時間帯を後から設定/変更する /api/routing/shipment/delivery を追加しました(LM-1096)。注文ヘッダ(sot.lm_routing_orders)の desired_delivery_date / desired_delivery_time の 2 列だけを部分更新します(再ルーティング・再 dispatch なし。それが必要な場合は従来どおり /api/routing/update)。

    • 値はラベル生成時に Ship&Co setup.date / setup.time へ載って佐川送り状へ印字されます(LM-1043 の取込列を再利用)。既発行の送り状へ反映するには retry-label(force)で再発行します。

    • null で指定解除。キャンセル済み注文は 409 order_cancelled、別 shop の注文は 404 routing_order_not_found。

    • これまではカート側(Shopify メタフィールド custom.pickup_date / pickup_time → Routing)の自動取込のみでしたが、Last Mile の出荷詳細ページからオペレーターが手で設定できるようになりました。

2026-06-24 — v74: 出荷元メンバー変更時に合算在庫 webhook を再発火

修正

  • 出荷元↔在庫ロケーションのマッピング変更(/api/routing/source-members の設定・解除)時に、影響を受けた出荷元の合算販売可能在庫を再計算して Source Inventory webhook を発火するようにしました(LM-1079)。これまでは在庫取込時しか発火しなかったため、出荷元からメンバーを外しても外す前の合算値が外部在庫ミラー(Shopify available 等)に固着し、在庫過大→オーバーセルになる不具合がありました。

    • メンバー追加・別出荷元への付け替え(新・旧の両出荷元)・解除のいずれにも対応し、最後のメンバーを外した場合も合算を 0 に補正します。

    • set / detach のレスポンスに起票した在庫変動イベント数 enqueued を追加しました。

    • 内部的に出荷元を直接受ける再計算 RPC public.lm_fs_inventory_recompute_source を追加(既存の在庫取込起点の検知経路は変更しません)。

2026-06-24 — v73: 確保前キャンセルの通知(Routing Cancel Webhook)

追加

  • 注文が確保(secure)前にキャンセルされたとき、確保前の出荷元(shipment)ごとに通知する Routing Cancel Webhook を追加しました(LM-1074)。確保前に外部システムへ反映済みだった引き当て(例: 店舗 POS の理論在庫の先行減算)を取り消す用途です。

    • /api/routing/cancel のキャンセル確定直後、確保前(secured_at IS NULL)かつ未出荷の shipment ごとに event: "routing_order_cancelled" を 1 通バックグラウンド送信します。確保後(物理確保済み)・出荷済みの shipment は通知しません(= 自動で取り消さない)。

    • 送信先は専用設定を持たず、Routing Allocation Webhook の設定(shop 単位・同一宛先 / secret)を再利用します。受信側は event フィールドで引き当て通知と判別します。

    • ペイロードは shipmentId(受信側の冪等キー)中心で明細を含みません。耐久性のため outbox(sot.lm_routing_cancel_events)へ起票し、pending / failed は自動 drain で再送します。

    • 詳細は Routing Cancel Webhook を参照。

2026-06-24 — v72: バッチピッキングリスト(複数注文を 1 枚に統合)

追加

  • 複数の注文をまとめて 1 つのピッキングリストに統合する API を追加しました(LM-1053)。出荷作業一覧(inventory-agent /mypage/routing/shipments)で複数行を選択 → スキャン可能な作業指示書(CODE128 バーコード付き PDF)と共有用 CSV を発行する用途です。LM-505 のとおりピッキングリスト出力は inventory-os に集約します。

    • POST /api/routing/picking-list/batch(x-ingest-secret)— routingOrderIds[](1〜500 件)を受け、選択注文の applied decision を在庫拠点単位に統合して format=pdf(統合 PDF 1 枚)/ csv(共有用 CSV)/ json を生成し、PDF・CSV は Storage 保存して公開 URL を返します。各明細に注文番号と**商品バーコード(CODE128)**を付け、刻印違いは別行で運びます。

    • missing(不在 id)/ unrouted(未ルーティング注文)/ unpickable[](引き当て不能)は silent skip せず応答・PDF に含めます。複数注文にまたがるため sot.lm_picking_lists への追記は行いません(単一注文版 /api/routing/picking-list のみ追記)。

    • 詳細は Picking List を参照。

2026-06-21 — v71: 刻印注文は店舗で佐川顧客ラベルを生成しない

変更

  • 刻印注文(external_order_ref に -engraved サフィックス)が secured へ遷移しても、店舗では佐川の顧客ラベルを生成しないようにしました(LM-960)。刻印品は change-source で流山倉庫へ転送し、顧客出荷は流山レグから行うため、店舗での顧客ラベル生成は不要で、生成失敗(住所不備等)が住所不備キューに紛れ込む・無駄なキャリア呼び出しが発生するのを防ぎます。secured 遷移自体は従来どおり確定し、labelStatus は skipped(last_label_error は記録しません)。確保フロー(/api/routing/secure・/api/operator/secure-scan 等)と出荷ステータス報告(/api/routing/fulfillment)の両経路に適用します。

2026-06-21 — v69: 出荷メモ(shipment memo)追記 API

追加

  • 出荷作業の各 shipment(注文 × 出荷元)にオペレーターが時系列でメモを残せる追記 API を追加しました(LM-1002)。出荷詳細ページ(inventory-agent /mypage/routing/shipments/:shipmentId)のタイムライン(システムイベント + 手書きメモ)に新しい順で表示します。

    • POST /api/routing/shipment/memo(x-ingest-secret または operator JWT)— 指定 shipment にメモを 1 件追記します(body 1〜2000 文字)。operator JWT 経由は投稿者(検証済スタッフ ID)を記録します。追記のみ(編集・削除なし = 完全な記録 / 監査ログ)で、呼ぶたびに新しい行を append します。

    • 別 shop の shipmentId には付けられません(404 shipment_not_found)。一覧取得 API はなく、body / 投稿者は PII 相当のため merchant 管理 UI が service_role で直読します(agent_read / LLM agent 非露出)。新テーブル sot.lm_shipment_memos(service_role 専用・agent_readonly grant なし)。

2026-06-16 — v70: 出荷元変更(change-source)を中止(cancelled)後に再起票可能に

変更

  • Source Change の起票(POST /api/routing/change-source)が、対象 unit に中止(cancelled)済みの変更が残っている場合でも再起票(再オープン)できるようになりました(LM-956)。lm_fulfillment_source_changes は UNIQUE(shop, fulfillment_unit_id) で 1 単位 1 行・cancelled は終端のため、従来は一度中止すると同じ単位を二度と転送に乗せられませんでした(前進経路では 409)。今後は secured の単位であれば、残った cancelled 行を change_requested に同一行で再オープンします(新 decision / 新ヘッダ / 旧ヘッダ cancel / 返送便ラベル生成を起票と同一に再実行)。レスポンスに reopened(前回 cancelled を再オープンしたか)を追加しました。cancelled 以外の進行中(change_requested / return_in_transit / return_received)は従来どおり前進/中止のままで挙動不変です。

2026-06-15 — v68: 外部アプリによる配送ラベル生成(汎用 read / write-back)

追加

  • 配送ラベルを inventory-os の組み込みアダプタ(Ship&Co 等)ではなく外部の mini-app(lm-apps)が生成するための、キャリア非依存の汎用 read / write-back を追加しました(LM-916)。越境注文の Global-e(DHL Express)など、住所正規化や ZPL→PDF 変換といった顧客固有・キャリア固有の処理を inventory-os に持ち込まず外部アプリ側に分離するための土台です。

    • GET /api/routing/shipment/label-job(x-ingest-secret)— secured 遷移の fulfillment_shipment_status_changed イベントを受けた app が、ラベル生成に必要な注文情報(orderName / externalOrderRef / 明細 sku × quantity / 出荷元 location)を取得します。宛先 PII は含めません。

    • POST /api/routing/shipment/label-result(x-ingest-secret または operator JWT)— app が生成した追跡番号とラベル PDF(base64)を書き戻します。PDF は Storage shipping-labels に保存し、tracking_number / carrier_code / label_pdf_path を shipment 行へ記録します(status=generated)。失敗は last_label_error のみ記録(status=failed)。shipment の状態は変更しません(secured は確保時に確定済み)。

  • ラベル config(action='label')を登録しない出荷元では従来どおり inventory-os 側のラベル生成は skipped となり(確保自体は確定)、この read / write-back で外部アプリが補完します。print-job / print-result(物理印刷, LM-711)と同じ app-facing プラミングのため、公開エンドポイント一覧(overview / authentication)には掲載しません。

2026-06-14 — v66: 出荷元変更(change-source)を secured のみに一本化

変更

  • Source Change の起票(POST /api/routing/change-source)が、対象 unit が secured のときのみ起票できるようになりました(LM-913。従来は allocated も可)。物理オペは「店舗で確保(secured)→ 業者が MFC へ集荷 → MFC で流山転送を起票」の順で、流山転送の指定は店舗確保より後でなければなりません。確保前(allocated)での起票を許すと確保報告に転送品が現れてしまうため弾きます。allocated での起票は 409 unit_not_changeable(unit must be 'secured' to change source — secure it first)。前進(return_in_transit / return_received)・中止の挙動は不変です。

2026-06-12 — v67: routing 注文に参照 URL(referenceUrl)

変更

  • Routing の POST /api/routing/orders に referenceUrl(任意)を追加しました(LM-910)。カート側の注文参照 URL(例 Shopify admin の注文ページ)を受け取り、管理 UI が注文番号からカート管理画面へ遷移できるようにします。http(s) の URL のみ受け付け、省略時は従来どおり(純 additive)。あわせて orderName(LM-888 で受理済の表示用注文番号)をボディパラメータ表に追記しました。

2026-06-12 — v66: 住所修正からラベル自動再発行・自動再印刷(autoRetryLabel)

変更

  • Address Recovery の POST /api/routing/shipment/address に autoRetryLabel オプション(default false = 既存呼び出し元は挙動不変)を追加しました(LM-838 / LM-904)。true のとき住所更新成功後に、ラベルエラー中の出荷元(住所不備復旧)と、ラベル面に影響する項目が実際に変わった発行済み出荷元(secured / oversell_secured・ラベル未破棄)をまとめて自動再発行し、結果を retryResults で返します。発行済み出荷元の再発行は新しい追跡番号になります(旧ラベルは現場で破棄)。

  • POST /api/routing/shipment/retry-label(および autoRetryLabel)の再発行成功時に、印刷イベント(fulfillment_shipment_status_changed)を印刷アプリへ自動配信するようになりました(LM-836)。住所修正 → 再発行 → 物理印刷が 1 操作で完結します(従来は Print Label の手動呼び出しが必要でした。同 API は紙詰まり等の手動再印刷専用に)。

  • 再発行成功時に label_printed_at / last_print_error をリセットするようになりました(LM-837)。新ラベルは未印刷のため、印刷済み出荷元の force 再発行でも自動印刷が二重印刷ガード(alreadyPrinted)に塞がれません。

2026-06-12 — v65: 出荷元変更(change-source)の secured 対応

変更

  • Source Change の POST /api/routing/change-source が secured(確保済 = ピック済み)の unit でも起票できるようになりました(LM-872。従来は allocated のみで 409 unit_not_changeable)。物理返送は出荷元でピック済みの品を送るのが前提のため、secured を弾く従来仕様は物理オペと矛盾していました。secured からの起票では、確保を解除(unit の secured / secured_at をクリア。宛先 B での受領 = allocated 復帰後に B で再確保)し、unit が抜けて旧出荷元 A のヘッダにアクティブ unit が残らない場合のみ、A の顧客出荷ヘッダを cancelled に遷移・発行済み配送ラベルを運用破棄マーク(label_voided_at。tracking / label 列は監査用に温存)・棚紐付けを新しい released_reason="source_changed" で解放します。レスポンスに解放数 releasedShelfLinks を追加(純 additive)。allocated からの起票・前進/中止の挙動は不変です。

2026-06-12 — v64: 出荷完了(shipped)にも transfer_required ガード

変更

  • Fulfillment の POST /api/routing/fulfillment が、shipped 報告のヘッダに出荷可能な unit が無く、注文配下に倉庫間移動(出荷元変更)フロー中(source_change_pending / source_change_in_transit)の unit がある場合に 409 transfer_required で明示拒否するようになりました(LM-874)。出荷元変更(刻印の倉庫返送等)後に現場へ残った旧ヘッダの顧客向け配送ラベルをスキャンして出荷完了できてしまう穴を塞ぎます。出荷可能な unit が残る混在ヘッダは従来どおり出荷できます(移動中 unit はヘッダ一括更新の対象外のまま)。

2026-06-12 — v63: Transfer API(倉庫間移動バルク)+ 通常出荷の transfer_required ガード

追加

  • Transfer API を新設しました(LM-853)。出荷元変更で旧倉庫に残った現品を複数まとめて(バルク)宛先倉庫へ送る運用の backend です。バルク作成・一覧・ユニットQR スキャンでの単位追加/取消(/api/operator/transfer/batches + add-unit / remove-unit)、発送確定(dispatch:内容物リスト PDF の生成・保存 + 所属単位の一括 return_in_transit + 旧拠点の自己在庫棚 −1)、宛先側の入荷照合(receive:1 点ずつスキャン受領 = return_received・全受領でバルク received)の 6 エンドポイント(operator JWT 認証)。単位の状態機械は既存の出荷元変更をそのまま使い、dispatch / receive の遷移は POST /api/routing/change-source と同一実装を共用します。バルク所属の単位は返送ラベルの夜間バッチ生成から除外されます(二重手配防止)。

  • Operator Queues の GET /api/operator/source-changes に batchId フィルタ(バルクの内容物一覧)とレスポンスの batchId を追加しました。

  • Operator Lookup の GET /api/operator/shipments/by-tracking の各 unit に sourceChange(移動フロー中の status / 行き先 / バルク所属 / 返送追跡番号。フロー外は null)を追加しました(LM-860)。

変更

  • 通常出荷の write API(在庫確保 /api/routing/secure・確保スキャン・追跡番号で確保・棚ピック /api/operator/shelf/pick)が、倉庫間移動(source_change_pending / source_change_in_transit)中の unit への操作を 409 transfer_required で明示拒否するようになりました(LM-860。従来は黙ってスキップ / 汎用エラー)。/api/routing/secure は確保可能な unit と混在する場合のみ従来どおり確保し、transferRequiredUnits[] で表面化します。Fulfillment のヘッダ一括 unit 更新も移動中 unit を巻き込まなくなりました。

2026-06-12 — v62: 確保(secured)遷移でも Fulfillment Status Webhook を発火

変更

  • Fulfillment Status Webhook が、確保フロー(在庫確保 /api/routing/secure・確保スキャン /api/operator/secure-scan・追跡番号で確保 /api/operator/secure-by-tracking)でヘッダが secured に遷移したときも発火するようになりました(LM-851)。従来は /api/routing/fulfillment 経由の遷移しか起票されず、確保フローの secured は外部から見えませんでした。ペイロード形・outbox(再送回収)・配信機構は既存(LM-521)と同一で、status: "secured" のイベントが増えるだけです。特定ステータスだけを処理する既存の受け手には後方互換です。

2026-06-12 — v61: 出荷元変更(拠点間移動)の一覧 API + change-source の operator JWT 対応

追加

  • Operator Queues に GET /api/operator/source-changes を追加しました(LM-849)。出荷元変更(/api/routing/change-source)で起票された「移動すべきもの」の read 専用一覧で、送り側(旧出荷元 MFC)は fromSourceLocationId で梱包キューを、受け側(流山等の新出荷元)は toSourceLocationId で入荷待ちキューを取得します。status(CSV 複数可)・返送便の trackingNumber(入荷照合)でも絞り込めます。商品・拠点表示名・注文・unit 現在 status を enrich し、返送ラベルは hasReturnLabel / returnLabelGeneratedAt のみ(PDF パス・エラー本文は非公開)。

変更

  • Source Change の POST /api/routing/change-source が operator JWT(Authorization: Bearer)でも呼べるようになりました(LM-850・Routing write の 2 系統認証 に追加 = 11 エンドポイント目)。系統はヘッダの有無で明示判別し、既存の機械間クライアント(x-ingest-secret)の挙動は不変です。operator 経由は操作スタッフを記録します(起票 = opened_by_staff_user_id / 前進・中止 = updated_by_staff_user_id)。

2026-06-12 — v60: 住所不備キュー(labelErrorOnly)+ 住所修正の dry-run(validateOnly)

変更

  • Operator Queues の GET /api/operator/shipments に labelErrorOnly(true/1・任意)フィルタと各 shipment の hasLabelError(boolean・純 additive)を追加しました(LM-840)。ラベル発行エラー中(住所不備等で last_label_error が非 null)の shipment だけに絞る「住所不備キュー」として使えます。エラー本文はキャリア応答に住所断片が混ざりうるため一覧には出さず、真偽値のみ返します。住所を修正(Address Recovery)→ 再発行が成功(labelStatus: "generated")するとエラーがクリアされ、このフィルタから外れます(= 解消の判定)。絞り込みは一覧・サマリの双方に効きます。

  • Address Recovery の POST /api/routing/shipment/address に validateOnly(boolean・任意)を追加しました。true のときマージ + 国内必須項目の検証だけを実行し、保存・変更履歴・webhook は行わない dry-run です(UI の保存前バリデーション用。検証失敗は通常時と同じ 422 validation_failed + missing[])。既存のリクエスト / レスポンス契約は不変です。

変更

  • Shelf Link の POST /api/shelf/link に relink(boolean・任意)を追加しました。true のとき、shipment が既に別棚へ紐付け済みなら既存のアクティブ紐付けを manual_release で解除してから新しい棚へ付け替えます(200 + relinked: true + previousShelfCode。解除行は履歴として残ります)。省略時は従来どおり 409 shipment_already_linked でブロックします(自動付け替えはしません)。picking-ios の棚紐付け画面で「既に棚 X に紐付いています → 別の棚に紐付け直す」フローに使います。

  • Operator Lookup の GET /api/operator/shipments/by-tracking の各 shipment に shelfLink(アクティブな棚紐付け。shelfCode / locationId / linkedAt、未紐付けは null・純 additive)を追加しました。units[].shelfCode(引き当て在庫棚)とは別物で、こちらは shipment の置き場所棚(sot.lm_shelf_links)です。追跡番号スキャン時点で「既に棚 X に紐付け済み」を案内し付け替えフローへ誘導するために使います。既存フィールド・リクエスト契約は不変です。

2026-06-10 — v58: 追跡番号照会の unit にギフトラッピング要否(giftWrap)を追加

変更

  • Operator Lookup の GET /api/operator/shipments/by-tracking の各 unit に giftWrap(boolean)を追加しました(LM-827・純 additive)。ギフトラッピング要否を、line item property isGiftWrapping = "true"(sot.lm_fulfillment_units.line_properties に保持)または SKU に GIFT を含むかから導出して返します。出荷時のギフトラッピング確認(picking-ios)に使います。line_properties の生値は PII のためレスポンスに出さず、導出した真偽値のみを返します。既存フィールド・リクエスト契約は不変です。

2026-06-10 — v57: 出荷作業キュー一覧に出荷元(メンバー在庫集合)フィルタを追加

変更

  • Operator Queues の GET /api/operator/shipments に、選択中の出荷元(MFC/倉庫)で絞り込む fulfillmentSourceLocationId(uuid・任意)を追加しました(LM-815・純 additive)。指定すると、その出荷元の有効なメンバー在庫ロケーション集合(sot.lm_fulfillment_source_members の is_active=true な inventory_location_id)で from_location_id を IN 絞り込みします。出荷元自身もメンバー行(self)として登録されているため集合に含まれ、出荷元自身の自己在庫 shipment も拾います。この絞り込みは一覧・サマリ(totalCount / byStatus / unlabeled)の双方に効きます。

  • 単一ロケーション完全一致の fromLocationId とは用途が排他で、両方指定すると 400 です。メンバーが 0 件の出荷元は shop 全体に逃げず**空(該当 0 件)**を返します(フォールバックしません・Locations の memberOnly/LM-741 と同じ思想)。既存の公開リクエスト / レスポンス契約は不変です。

2026-06-10 — v56: 追跡番号で確保(Secure by Tracking)+ 追跡番号照会に棚番号を追加

追加

  • Secure by Tracking(POST /api/operator/secure-by-tracking)を追加しました(LM-778)。先行印刷された配送ラベルの追跡番号をスキャンして、その shipment(出荷元単位の梱包)配下の status=allocated ユニットを一括確保する operator 向け API です。案 A(MFC 配送ラベル先行印刷)の「ピック(棚スキャン)→ ラベル貼付 → 確保」動線の「確保」ステップを担います。ユニットQR で 1 件ずつ確保する Secure Scan と違い、追跡番号を解決キーにして shipment 配下の確保可能ユニットをまとめて確保し、案 A では確保時点でユニットが既に picked のことがあるため picked 済も含めて確保します。確保で shipment 配下の全ユニットが確保済になるとヘッダを secured に遷移させますが、先行生成済みラベルは再生成しません。レスポンスには各 shipment の確保数(secured / alreadySecured)・棚番号(shelves[])・ヘッダ結果を含みます。

  • 認証は operator JWT(Authorization: Bearer)または x-ingest-secret(dual auth)で、operator 経由の確保は secured_by_staff_user_id に操作者を記録します。冪等で、確保可能ユニットが無く既確保が居れば 200 + secured: 0、確保可能でも既確保でもないユニットしか無い shipment は 409 unit_not_securable、追跡番号に該当 shipment が無ければ 404 shipment_not_found で表面化します(fallback しません)。

変更

  • Operator Lookup の GET /api/operator/shipments/by-tracking の各 unit に shelfCode を追加しました(LM-774・純 additive)。ユニットの引き当て先(allocated_location_id)× barcode から、棚運用と同一規則(同一 (location, barcode) で qty>0 優先・同点は shelf_code 昇順の 1 棚)で棚番号を解決して返します。確保前の「追跡番号 → 棚表示」に使えます。棚を持たない店舗 / 同期拠点のユニットは null です。既存フィールド・リクエスト契約は不変です。

2026-06-09 — v55: 宛先住所・氏名の変更を完全な変更履歴として保存

変更

  • 宛先住所の手修正(Address Recovery の POST /api/routing/shipment/address)が、これまで sot.lm_routing_orders.ship_to_* を上書きするだけで変更前の値を残していなかった問題に対応し、変更のたびに append-only の変更履歴(sot.lm_routing_order_ship_to_changes)へ 1 行を記録するようにしました(LM-783)。各行に「変更前(before)/変更後(after)の宛先住所スナップショット」「変更した項目(changedFields)」「実施者(operator の staff_user_id または correctedBy)」「変更時刻」を残します。

  • 住所の更新と履歴記録を RPC で同一トランザクション(atomic)にしました(public.lm_routing_order_ship_to_update)。変更前の値は行ロック下に DB の現在値を読むため、真の before→after を取りこぼしなく記録します。実際に値が変わったときだけ 1 行を append するため、同じ住所での再 POST(冪等)は履歴を増やしません。

  • レスポンスに changedFields(今回の修正で実際に変わった shipTo 項目名の配列)を追加しました(純 additive。リクエスト契約・既存フィールドは不変)。

  • 変更履歴は受取人氏名・電話・メール・住所を含む PII のため service_role 専用です(公開 view / agent_read には出しません)。

2026-06-09 — v54: MFC ピック時に棚 qty を減算(出荷後の窓をゼロ化)

変更

  • 自己在庫 MFC のユニットを POST /api/operator/shelf/pick で picked にする瞬間(picked_at の未→確定遷移)に、そのユニットが置かれていた棚の qty を −1(reason=pick) してから自己在庫の available_qty を再計算(MFC Inventory LM-761 と同式)し、変化分を源在庫 webhook で販売面へ反映するようにしました(LM-769)。ピックはユニットが物理的に棚を離れる瞬間のため、出荷(shipped)を待たずに棚 qty が実態へ落ち、shipped 除外と合わせて「出荷後〜MFC が棚を再報告するまで」available_qty が一時的に過大になる窓(v52 で残課題として明記)がゼロになります。

  • 減算する棚は star ラベルが作業者に提示する棚(同一 (location, barcode) で qty>0 優先・同点は shelf_code 昇順の 1 棚)と一致させ、「作業者がピックした棚」と「qty を −1 する棚」を揃えました。ピックの取り消し(unpick)では棚 qty を +1(reason=receive) して対称に復元します。

  • 対象は自己在庫 MFC のみ(sot.lm_shelf_inventory に棚在庫を持つ出荷元)。棚を持たない店舗 / 同期拠点のユニットは該当棚が無いため no-op です。棚の増減と再計算は picked_at の遷移時のみ行うため二重減算しません。MFC が mode=absolute で棚を再報告すると棚 qty は物理実数へ上書きされ整合します(差分積算でないため二重減算なし)。

  • あわせて、available_qty / capacity(LM-768)の算出に使う「引き当て済み未出荷数」からピック済み(picked_at 確定)ユニットを除外しました(sot.lm_self_inventory_active_count に picked_at IS NULL を追加)。ピック時に棚 qty を物理減算するため、棚合計とアクティブ引当数の両方で引くと二重減算になり、同一 barcode に複数在庫があるとき available_qty が過少になっていたのを是正します(ピック確定の瞬間に available_qty が不変になる)。この除外はピック時の棚減算とセットで適用します。

  • 本リリースは公開リクエスト / レスポンス契約を変更しません(内部 SoT の棚 qty / available_qty 挙動のみ)。

2026-06-09 — v53: 受注情報更新(住所修正など)の webhook 通知を追加

追加

  • Order Update Webhook(POST /api/routing/order-update-webhook-config)を追加しました(LM-742)。Address Recovery(/api/routing/shipment/address)で受注の配送先住所を手修正すると、shop 単位で登録した宛先へ修正後の shipTo(絶対状態)と changeType / correctedAt / correctedBy を自動 POST します。変更種別 changeType を持ち、当面は住所修正(address_corrected)の 1 種です(将来、明細プロパティ修正など他の更新種別も同じ webhook に changeType を追加して載せられます)。

  • 既存 4 つの webhook(Source Inventory / Routing Allocation / Fulfillment Status / Oversell Status)と同一の outbox / 配信機構(テンプレートエンジン・暗号化 secret・リトライ・outbox 自動 drain / 再送)を共有する 5 本目の webhook です。住所修正成功直後にバックグラウンド送信し、操作レスポンスや住所修正処理の成否には影響しません。

  • 配送先住所(shipTo)は**個人情報(PII)**のため、outbox(sot.lm_order_update_events)は service_role 限定とし、公開 read view を作りません(request_payload も service_role 直のみ)。設定(sot.lm_order_update_webhook_config)の認証 secret は既存 webhook と同じ Vault 鍵で暗号化します。本リリースは既存の公開リクエスト / レスポンス契約を変更しません(住所修正レスポンスは不変・additive な webhook 発火のみ追加)。

2026-06-09 — v52: 自己在庫(MFC 棚付き入庫)を引き当て確定時に即時減算

修正(Bug)

  • 自己在庫(MFC Inventory で入庫する出荷元自前在庫)が引き当て後も available_qty から減算されず、源在庫 webhook(Webhooks)が phantom available を販売面へ push してオーバーセルしていた問題を修正しました(LM-761)。受注ルーティングは判定のみで在庫を書かず、自己在庫の available_qty は入庫 API の棚合算 set が唯一の更新経路だったためです。

  • 自己在庫の available_qty を派生量 max(0, 棚合計 − 引き当て済み未出荷数) として再計算する経路を追加しました(引き当て済み未出荷数 = sot.lm_fulfillment_units の allocated / secured / in_transit_to_mfc / packing)。引き当て(/api/routing/orders)・取消(/api/routing/cancel)・出荷元変更(/api/routing/change-source)・再引き当て(/api/routing/reallocate)・入庫(/api/ingest/mfc-inventory)の各点で再計算し、変化した自己拠点は源在庫 webhook で Shopify に反映します。再計算は確定値 set のため冪等で、committed_qty=0 の自己在庫では routable=available となり LM-526 と整合します。

  • 対象は自己在庫のみ(inventory_levels.source_system='mfc_inventory_ingest')。Shopify / smaregi 同期拠点は外部 push が在庫真実を持つため触りません(二重減算回避)。

  • 出荷後〜MFC の棚再報告までの窓(pick 時の物理棚減算)と、engine 判定の同時刻レース完全封じ込め(行ロック原子化)は別チケット(LM-769 / LM-768)に分離しています。本リリースは公開リクエスト / レスポンス契約を変更しません(内部 SoT の available_qty 挙動のみ)。

2026-06-09 — v51: MFC 入庫(棚付き)に mode(absolute / adjust)を追加

変更

  • MFC Inventory(POST /api/ingest/mfc-inventory)に top-level の mode を追加しました(LM-739)。mode=absolute(既定 / 省略時)は従来どおり各行の qty を絶対値で set(棚卸し的な確定)、mode=adjust は qty を符号付き差分として加減算します(+ 入庫 / - 減算)。mode 省略時の挙動は従来と完全に同一です(後方互換)。いずれの mode でも棚別在庫(sot.lm_shelf_inventory)の反映と barcode 集約 sot.inventory_levels.available_qty(ルーティング引当原資)への更新を同一トランザクションで行います。adjust で在庫が負になる行はバッチ全体を 409 insufficient_shelf_qty で reject します(部分適用なし)。adjust は差分加減算のため非冪等です(Idempotency)。なお adjust は棚在庫のみ反映する POST /api/shelf/inventory/receive とは別レイヤーで、本 API は引当原資(inventory_levels.available_qty)まで反映する点が異なります。

  • あわせて本ページのレスポンス例・エラー表・冪等性の記述を実装に合わせて是正しました(実レスポンスは { ok, applied, mode }。product_not_found はバッチ全体を 422 で中断、占有チェックは本 API には無い旨)。

2026-06-09 — v50: 拠点一覧を出荷元メンバーに絞り込む memberOnly

変更

  • Operator Locations(GET /api/operator/locations)に memberOnly クエリを追加しました(LM-741)。memberOnly=true(または 1)で、sot.lm_fulfillment_source_members の is_active=true な inventory_location_id に一致する拠点だけを返します(出荷が実際に流れる拠点のみ)。type 絞り込み(role 別)とは AND で、fallback はありません(member が 0 件なら空配列)。出荷元(MFC / 倉庫)自体も member 行(自己 member 登録を含む)が無ければ一覧に出ません。picking-ios(LM-737)の店舗選択 UI を、店舗・POPUP の全拠点ではなく出荷元メンバー拠点だけに絞るためのオプションです。既定(memberOnly 未指定)は従来どおり全アクティブ拠点を返します。

2026-06-09 — v49: ストア表示名(shopNames)をログインレスポンスに追加

変更

  • Operator Login の login / login/google / login/apple / me のレスポンスに shopNames(shop ドメイン → 表示名の map) を追加しました(LM-736・純 additive)。これまで picking-ios の shop / 拠点選択・設定画面は shop ドメイン(mybonaventura.myshopify.com)をそのまま表示していましたが、表示名(ブランド名)を inventory-os 側の単一ソースで一元管理し、アプリがドメインの代わりにブランド名を表示できるようにします。表示名が登録されている shop のみ map に含み、未登録の shop はキーに現れません(アプリはその shop のドメインをそのまま表示する graceful fallback)。既存の shops フィールドは変更ありません。

2026-06-09 — v48: セルフサインアップ(Operator Signup)を廃止

変更

  • POST /api/operator/signup を撤去しました(LM-723 / LM-724)。picking-ios はサインインのみのマーチャント業務アプリ(Shopify POS モデル)として一般公開する方針に変更したため、アプリ内のセルフサインアップを廃止します。スタッフアカウントはプラットフォーム / 管理者側で発行し、本 API は既存アカウントの認証(login / login/google / login/apple / refresh)のみを担います。これに伴い signup 専用の error_kind(weak_password / invalid_email / signup_disabled / user_already_exists)は廃止しました。アカウント作成がアプリ内に無くなるため、アプリ内アカウント削除(Apple 5.1.1(v))の要件も対象外になります(バックエンドの POST /api/operator/account/delete は残置)。

2026-06-09 — v47: 再引き当て(reallocate)の ok セマンティクスを明文化

ドキュメント

  • Oversell / Reallocate(POST /api/routing/reallocate)のレスポンス ok フィールドの意味を明記しました(挙動変更なし)。再引き当て先の在庫が無くても(status: no_stock / unresolvedReallocations > 0 / skipped > 0)ok: true のまま 200 で返り、ok: false になるのは入力不正(400)・注文不在(404)・dispatch 送信失敗(status: failed)に限ります。再引き当ての成否は ok ではなく status / unresolvedReallocations / skipped で判定する旨をレスポンスフィールド表と「挙動・冪等性」に追記しました。

2026-06-08 — v46: Apple サインイン(Operator Login with Apple)

新規

  • Operator Login(POST /api/operator/login/apple)— ピッキングアプリ(picking-ios)が Sign in with Apple で取得した Apple identity token を検証して operator JWT を発行する API を追加しました。アプリは Supabase の anon key を持たず api.lmile.io のみと通信する設計のため、inventory-os が Supabase Auth の signInWithIdToken(provider=apple)を代理します(Operator Login の Google サインインと同じプロキシ方針)。Google サインインを併設するアプリに同等の代替ログインを求める Apple ガイドライン 4.8 への対応です。認証は identityToken のみで完結し(email / fullName / user は初回のみ届く付随情報)、束縛 shop が 0 件(自己登録直後 / Hide My Email の新規ユーザー)でも ok: true + shops: [] で返してアプリのオンボーディングが shop 紐付けを担います。検証失敗は一律 401 invalid_id_token / 試行上限 429 rate_limited / 認証基盤不通 503 auth_unavailable(フォールバックなし)。

2026-06-08 — v45: MFC 入庫(棚付き)を operator JWT でも実行可能に

変更

  • MFC Inventory(POST /api/ingest/mfc-inventory)の認証を 2 系統(x-ingest-secret / operator JWT)に拡大しました(認証)。倉庫スタッフのピッキングアプリ(picking-ios)から棚付き在庫を直接入庫できます。系統はヘッダの有無で明示判別し、既存の機械間クライアント(x-ingest-secret のみ提示)の挙動は不変です。operator JWT で呼んだ場合は入庫操作者(検証済の auth.users.id)を棚在庫ログ(lm_shelf_inventory_logs.operator)に記録します(機械間経由は NULL)。これで 2 系統認証で呼べるエンドポイントは 10 になりました。

2026-06-08 — v44: アカウント削除(Operator Account Delete)

新規

  • Operator Login(POST /api/operator/account/delete)— ピッキングアプリ(picking-ios)の退会導線として、ログイン中スタッフ本人が自分のアカウントを即時削除できる API を追加しました。削除できるのは JWT の持ち主自身のみで、誤操作防止のため confirm: true が必須です。削除すると全セッション / refresh token が即時失効し、shop 束縛も解除されます。出荷作業などの操作履歴は匿名 UUID として保持し、メールアドレス(個人情報)は削除します。削除はメールアドレスの snapshot 付きで内部監査トレイル(sot.lm_operator_account_deletions)に記録します。デモアカウント(審査・デモ用)は 403 demo_account_protected で保護され削除できません。既に削除済みのアカウントへの再実行は 200 + deleted: true で冪等です(Idempotency / Error Codes)。

2026-06-08 — v43: セルフサインアップ(Operator Signup)

新規

  • Operator Signup(POST /api/operator/signup)— 倉庫スタッフ向けピッキングアプリ(picking-ios)が、メールアドレス + パスワードでセルフサインアップできる API を追加しました。アプリは Supabase の anon key を持たず api.lmile.io のみと通信する設計のため、inventory-os が Supabase Auth の signUp を代理します(Operator Login と同じプロキシ方針)。確認メール方式に従い、作成成功時は確認メールを送信して confirmed: false(JWT 未発行)を返し、スタッフは確認後に POST /api/operator/login で JWT を取得します。既存メールの重複は、メールアドレスの存在有無を漏らさないため新規と同じ confirmed: false に吸収します(user enumeration 対策)。パスワード強度不足 422 weak_password / 無効なメール 422 invalid_email / 試行上限 429 rate_limited / 認証基盤不通 503 auth_unavailable(フォールバックなし)。作成直後のアカウントは shop 未束縛です(認証 / Error Codes / Idempotency)。

2026-06-08 — v42: MFC 入庫(棚付き)エンドポイント(MFC Inventory)

新規

  • MFC Inventory(POST /api/ingest/mfc-inventory)— 大阪 MFC などの出荷元ロケーションに棚番号付きの在庫を絶対値で入庫する取込 API を追加しました。1 リクエストで棚別在庫(sot.lm_shelf_inventory)の (barcode × shelfCode) 絶対値 set と、その barcode を全棚で合算した販売可能在庫(sot.inventory_levels.available_qty)の更新を同一トランザクションで行います(部分適用なし・絶対値 set のため再送に冪等)。この入庫在庫は受注ルーティングで優先的に引き当てられ、MFC 引き当て時は Star ラベルに棚番号が印字されます。barcode 未登録の行は unresolved[] に返して skip します(Data Model / Idempotency / Error Codes)。

2026-06-08 — v41: 出荷ステータス遷移を operator JWT でも実行可能に

変更

  • Fulfillment(POST /api/routing/fulfillment)の認証を 2 系統(x-ingest-secret / operator JWT)に拡大しました(認証)。倉庫スタッフのピッキングアプリ(picking-ios)から確保済 → 梱包 → 出荷完了などの状態遷移を直接報告できます。系統はヘッダの有無で明示判別し、既存の機械間クライアント(x-ingest-secret のみ提示)の挙動は不変です。operator JWT で呼んだ場合は報告した出荷元ヘッダに操作スタッフ(検証済の auth.users.id)を記録します(status_reported_by_staff_user_id。機械間経由は NULL・非公開列)。これで Routing write の 2 系統認証は 9 エンドポイントになりました。

2026-06-07 — v40: 拠点一覧(Operator Locations)

新規

  • Operator Locations(GET /api/operator/locations)— ピッキングアプリ(picking-ios)の店舗(location)選択 UI 用に、shop のアクティブな拠点一覧(id / label / locationType / region)を返す read 専用 API を追加しました。type(location_type の CSV、例: store,popup)で拠点種別を絞り込めます。返る id は Operator Queues の fromLocationId フィルタにそのまま渡せます。認証は operator JWT です。

2026-06-07 — v39: 確保スキャン(Secure Scan)+ ユニットQR を本番印字の 2 値規格に統一

新規

  • Secure Scan(POST /api/operator/secure-scan)— 店舗スタッフが商品ラベルのユニットQR(<barcode>|<shipmentId>)をスキャンして在庫を 1 ユニットずつ確保する API を追加しました。QR からの解決(shipmentId → 注文)と対象ユニットの選定(allocated かつ 未 picked の lineInstanceNo 昇順先頭 1 件)をサーバ側で行うため、呼び出し側は QR をそのまま渡すだけです。出荷元の全ユニットが確保済になるとヘッダを secured に遷移させ、POST /api/routing/secure と同一経路で配送ラベルを自動生成します。再スキャンは冪等(alreadySecured・二重確保なし)。認証は operator JWT / x-ingest-secret の 2 系統です。

変更

  • ユニットQR の規格を本番印字形式(2 値)に統一 — Shelf Lookup(GET /api/operator/shelf/lookup / POST /api/operator/shelf/pick)の QR 形式を、出荷指示ラベルの本番印字形式である <barcode>|<shipmentId>(2 値)に修正しました(従来ドキュメントの LM2|... 4 値形式は印字実態と不一致のため撤回)。2 値は同一 barcode の複数ユニットを区別しないため、pick はスキャンごとに未 picked の lineInstanceNo 昇順先頭 1 件、unpick は picked の降順先頭 1 件(LIFO)を対象にし、レスポンスに units.total / units.picked(進捗)を追加しました。lookup は shipmentId の shipment 不在を 404 shipment_not_found で区別します(Error Codes)。

2026-06-07 — v38: 出荷作業キュー・引当不能注文の一覧(Operator Queues)

新規

  • Operator Queues — 倉庫スタッフ向けピッキングアプリ(picking-ios)が現場(店舗 / MFC)の作業量を pull で把握する一覧 API を公開ドキュメント化しました。出荷作業キュー一覧(GET /api/operator/shipments・location × status × 期間でフィルタ + フィルタ全体の status 別件数・未ラベル件数サマリ)と、引当不能(no_stock)のまま滞留している注文の一覧(GET /api/operator/unallocated-orders・Routing Allocation Webhook の unallocated イベントを見逃しても滞留に気づける pull 経路)です。いずれも read 専用・operator JWT 認証(API は提供済で、本リリースはドキュメントの追加です)。

2026-06-07 — v37: Allocation Webhook に出荷元(fulfillmentSourceLocationId)を追加

変更

  • Routing Allocation Webhook のペイロード変数に fulfillmentSourceLocationId(注文の出荷元 id = Routing リクエストの fulfillmentSourceLocationId)を追加しました。既定テンプレートにも同梱されます。unallocated(引き当て不能)イベントは shipmentId / fromLocationId が null で出荷元を特定できませんでしたが、本フィールドで「どの出荷元の注文が引き当て不能か」を受け手が解決できます(出荷元単位の通知・印刷用途)。追加のみの後方互換変更で、カスタム payloadTemplate 利用時は影響ありません。本フィールド追加前に起票済みのイベントが再送される場合は null です。

2026-06-07 — v36: operator Google サインイン(Operator Login)

新規

  • POST /api/operator/login/google — 倉庫スタッフ向けピッキングアプリ(picking-ios)のログインに Google サインインを追加しました。アプリ側で取得した Google ID token(idToken)を渡すと、POST /api/operator/login(email + password)と同形のレスポンス(operator JWT / refreshToken / staff / shops)を返します。staff↔shop 束縛はスタッフのユーザー単位なので、同じメールアドレスのスタッフは email + password ログインと同じ束縛 shop 群に解決されます。ID token の検証失敗は 401 invalid_id_token(Error Codes)。

2026-06-07 — v35: リカバリ系 3 エンドポイントの operator JWT 対応(Address Recovery / Print Label)

変更

  • リカバリ系 write の 2 系統認証 — 宛先住所修正 / ラベル再発行(/api/routing/shipment/address / /api/routing/shipment/retry-label)とラベル手動再印刷(/api/routing/shipment/print-label)の 3 つが、x-ingest-secret に加えて operator JWT(Authorization: Bearer)でも呼べるようになりました(Routing write の 2 系統認証は計 7 エンドポイント。系統はヘッダの有無で明示判別・フォールバックなし。既存の機械間クライアントの挙動は不変)。

  • operator JWT 経由の操作は操作スタッフを記録します — 住所修正は既存の監査列 sot.lm_routing_orders.ship_to_corrected_by にスタッフの検証済 ID(correctedBy ボディ値より優先)、ラベル再発行 / 手動再印刷は新設の sot.lm_fulfillment_shipments.label_retried_by_staff_user_id / label_printed_by_staff_user_id(Data Model)。

2026-06-07 — v34: 倉庫スタッフ向け Operator API(authentication / Operator)

新規

  • Operator API — 倉庫スタッフ向けピッキングアプリ(picking-ios)が呼ぶ /api/operator/* を公開ドキュメント化しました。スタッフ個人ログイン(POST /api/operator/login)で operator JWT を発行し、POST /api/operator/refresh で更新、GET /api/operator/me で id / email / 束縛 shop を取得します。照会 API(Operator Lookup)として追跡番号 → shipment + 注文 + 明細 + 配送先 + 状態(GET /api/operator/shipments/by-tracking)、バーコード → 商品(GET /api/operator/products/by-barcode)、追跡番号 / ステータスで売越しケース検索(GET /api/operator/oversell-cases)を追加しました。棚運用(/api/operator/shelf/*)は Shelf Lookup を参照してください。

  • 認証の 2 系統化を明文化 — 認証 に operator JWT(Authorization: Bearer)系統を追記しました。倉庫スタッフはスタッフ個人ログインで発行した JWT で /api/operator/* を呼び、操作できる shop は staff↔shop 束縛で制限されます(束縛 shop 外は 403 shop_not_authorized)。

  • Routing write の 2 系統認証 — 在庫確保(/api/routing/secure)・売越しマーク / 再引き当て(/api/routing/oversell / /api/routing/reallocate)・売越しケース(/api/routing/oversell-case)の 4 つは、x-ingest-secret と operator JWT のどちらでも呼べるようになりました(系統はヘッダの有無で明示判別・フォールバックなし。既存の機械間クライアントの挙動は不変)。operator JWT 経由の write は操作スタッフを記録します(sot.lm_fulfillment_units.secured_by_staff_user_id / sot.lm_routing_decisions.oversold_by_staff_user_id・created_by_staff_user_id / sot.lm_oversell_cases.opened_by_staff_user_id・updated_by_staff_user_id)。

  • sot.lm_operator_staff_shops(スタッフ ↔ shop の operator API 認可束縛)を追加(Data Model)。個人情報を含むため service_role 限定で agent_read.* / 公開 view には露出しません。

2026-06-07 — v33: 棚(シェルフ)運用 API(Shelf)

新規

  • Shelf API — 倉庫内の棚運用(picking-ios 移行)を routing-native に再構築した API 群を追加しました。配送ラベルの追跡番号 + 棚コードをスキャンして棚に出荷を割り当てる Shelf Link(POST /api/shelf/link)、棚在庫を barcode 単位で増減する Shelf Inventory(POST /api/shelf/inventory/receive / /pick)、ピッキングアプリ向けの照会・ピック Shelf Lookup(GET /api/operator/shelf/lookup / /by-code / POST /api/operator/shelf/pick)です。

  • 統合QR v2 規格 LM2|<barcode>|<routingOrderId>|<lineInstanceNo> を採用し、3 値で Units を per-unit で完全特定します(旧規格 JAN|FulfillmentOrderId は受理せず legacy_qr で再印刷を案内)。棚コードは ^[A-Z0-9]+(-[A-Z0-9]+)+$(英字必須・32 文字以内)に統一し、追跡番号との誤認を構造的に防ぎます。

  • 棚紐付けは shipment 単位で、確保済(secured)以降〜出荷前の shipment にのみ可能。出荷完了 / 取消で自動解除されます。棚在庫は qty 集約モデル(同一棚に複数 barcode 不可・同一 barcode は複数棚に分散可)で、増減は sot.lm_shelf_inventory_logs に append-only で記録します。ピッキング完了は配送 status と直交の作業状態として sot.lm_fulfillment_units.picked_at / picked_by で表現します。

  • write 系(link / inventory / pick)は x-ingest-secret または operator JWT(Authorization: Bearer)、read 系(lookup / by-code)は operator JWT で認証します。sot.lm_shelf_links / sot.lm_shelf_inventory / sot.lm_shelf_inventory_logs と sot.lm_fulfillment_units.picked_at / picked_by を追加(Data Model)。read 用 view public.lm_v_shelf_links / public.lm_v_shelf_inventory は内部 service / 管理用途で、agent_read.* には露出しません。

2026-06-07 — v32: 売越しケース受付完了通知(Oversell Status Webhook)

新規

  • Oversell Status Webhook — 売越しケースが MFC 倉庫で受付完了(warehouse_received)に遷移したときに shop 単位で登録した宛先へ通知する webhook を追加しました(既定イベント名 oversell_case_warehouse_received)。確保元ロケーション(foundLocationId)からの出庫分が MFC で受付完了したことを外部システムへ伝え、スマレジ等への入庫処理を実行する用途を想定しています。設定は POST /api/routing/oversell-status-webhook-config で upsert します。

  • ペイロードは受付完了の絶対状態(oversellCaseId / foundLocationId / status: warehouse_received)と明細 snapshot(lines = barcode / sku / productName / quantity、1 ケース = 1 単位のため常に 1 行)です。配信・リトライ・暗号化・耐久性(outbox)は既存 webhook と共通(Webhooks 概要)。outbox は UNIQUE (oversell_case_id) で二重発行を防ぎます。

  • sot.lm_oversell_status_webhook_config / sot.lm_oversell_status_events を追加(Data Model)。

2026-06-07 — v31: 在庫変動通知(Source Inventory Webhook)の並列配信

変更

  • Source Inventory Webhook の配信を並列化しました。これまではイベントを 1 件ずつ順次送信していたため、全量再同期などで数千件の変動が一度に発生すると配信に時間がかかっていました。今後は同時実行数の上限つきで並列送信します(同一 barcode のイベントは順序を保持)。受け手は複数 barcode の POST を同時に受け取ることがあります。ペイロード・認証・リトライの仕様に変更はありません。

2026-06-05 — v30: 出荷ラベルの出荷元プリンター自動印刷 + 手動再印刷

新規

  • ラベル自動印刷 — ラベル生成(Fulfillment の確保済遷移 / Retry Label)の成功直後に、出荷元の action: "print" 設定(Dispatch Config)があれば保存した PDF を出荷元の print server へ multipart/form-data(A5 / Cardstock)で自動送信するようになりました。印刷は best-effort で、失敗してもラベル生成・状態遷移は維持し last_print_error に記録します(レスポンスに printStatus を追加)。Source Change の返送ラベルも旧出荷元で自動印刷されます(returnLabelPrintStatus)。

  • POST /api/routing/shipment/print-label — 保存済みラベル PDF の手動再印刷。キャリア API を再呼び出ししないため追跡番号は変わりません(紙詰まり等の回収用)。

  • sot.lm_location_dispatch_config.action に print を追加(print は payloadTemplate 不要)。sot.lm_fulfillment_shipments に label_printed_at / last_print_error を追加(Data Model)。

2026-06-05 — v29: 顧客注文照会 API(Customer Orders)

新規

  • Customer Orders — 顧客のメールアドレスを突合キーに、注文履歴(POST /api/customer-orders/list)と注文詳細(POST /api/customer-orders/detail)を返す read API を追加。マイページ等の BFF から server-to-server で呼び出す想定です。注文ごとに 4 値の集約ステータス(processing / partially_shipped / shipped / cancelled)、明細(商品名・バリアント・数量・税込単価・画像)、金額(order_line_master 合算)、配送先、出荷元単位の追跡番号・出荷日時を返します。

  • 突合対象は Routing に shipTo.email 付きで投入された注文のみ(email の大文字小文字・前後空白は正規化して照合。sot.lm_routing_orders.ship_to_email_norm 生成列 + index を追加)。detail は email と注文の組み合わせを所有権チェックとして使い、不一致は 404 order_not_found(存在を判別させません)。

  • 配達完了(delivered)はキャリア配達イベントを持たないため返しません(終端は shipped)。送料・決済手段も SoT に存在しないため返しません(shipping: null / payment 無し)。

2026-06-04 — v28: LMile Apps(ホスト型ミニアプリ・プレビュー)

新規

  • Apps — イベントを検知して自動処理(外部システム連携・通知・LMile API への write-back)を実行するミニアプリを、LMile がホストする専用実行環境(1 アプリ = 1 VM、相互に隔離)で動かせるようになりました(プレビュー)。アプリは TypeScript の SDK(@lmile/app-kit)で handler を書くだけで、受け手サーバーの運用は不要です。既存の Webhooks(自前サーバーへの通知)と同じ発火点から並走して配信されるため併用できます。

  • 現在配信されるイベントは routing_allocation_decided(引き当て暫定確定)。fulfillment_shipment_status_changed / fulfillment_source_inventory_changed は準備中です。配信は outbox 記録 + at-least-once(Idempotency)。明細の properties(名入れ等)と配送先住所はアプリ向けイベントに含まれません(PII 保護)。

  • アプリの登録・デプロイ・環境変数の設定は現在 LMile 運用が行います(admin@lmile.io)。sot.lm_apps / lm_app_subscriptions / lm_app_deliveries / lm_app_executions を追加(Data Model)。

2026-06-04 — v27: 出荷ラベル設定の解決キーを出荷元(fulfillment source)に変更

変更

  • action=label の Dispatch Config は出荷元 location で解決 — 出荷ラベルを物理出力するのは引き当て店舗ではなく出荷元(MFC センター / 倉庫)のため、ラベル設定の解決キーを shipment の引き当て先在庫ロケーションから注文の出荷元(fulfillment source location)に変更しました。label 設定の locationId には出荷元 location を指定してください(create / update / cancel は従来どおり引き当て先在庫ロケーションで解決)。Source Change の返送便ラベルは旧出荷元 + tag(既定 return)で解決します。

  • ラベル再発行(/api/routing/retry-label)の skip 理由に fulfillment_source_unresolved(shipment 配下の unit から出荷元を特定できない場合)を追加。

  • ラベル PDF の Storage パス({shop}/{routingOrderId}/{fromLocationId}.pdf = shipment 単位)は不変です。

出荷元とその実在庫メンバーが同一 location の構成(単一倉庫など)では挙動は変わりません。出荷元配下に複数の店舗在庫メンバーを持つ構成では、メンバーごとに設定を複製せず出荷元 1 箇所に登録します。

2026-06-04 — v26: 引き当て暫定確定 webhook(Routing Allocation Webhook)

新規

  • Routing Allocation Webhook — Routing(/api/routing/orders)で在庫引き当てが暫定確定した直後に、引き当て先ロケーションごとに 1 通ずつ通知する webhook を追加。引き当て不能明細があれば unallocated イベントを 1 通追加送信します(全量在庫不足 = no_stock 含む)。設定は POST /api/routing/allocation-webhook-config(shop 単位。既存 webhook と同じ設定スキーマ / ペイロードテンプレート / リトライ / outbox / secret 暗号化)。

  • 明細(lines)は起票時の引き当て結果を outbox(sot.lm_routing_allocation_events)に snapshot して送信します(出荷指示と同じ barcode × properties 単位の行に、商品情報 sku / productName と明細単位の任意キー/値 properties を同梱)。後続の売越し再引き当て・出荷元変更で引き当てが変わる場合があるため、確保以降の進捗は Fulfillment Status Webhook で追跡してください。

2026-06-04 — v25: ロケーション単位の Star プリンター設定 API

新規

  • Star Printer(/api/routing/star-printer)— 在庫ロケーションに Star プリンターの device ID を紐付ける設定 API を追加。設定(upsert)/ 解除(detach)/ 一覧(GET)。キーは (shop, locationId) = 1 ロケーション 1 プリンターで、再設定は device ID の差し替えになります。sot.lm_location_star_printers に保存します。

2026-06-04 — v24: routing 明細単位の properties(line item property 相当)

新規

  • lines[].properties — Routing(/api/routing/orders / /api/routing/update)の受注明細に、明細単位の任意キー/値(刻印テキスト・名入れ・ギフト指定等。Shopify line item property 相当)を渡せるようになりました。object 形式(最大 20 キー、キー 100 文字・値 500 文字以内)。sot.lm_routing_decisions.line_properties / sot.lm_fulfillment_units.line_properties に保存し、出荷指示(shipments[].lines[] / unroutableLines[] / serviceLines[])→ Picking List(JSON items[].properties + PDF 1 行表示)→ Dispatch Config の WMS / label テンプレート($each 内 {{properties.<キー>}})まで透過します。Reallocate / Source Change でも後継 decision へ引き継がれます。

  • テンプレート変数の日本語キー対応 — payloadTemplate の {{path}} が {} と空白を除く任意の文字を受け付けるようになり、{{properties.刻印}} のような日本語キーを参照できます。

変更

  • 同一 barcode 複数明細の引き当て修正 — 同一 barcode の明細が複数ある注文(properties 違い等)で、在庫を二重参照して二重引き当てになり lineInstanceNo が衝突する問題を修正。明細は barcode 単位に合算して 1 回で引き当て、unit へ元明細の順に properties を配り戻します。出荷指示・ピッキングリストは barcode × properties 単位で行を分けて集計します。

properties は名入れ等で顧客 PII になり得るため、agent_read には公開しません。properties 導入前に保存された出荷指示の明細は properties: null として扱われます(後方互換)。Ship&Co ラベルアダプタの送信 payload は不変です。

2026-06-04 — v23: ドキュメント再構成(Webhooks セクション新設)

変更

  • ナビゲーションを機能別セクションに再編 — Getting Started / Ingestion / Routing / Fulfillment / Oversell / Configuration / Webhooks / Reference。2 種の webhook を Webhooks に集約し、共通機構(設定・ペイロードテンプレート・リトライ・outbox・暗号化)を概要ページに一本化。

  • 共通記述の集約 — 共通エラーは Error Codes、冪等性は Idempotency を正とし、各エンドポイントページはエンドポイント固有の挙動のみを記載。

  • 移動したページの旧 URL はリダイレクトされます。curl サンプル集(examples/curl)は各エンドポイントページのリクエスト例に集約し廃止。

API 自体の変更はありません(エンドポイント・パラメータ・挙動は不変)。

2026-06-04 — v22: 出荷ステータス webhook に出荷明細(lines)を同梱

変更

  • Fulfillment Status Webhook の既定テンプレート拡張 — ペイロードに shipmentId(sot.lm_fulfillment_shipments.id。受信側の冪等キー用)と lines(shipment 配下の sot.lm_fulfillment_units を barcode 単位に集約した [{ "barcode", "sku", "quantity" }])を追加。受信側が注文全体ではなく出荷された明細だけを外部システム(Shopify 等)の出荷済みに反映できるようにする。

  • units の取得失敗・0 件時は lines 無しのまま送信せず delivery_status: failed(last_error: units_fetch_error / no_units_for_shipment)として残し、再送 endpoint で回収する。

  • カスタム payloadTemplate 利用時は新変数 {{shipmentId}} / {{lines}}(単一変数で配列型を保持)を任意で利用可能。既存テンプレートの挙動は不変。

2026-06-04 — v21: 非在庫サービス品をルーティング対象から除外

変更

  • 非在庫サービス品の除外 — 物理在庫を持たないサービス/カスタム明細(刻印サービス等)が在庫ベースのルーティングで恒久的に no_stock_anywhere / unroutableLines ノイズになる問題を解消。sot.products.is_non_inventory = true の商品は在庫引き当ての対象外になり、出荷指示の新フィールド serviceLines[](barcode / quantity)に分類されます(Routing — 受注ルーティング)。

  • 判定根拠は従来どおり sot.lm_routing_decisions に記録(selected_reason: non_inventory_service / selected_location_id: null)。/api/routing/orders / /api/routing/update / /api/routing/reallocate の全経路に適用。

  • フラグの設定は ops の明示操作のみ(SKU や品名による自動判定はしない)。products ingest は本列を上書きしません。

serviceLines は出荷指示(レスポンス / 保存 payload)レベルのフィールドです。per-location の WMS dispatch payload(Dispatch Config テンプレート)には従来どおり引き当て済みの lines のみが渡ります。

2026-06-04 — v20: ルーティング引き当てを available + committed で判定

変更

  • 自己予約レースの解消 — 受注ルーティングの引き当て可能数を available_qty のみから routable = available_qty + committed_qty に変更。Shopify の available は注文作成の瞬間に committed へ移って減るため、約10分後にルーティングが走る頃には available=0 となり、その注文のために確保済みのユニットへ引き当てられず no_stock になっていた。committed を足し戻すことで物理確保分(reserved/damaged/safety を除く)へ正しく引き当てる。

  • 在庫取込の拡張 — Inventory Levels(POST /api/ingest/inventory-available)が任意の committed_qty / on_hand_qty を absolute で受領(省略時は据え置き。available の absolute/delta・冪等・clamp は不変)。変更は sot.inventory_update_logs に committed_set / on_hand_set で記録。

  • sot.inventory_levels.committed_qty 列を追加(agent_read.inventory_levels view にも露出)。判定根拠用に sot.lm_routing_candidates.committed_qty_at_decision を追加。

available のみを送る取込経路(committed を持たない POS 等)は従来どおり routable = available で判定されます(committed 省略=据え置き=0)。

2026-06-03 — v19: 注文取消の内部状態 cascade

変更

  • Cancel の内部 SoT 同期 — POST /api/routing/cancel(Cancel / Update)が、注文ヘッダ(lm_routing_orders.status=cancelled)と WMS への cancel dispatch に加えて、出荷元ヘッダ lm_fulfillment_shipments / 単位明細 lm_fulfillment_units を status='cancelled'(+ cancelled_at)に、出荷指示 lm_shipping_instructions を delivery_status='cancelled' に同期します。shipped(出荷完了)は終端として保護し上書きしません(追跡番号・ラベル PDF は温存)。

  • レスポンスに cascade 件数(cancelledShipments / cancelledUnits / shippingInstructionCancelled)を追加。

  • 集計 view lm_v_routing_order_fulfillment(cancelled_count)/ lm_v_routing_order_unit_fulfillment(cancelled_unit_count)に cancelled 分類を追加。

在庫数量(inventory_levels)は「状態のみ」方針のため変更しません。WMS への cancel dispatch 経路(Dispatch Config の action: "cancel")は従来どおりです。

2026-06-03 — v18: 出荷ステータス変動 webhook

新規

  • Fulfillment Status Webhook — Fulfillment(POST /api/routing/fulfillment)で出荷元(shipment)の status が直前の値と変わったとき(初回報告含む)に、shop 単位で登録した宛先へ POST で通知(Fulfillment Status Webhook)。設定は POST /api/routing/status-webhook-config(shop 単位・authSecret は pgcrypto 暗号化・payloadTemplate 省略可)。

  • 即時かつ軽量: フルフィルメント報告の成功直後にバックグラウンド送信。注文レスポンスは遅延させない。ペイロードには status / previousStatus / trackingNumber / carrierCode / externalOrderRef 等を含む。

  • sot.lm_fulfillment_status_webhook_config(送信設定・UNIQUE (shop))/ sot.lm_fulfillment_status_events(status 遷移イベント outbox + 送信ログ)+ 読み取り view lm_v_fulfillment_status_webhook_config(secret 除外)/ lm_v_fulfillment_status_events。暗号鍵は Vault lm_dispatch_enc_key を共有。

  • 耐久性: 送信前にプロセスが落ちても pending / failed の event は outbox に残り、回収・再送できる。

2026-06-03 — v17: Ship&Co 配送ラベル + 宛先住所修正・ラベル再発行

新規

  • Ship&Co ラベルアダプタ — Dispatch Config の action=label に adapterType=shipandco を追加。Ship&Co API(https://api.shipandco.com/v1/shipments / x-access-token)向けに、県名正規化・電話整形・市区町村の address1 前置・商品配列フィルタといった手続き的変換を行ってラベル発行し、delivery.label(URL) から PDF を取り込み(shipping-labels バケット)。carrierId / fromAddress 等は payloadTemplate に静的設定、API トークンは pgcrypto 暗号化(ソース直書きしない)。Fulfillment の確保済遷移で自動発行。

  • Shipment Address Recovery — ラベル発行が宛先住所不備で失敗したケースのリカバリ(Shipment Address Recovery)。POST /api/routing/shipment/address(宛先住所の部分上書き + 国内必須住所検証 + 監査列更新)/ POST /api/routing/shipment/retry-label(失敗した出荷元のラベル再発行・二重発行ガード)。

  • 宛先住所は sot.lm_routing_orders.ship_to_* を単一ソースとして保持・更新(出荷ラベル生成もこの行から読む)。監査列 ship_to_corrected_at / ship_to_corrected_by を追加(PII 列同様に公開 view から除外)。

移植元(MFC の Ship&Co 連携)には無かった住所修正・再発行の導線を inventory-os の fulfillment レイヤーに新設。代引き / 配達希望日時 / 刻印返送(Shopify 注文固有)は対象外。

2026-06-03 — v16: マーチャント単位の ingest API キー(shop スコープ)

新規

  • per-merchant API キー — x-ingest-secret に発行済みの API キーを渡すと、そのキーにひも付いたストア(shop)にのみ ingest / routing できます。1 キー = 複数 shop も可。ボディの shop がキーの範囲外の場合は 403 shop not authorized for this key(認証)。

  • 既存のサーバー間連携(LastMile 運用の取込アプリ)はこれまでどおり動作します(admin global secret = x-ingest-secret の env 値はそのまま・後方互換)。

キーの平文は発行時に一度だけ返されます(DB には sha256 ハッシュのみ保存)。発行・失効は admin@lmile.io。

2026-06-03 — v15: 出荷元変更(返送→別拠点出荷)

新規

  • Source Change — 引当先(出荷元A)では加工できないため別の出荷元B へ返送してから出荷するケースの管理 sot.lm_fulfillment_source_changes(change_requested → return_in_transit → return_received + cancelled)。POST /api/routing/change-source(起票 + 前進の単一 advance)(Source Change)。

  • 出荷元の切替 — 起票時に旧 decision を superseded・新 decision(出荷元=B)を applied にし、unit の 3 ロケーション列(引当 / 出荷元 / 現在在庫)を更新。旧出荷元A へ cancel、受領時に新出荷元B へ create を dispatch。最終出荷ラベルは B 受領後に既存 /api/routing/secure で生成。

  • 返送便ラベル自動生成 — 起票時に A 拠点の action=label + returnTag 設定で返送便(A→B)ラベルを生成し追跡番号 + PDF を取り込み。送付先 B の住所はテンプレートに定義。generateAndStoreLabel に pathKey を追加し顧客出荷ラベルと衝突回避。

  • sot.lm_fulfillment_units.status に source_change_pending / source_change_in_transit を追加。注文集計 view lm_v_routing_order_unit_fulfillment に source_change_unit_count + source_changing 分類を追加。読み取り view lm_v_fulfillment_source_changes。

Oversell / Reallocate(同一出荷元内の振替)や in_transit_to_mfc(出荷元は変えず現在在庫のみ移動)とは別経路。在庫は状態のみで inventory_levels は不変。

2026-06-03 — v14: 出荷元の合算在庫変動 webhook

新規

  • Source Inventory Webhook — 出荷元の member 在庫ロケーションが在庫取込で更新され、その出荷元の barcode 単位の合算 available_qty(= member の available_qty 合算)が前回送信値と変わったときに、登録した宛先へ POST で通知(Source Inventory Webhook)。設定は POST /api/routing/source-webhook-config((shop, fulfillment_source_location_id) 単位・authSecret は pgcrypto 暗号化・payloadTemplate 省略可)。

  • 即時かつ軽量: 在庫取込(/api/ingest/inventory-snapshot / /api/ingest/inventory-available)の成功直後にバックグラウンド送信。取込レスポンスは遅延させない。送信は合算の絶対値(差分でない)。

  • sot.lm_fulfillment_source_webhook_config(送信設定)/ sot.lm_fulfillment_source_inventory_state(前回送信した合算値 = dedup)/ sot.lm_fulfillment_source_inventory_events(変動イベント outbox + 送信ログ)+ 読み取り view lm_v_fulfillment_source_webhook_config(secret 除外)/ lm_v_fulfillment_source_inventory_events。

2026-06-03 — v13: ピッキングリスト生成(JSON / PDF 作業指示書)

新規

  • Picking List — POST /api/routing/picking-list。ルーティング済み注文(routingOrderId または sourceSystem + externalOrderRef)から在庫ロケーション単位のピック内容を生成(Picking List)。

    • format=json は構造化データ(商品名 / SKU / imageUrl / 数量、ロケーション別 + 引き当て不能)。

    • format=pdf は出荷元ロケーション単位の作業指示書(A4・IPAex ゴシック埋め込み・スキャン用 CODE128 バーコード・商品画像・1 点 1 行のピックチェック枠)。locationId 指定で単票を本体返却(X-Picking-List-Url)、省略時は全拠点分を生成し JSON で URL 一覧を返却。Storage bucket picking-lists(public read)。

  • sot.lm_picking_lists(生成ログ・append-only)+ 公開 view lm_v_picking_lists + Storage bucket picking-lists を追加。sot.products.primary_image_url を商品画像に利用。

2026-06-03 — v12: 単位ステータス + 在庫確保 + 店舗→MFC移動 + 売越しケース

新規

  • Fulfillment Units — order_line_master 方式の単位明細 sot.lm_fulfillment_units(1 行 = 1 単位・数量列なし)。barcode / sku / 引当ロケーション / 出荷元 / 現在在庫ロケーション(店舗→MFC で更新)/ status / 在庫確保フラグ。ヘッダ lm_fulfillment_shipments にリンク(Fulfillment Units)。

  • 在庫確保 — POST /api/routing/secure(単位ごとに確保。出荷元ヘッダの全単位確保で secured 遷移 + ラベル生成)。一部確保は partially_secured(public.lm_v_routing_order_unit_fulfillment)。在庫は状態のみで inventory_levels は不変。

  • 店舗→MFC 移動 — /api/routing/fulfillment の status: "in_transit_to_mfc" に targetMfcLocationId を追加。単位の現在在庫ロケーションを MFC へ更新(状態遷移を単位へ cascade)。

  • Oversell Cases — 売越しの 8 ステップ管理 sot.lm_oversell_cases(発生→探索→連絡→確保→出庫依頼→出庫→追跡番号→MFC受付完了 + wont_do)。POST /api/routing/oversell-case(起票 + 前進の単一 advance)。LM-498 の自動再引き当てとは独立共存(Oversell Cases)。

Shopify fulfillment order id 非依存(routingOrderId / sourceSystem+externalOrderRef / barcode+lineInstanceNo で特定)。追跡番号・ラベル PDF は梱包単位=出荷元ヘッダに保持(単位に重複させない)。

2026-06-03 — v11: 出荷元の状態遷移 + 確保済ラベル生成

新規

  • Fulfillment — POST /api/routing/fulfillment(出荷元 from-location 単位の状態遷移を報告。確保済→移動中→梱包→出荷完了 + 売越サブ状態)(Fulfillment)。

  • 確保済ラベル生成 — secured / oversell_secured への遷移時に action: "label" 設定で送信先(キャリア API / 印刷 agent)へ POST し、応答から追跡番号 + ラベル PDF を取り込み。PDF は Supabase Storage shipping-labels(private)に保存。

  • Dispatch Config を label 対応 — action に label を追加し、応答マッピング responseMapping(trackingNumber / carrierCode / labelPdfBase64 / labelPdfUrl)を登録可。

  • sot.lm_fulfillment_shipments(出荷元単位の状態 + 追跡番号 + ラベル PDF パス)+ 読み取り view lm_v_fulfillment_shipments / 注文集計 view lm_v_routing_order_fulfillment。

2026-06-03 — v10: 受注ルーティングの取消・更新 + action別ディスパッチ

新規

  • Cancel / Update — POST /api/routing/cancel(注文を cancelled にし cancel を dispatch)+ POST /api/routing/update(最新内容で再ルーティングし update を dispatch)(Cancel / Update)。

  • Dispatch Config を action 対応 — 設定を (shop, location, tag, action) で保持。action(create/update/cancel) 別に宛先/テンプレートを登録可。dispatch は action 完全一致 + tag 一致優先で解決。

  • sot.lm_routing_orders.status に cancelled 追加。lm_location_dispatch_config / lm_location_dispatch_log に action 列。

2026-06-03 — v9: routing tag + tag条件ディスパッチ + 配送先住所の詳細化

新規 / 変更

  • /api/routing/orders に tag(任意・単一)を追加 — ディスパッチ先(WMS)選択の条件。引き当て自体には影響しない。

  • Dispatch Config を tag 対応 — (shop, location, tag) で設定。注文 tag に一致する設定を優先、無ければ tag=NULL 既定(POST /api/routing/dispatch-config に tag 追加)。

  • 配送先住所の詳細化 — shipTo に name / company / phone / email / address1 / address2 を追加(Shopify MailingAddress / ship&co 準拠。全任意)。出荷指示・ディスパッチテンプレートの変数として利用可。

  • PII 是正 — 公開 view lm_v_routing_orders から詳細配送先(氏名/会社/電話/email/住所)を除外(service_role 直アクセスのみ)。

2026-06-03 — v8: 出荷元↔ロケーション マッピング管理 API

新規

  • Source Members — 出荷元↔在庫ロケーションのマッピングを API で管理(Source Members):

    • POST /api/routing/source-members 設定(upsert。キー shop + inventoryLocationId、別出荷元への付け替え可、isActive で論理無効化)

    • POST /api/routing/source-members/detach 解除(物理削除)

    • GET /api/routing/source-members?shop=... 状況取得(ラベル付き一覧)

2026-06-03 — v7: 引き当て先ロケーションの明示指定

  • /api/routing/orders に任意の inventoryLocationId を追加。指定時は出荷元のその在庫ロケーションのみに引き当て(他メンバーへ振らない)。指定 location が出荷元にマッピングされていなければ 422 location_not_member_of_source。

2026-06-02 — v6: per-location WMS ディスパッチ設定(テンプレート送信)

新規

  • Dispatch Config POST /api/routing/dispatch-config — 在庫ロケーション単位で WMS 宛先 URL・認証・ペイロードテンプレート({{barcode}}/{{sku}}/{{quantity}} 等の変数差し込み + $each 配列展開)を登録。authSecret は pgcrypto 暗号化保存(鍵 = Supabase Vault)。sot.lm_location_dispatch_config / lm_location_dispatch_log を追加(Dispatch Config)。

変更

  • 引き当て確定時の外部送信を per-location 設定駆動に変更。/api/routing/orders・/api/routing/reallocate のレスポンスは単一 dispatch → dispatches[](ロケーションごとの送信結果)。旧 単一 env 宛先(ROUTING_FULFILLMENT_URL)は撤去。

2026-06-02 — v5: 出荷元(fulfillment source)モデル + 売越し・再引き当て

破壊的変更

  • /api/routing/orders に fulfillmentSourceLocationId(必須)を追加。受注は出荷元ロケーションIDを必須で受け取り、その出荷元に紐づく在庫ロケーション(member)内だけで引き当てます。ec_fulfillable 横断のルーティングは廃止。

新規

  • 出荷元 ↔ 在庫ロケーション 紐付け sot.lm_fulfillment_source_members(1出荷元 : N在庫)。出荷元の販売可能在庫はメンバー在庫の合算。

  • Oversell / Reallocate POST /api/routing/oversell(売越しフラグ)+ POST /api/routing/reallocate(同一出荷元の別メンバーへ再引き当て)。lm_routing_decisions に fulfillment_source_location_id / oversold / superseded_by_decision_id を追加(Oversell / Reallocate)。

2026-06-02 — v4: Routing API を inventory-os に一本化

新規

  • Routing API POST /api/routing/orders — cart-agnostic 受注ルーティング。出荷元拠点の判定 → canonical 出荷指示の生成 → 外部 fulfillment への dispatch を 1 リクエストで実行。x-ingest-secret 認証・shop はボディ(入力フィールドは camelCase)。

  • 永続モデル追加: sot.lm_routing_orders / lm_shipping_instructions、および lm_routing_decisions の routing_order 経路拡張(Data Model)。

アーキテクチャ変更

  • routing 公開 API を inventory-os(Hono)に一本化。これにより取込(ingest)と受注ルーティングが同一サーバー・同一認証(x-ingest-secret / shop ボディ)に統一されました。

2026-06-02 — v3: Base URL を api.lmile.io に変更

  • Base URL が https://api.lmile.io に変更(ingest 専用カスタムドメイン)。旧 https://inventory-os.fly.dev も当面エイリアスとして利用可能ですが、新規連携は api.lmile.io を使用してください。

2026-05-24 — v2: Products + Inventory API

新規

  • Products API POST /api/products/bulk-upsert — 商品マスター一括登録・更新。価格変更ログ自動記録。

  • Inventory Levels API POST /api/inventory-levels/bulk-upsert — 絶対値 + delta 両対応。欠品自動検知 (stock_zero)。

  • Inventory Daily Snapshots — 日次 cron で全在庫を毎日スナップショット保存。

破壊的変更

  • External Signals API 廃止 — POST /rest/v1/external_signals (Supabase PostgREST 直接) は使用不可。

  • Pixel Events API 廃止 — POST /api/pixel-events は使用不可。

  • Shopify Webhooks 自動購読 廃止 — Webhook 依存から外部アプリ push モデルに移行。

  • DB スキーマ再構築 — sot / agent_runtime / agent_read / public の 4 スキーマに分離。旧テーブルは全て削除。

アーキテクチャ変更

  • 全データは外部アプリが API 経由で push する設計に統一。

  • Base URL が inventory-os.fly.dev に統一(外部アプリ push モデル)。

  • 認証が Supabase service_role から x-cron-secret + x-shop ヘッダーに変更。

Last updated

Was this helpful?