2026-03 同意スコープの Product / Variant 両対応仕様¶
背景¶
- SMILE 連携では
SKU = Variantが正本であり、同一 Product に複数 SKU を手動 regroup できる。 - 同意要件を Product にしか持てないと、SKU 固有の同意を表現できず、regroup 後に同意要件が混線する。
- 一方で、商品全体で共通の同意も引き続き必要である。
決定事項¶
- 同意設定は
ProductとProductVariantの両方に持てる。 - 解決順は
Variant 優先 / Product フォールバックとする。 ConsentRecordはproductIdに加えてvariantIdを持てる。- SKU 固有同意は
variantId単位で記録・再利用判定する。 - 商品共通同意は
productId単位で記録・再利用判定する。
対象フィールド¶
consentRequiredconsentIdsconsentInstructionsconsentTemplateIdconsentNoteHtmlconsentChecklist
同意判定の正本は consentRequired / consentIds / consentInstructions /
consentTemplateId だが、表示用の consentNoteHtml / consentChecklist
も同じ優先順位で解決し、Shop API から ProductVariant.customFields に公開する。
解決ルール¶
1. 同意が必要か¶
Variant.customFields.consentRequiredが boolean で明示されていれば、それを使う。- Variant 側が未設定なら
Product.customFields.consentRequiredを使う。 - どちらにも明示値がない場合は
consentIdsの有無から推定してよい。
2. 必要な同意ID¶
Variant.customFields.consentIdsが 1 件以上あれば、それを使う。- Variant 側が空なら
Product.customFields.consentIdsを使う。 - 上記が両方空なら、既定テンプレートや legacy heuristic にフォールバックしてよい。
3. 同意テンプレート¶
Variant.customFields.consentTemplateIdがあれば、それを最優先する。- Variant 側が未設定なら
Product.customFields.consentTemplateIdを使う。 - それでも無ければ同意IDから既定テンプレートを引く。
4. 補助文言¶
consentInstructionsなどの表示用フィールドも、Variant 明示値があれば Variant を使い、無ければ Product を使う。consentNoteHtml/consentChecklistも同じく Variant 明示値を優先し、未設定時のみ Product にフォールバックする。
記録ルール¶
recordConsent/denyConsentはproductIdとvariantIdの両方を受け付ける。- Variant 対象で同意した場合は、
variantIdと親のproductIdを両方保存する。 - Product 共通同意のみを記録する場合は、
productIdのみ保存してよい。 - 単一 target API は、
productIdまたはvariantIdの少なくとも一方が必須である。 variantIdのみ指定された場合は、サーバー側で親productIdを解決する。productIdとvariantIdの両方が指定され、所属関係が一致しない場合はBAD_USER_INPUTとする。consentHistory/getValidConsentsはvariantIdが指定された場合、まず Variant 記録を評価し、必要に応じて Product 共通記録も併せて評価する。
GraphQL API ルール¶
checkProductConsentRequirementsはproductId: ID, variantId: IDを受け付ける。denyConsentはproductId: ID, variantId: IDを受け付ける。checkMultipleProductConsentsは input object 化せず、productIds/variantIdsの dual-array 形式を維持する。- batch API は
productIdsのみ、variantIdsのみ、両方指定の 3 パターンを許可する。 - batch API で両配列を渡す場合は長さ一致を必須とし、不一致は request 全体を
BAD_USER_INPUTとする。 - batch API の各 index では、
productId/variantIdの少なくとも一方が必要である。
Storefront ルール¶
- カート投入や購入前チェックは、実際に購入する
variantIdを起点に同意確認する。 - Product 詳細での「同意が必要」表示も、選択中 Variant があればその Variant を優先する。
- バンドル商品では、親 Product ではなく構成商品の
variantId/productIdを使って同意確認する。 - consent の GraphQL operation 定義は
packages/sdk/shopを正本にし、storefront ローカル定義を持たない。
非対象¶
brandCode/categoryCodeは本仕様では Variant へ移さない。これらは引き続き Product 側運用とし、regroup 条件で同値を要求する。directShippingEligibleは別仕様(2026-03-smile-product-field-responsibility.md)で Variant 正本へ訂正済み。本仕様の対象外。- 購入数量制限(
minimumQuantity/purchaseUnit/maxPerOrder)はPurchaseLimitRuleを正本とし、Product / ProductVariant custom field 側には持たない。