コンテンツにスキップ

ProductVariant の用途分類と通常カート追加可否

目的

商品ラインナップには出さないが、キャンペーンギフト、サンプル同梱、ポイント調整、マイナス価格行など、システムが注文へ投入する SKU を安全に扱うための正本を定義する。

合意日

  • 2026年5月25日

原則

  • ProductVariant.enabled は商品マスタとして有効かどうかを表す。ギフト・サンプル・内部調整 SKU を顧客導線から隠す目的では OFF にしない。
  • 表示可否は visibility rule を正本にする。storefrontHidden のような表示専用 custom field は使わない。
  • 用途分類は既存 Facet product-type に寄せる。product-type は製品種別と、ギフト・サンプル・内部予約 SKU などの role を兼ねる。
  • 顧客が通常導線から能動的にカート追加できるかは、ProductVariant custom field customerAddable で表す。
  • 同じ sample でも、能動購入できるサンプルと、受動的に 0 円同梱されるサンプルを分ける。差分は sample FacetValue ではなく customerAddable で表す。

データモデル

product-type Facet

既存の product-type Facet を維持し、次の FacetValue を required baseline と runtime drift audit の対象にする。

code name 用途
gift ギフト キャンペーンギフト・おまけとしてシステム投入する SKU
sample サンプル サンプル品。能動購入・受動同梱のどちらもこの role を使う
system システム ポイント調整、マイナス価格、内部予約 SKU など

既存の skincaremachine-consumablesretailprofessionalpromotion などの製品種別は維持する。同一 Product / ProductVariant が複数の product-type FacetValue を持ってよい。

customerAddable

ProductVariant.customFields.customerAddable: boolean

意味
true visibility rule で許可されていれば、顧客の通常 addItemToOrder を許可する
false 顧客の通常 addItemToOrder / 通常 adjustOrderLine を拒否する

default は true。これは表示状態ではなく、通常カート追加可否の system 判定である。

代表パターン

パターン product-type customerAddable 表示制御 カート投入
通常商品 既存製品種別 true visibility rule 通常追加可
能動購入サンプル sample true visibility rule 通常追加可
受動付与サンプル sample false visibility rule で非表示にできる marker 付き内部投入のみ
キャンペーンギフト gift false visibility rule で非表示にできる campaignGift / campaignMarker 付きのみ
ポイント・調整 SKU system false visibility rule で非表示にできる point adjustment 等の marker 付きのみ
セット構成品 既存製品種別 通常は false visibility rule で非表示にできる SET_COMPONENT: marker 付き内部投入のみ

visibility rule との関係

visibility policy の conditions.targets.facetValueIds は Product / ProductVariant の FacetValue ID を評価対象に含める。

  • facetValueIds は商品軸条件として扱う。
  • Product 側と Variant 側の FacetValue を合算して評価する。
  • product-type=gift / sample / system を allow / deny 条件に使える。
  • 商品一覧、検索、Quick Order、商品詳細は visibility rule を正本にして表示可否を決める。

customerAddable=false でも visibility rule が許可すれば画面に表示できる。ただし通常カート追加は server-side で拒否される。表示と購入可否を混ぜないため、この挙動を許容する。

通常カート追加の server-side guard

Shop API の通常 addItemToOrder / adjustOrderLine は次の条件を満たす場合だけ許可する。

  1. 内部投入 marker がない。
  2. 対象 ProductVariant が visibility rule で現在の顧客に許可されている。
  3. customerAddable !== false

内部投入 marker がある場合は、visibility / customerAddable=false を bypass できる。現行 marker は次を許可する。

marker 用途
campaignGift === true キャンペーンギフト
campaignMarkercamp: で始まる キャンペーン由来の内部投入
specialPricingSET_COMPONENT: で始まる セット構成品の内部投入
sampleGrant === true 将来のサンプル同梱
pointAdjustment === true 将来のポイント・調整行

marker は注文行 custom field で明示し、通常顧客操作と内部処理を区別する。既存注文行に marker が残っていても、通常の数量変更 input に marker が無ければ通常操作として判定する。

運用ルール

  • ギフト・受動サンプル・内部調整 SKU は enabled=true のまま、product-type role と visibility rule で顧客導線から外す。
  • 顧客が能動的に買えるサンプルは product-type=sample + customerAddable=true にする。
  • 受動同梱だけのサンプルは product-type=sample + customerAddable=false にする。
  • ポイント調整やマイナス価格 variant は product-type=system + customerAddable=false にする。
  • visibility rule の deny 条件として hidden Facet は使わない。非表示は visibility policy で表現し、用途分類は product-type で表現する。

受け入れ観点

  • product-type=sample + customerAddable=true は visibility rule で許可されていれば表示・通常追加できる。
  • product-type=sample + customerAddable=false は visibility rule で非表示にでき、直接通常追加も拒否される。
  • product-type=gift / system + customerAddable=false は marker 付き内部投入だけ通る。
  • visibility policy の facetValueIds 条件で product-type=gift/sample/system を allow / deny できる。
  • 通常商品は既存の表示・購入挙動が変わらない。
  • required baseline / runtime drift で product-type 追加値の欠落を検出できる。