diff --git a/use-crystallize/skills/content-model/SKILL.md b/use-crystallize/skills/content-model/SKILL.md index 3d4ec3d..2301ee7 100644 --- a/use-crystallize/skills/content-model/SKILL.md +++ b/use-crystallize/skills/content-model/SKILL.md @@ -67,6 +67,10 @@ Product variants have additional built-ins: `sku`, `images`, `videos`, `price`, **Components are the additional fields you define** beyond these built-ins. For product shapes, use `variantComponents` in the shape definition to add custom components directly to product variants (e.g., custom certifications, variant-level specs). +**`variantComponents` supports all component types**, including structured components: `contentChunk`, `componentChoice`, `componentMultipleChoice`, and `piece` references. This means you can add repeating field groups, polymorphic choices, or reusable pieces directly on variants — not just simple fields like `singleLine` or `numeric`. For example, a product variant can have a `contentChunk` for packaging dimensions, or a `componentChoice` for variant-specific technical specs. + +**`variantComponents` require the same type discipline as product-level components** — apply the Component Selection Guide below. Measurable values (weight, voltage, length) → `numeric` with units. Controlled options (connection type, material) → `selection`. Free-form identifiers → `singleLine`. Do not default everything to `singleLine`. + **IMPORTANT:** Do NOT add components for price or stock - these are native properties managed through the product variant's built-in fields. Only create custom price/stock components for specific edge cases (e.g., tiered pricing models, subscription pricing, price modifiers for configurators). **Product Identification:** The built-in `sku` field on product variants is the primary product identifier — use it for GTIN, EAN, ISBN, or any single identifier. Do NOT add a separate `gtin` or `ean` single-line component on the variant. If a product needs **multiple identifiers** (e.g., both ISBN-10 and ISBN-13, or a GTIN plus a legacy system ID), add an **identifiers chunk** with named fields to the shape: @@ -773,6 +777,8 @@ Piece: "SEO" (not "SEO Metadata") ❌ **Flat component lists** - Group related fields with Chunks for better structure +❌ **Flat singleLine variant components** - `variantComponents` follow the same type rules as product-level components. Voltage, length, weight → `numeric` with units. Connection type, material, animal version → `selection` with options. Only use `singleLine` for genuinely free-form text (a color label, a custom code). A variant story full of `singleLine` is a modeling smell. + ❌ **Mixing variant data with product data** - Use variant attributes (built-in) for size/color/sku ❌ **Adding GTIN/EAN/ISBN as a variant component** - The built-in `sku` field handles single product identifiers. For multiple identifiers, add a chunk with named single-line components (e.g., `isbn-10`, `isbn-13`, `gtin`, `ean`, `upc`, `legacy-id`) at the shape level, not on the variant. @@ -900,7 +906,15 @@ Components can reference pieces (via `type: "piece"`) and shapes (via `itemRelat } } ], - "variantComponents": [{ "id": "gtin", "name": "GTIN", "type": "singleLine" }] + "variantComponents": [ + { "id": "weight", "name": "Weight", "type": "numeric", "config": { "numeric": { "units": ["g", "kg"], "discoverable": true } } }, + { + "id": "color", + "name": "Color", + "type": "selection", + "config": { "selection": { "options": [{ "key": "black", "value": "Black" }, { "key": "white", "value": "White" }] } } + } + ] }, { "intent": "shape/upsert", diff --git a/use-crystallize/skills/content-model/references/shapes.md b/use-crystallize/skills/content-model/references/shapes.md index 2733e14..e8050c0 100644 --- a/use-crystallize/skills/content-model/references/shapes.md +++ b/use-crystallize/skills/content-model/references/shapes.md @@ -32,6 +32,8 @@ Use `variantComponents` when you need variant-level data beyond the built-in SKU - Variant-level specs that differ per variant (e.g., battery capacity per size) - Custom variant identifiers (e.g., manufacturer variant codes) +**`variantComponents` supports all component types**, including structured components: `contentChunk`, `componentChoice`, `componentMultipleChoice`, and `piece` references. You are not limited to simple fields — you can model rich, grouped, or polymorphic data directly on variants. + ```graphql mutation { createShape( @@ -49,7 +51,7 @@ mutation { } ] variantComponents: [ - # Variant-level custom components + # Simple variant-level components { id: "battery-capacity" name: "Battery Capacity" @@ -62,6 +64,29 @@ mutation { type: singleLine config: { singleLine: { multilingual: true } } } + # Structured variant-level component (contentChunk) + { + id: "packaging" + name: "Packaging Dimensions" + type: contentChunk + config: { + contentChunk: { + components: [ + { id: "width", name: "Width", type: numeric, config: { numeric: { units: ["cm", "in"] } } } + { id: "height", name: "Height", type: numeric, config: { numeric: { units: ["cm", "in"] } } } + { id: "depth", name: "Depth", type: numeric, config: { numeric: { units: ["cm", "in"] } } } + { id: "weight", name: "Weight", type: numeric, config: { numeric: { units: ["g", "kg"] } } } + ] + } + } + } + # Piece reference on a variant + { + id: "certifications" + name: "Certifications" + type: piece + config: { piece: { identifier: "variant-certifications" } } + } ] } ) { @@ -74,6 +99,8 @@ mutation { > **Note:** Do not use `variantComponents` for fields that are the same across all variants — those belong in `components` (product level). +> **Type discipline:** `variantComponents` follow the exact same component type rules as product-level components. Use `numeric` (with units) for measurable values like voltage, length, weight, or wattage. Use `selection` for controlled options like connection type, material, or animal version. Reserve `singleLine` for genuinely free-form text. A variant story full of `singleLine` components is a modeling smell — it loses queryability, unit awareness, and editor guardrails. + ### Document Shape Used for editorial and marketing content. **Documents are leaf nodes and cannot have children.**