AstroBaaS

Catalogue & product data

Product Variant Selector

Free — GPL coresize Mplanned, not built

Generated from docs/plan/core/product-variant-selector/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Core UI component for selecting product variants (size, color) on product pages and in checkout. Provides a clear, accessible picker that displays available options, shows which combinations are in stock or out of stock, and prevents invalid selections. This is foundational storefront infrastructure; advanced visual selectors (color swatches, 3D views) belong in design/presentation tier.

The problem

Customers can’t select size/color; merchants’ dropdowns are confusing, causing checkout abandonment.

What it does

  • Variant picker UI: for each attribute (size, color), show available option values; customer selects one value per attribute
  • Option combinations: show only valid variant combinations (if only ‘S-Red’ and ‘L-Blue’ exist, don’t show ‘M-Red’ as valid)
  • Stock indication: mark options as ‘In Stock’, ‘Low Stock’, ‘Out of Stock’, or ‘Untracked’ based on variant.in_stock and stock levels
  • Disabled state: disable out-of-stock options visually; prevent customer from selecting them
  • Variant image swapping: when customer selects a variant with a unique image, swap the product image to that variant’s image
  • Price updates: when a variant is selected, update the displayed price (some variants may have different prices)
  • Quantity selector: after variant selection, show qty picker (1-99), respect sold_individually limit (qty max 1)
  • Add-to-cart integration: serialize selected variant and qty into cart line item with correct SKU and price
  • Accessibility: keyboard navigation (arrow keys to select), screen-reader labels, focus management
  • Mobile support: responsive layout (dropdown or button row depending on screen size), touch-friendly targets
  • Clear selection: show current selection, allow ‘clear’ to reset picker
  • Default selection: if only one option is valid, auto-select it and show variant details immediately

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Visual swatches (color swatches, pattern preview) — that’s design/presentation; handled by storefront, not core API
  • 3D model swapping — presentation layer responsibility
  • Variant availability real-time updates (via WebSocket) — use polling; WebSocket is advanced
  • Pre-order or backorder indication per variant — use the product backorder policy; variants don’t override it individually
  • Variant recommendations (e.g., ‘Most popular: Red’) — that’s analytics; core returns raw data only

Data model

No new schema; uses existing ProductVariant model and Product.variants array. Assumes variant.options (attribute name → value map), variant.in_stock, variant.stock, variant.price_cents, variant.image, variant.sku are populated.

API

  • GET /products/:id/variants — list all variants with options, in_stock, price_cents, image, for picker to render
  • GET /products/:id/variants/:variant_id — retrieve specific variant details (price, stock, image, SKU)
  • POST /cart/items — add item with variant selection {product_id, variant_id, qty}, validate variant is valid and qty is allowed

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

No admin-specific UI; variant picker is a storefront component. Admin creates and edits variants via product management (variant-management slug). Admin should test picker before publishing.

The seam — why this is core

Core owns the ProductVariant schema and GET /products/:id/variants API. Storefront (Next.js) owns the picker UI rendering, selection state management, and image swapping. Core returns raw variant data; storefront decides presentation (buttons, dropdowns, swatches).

Core owns the interface + honest variant picker; storefront UX is infrastructure, not a support commitment or credential.

Dependencies

  • product-management (core; variants are created/edited in product management)
  • variant-management (core; full variant CRUD)
  • cart-system (core; cart accepts selected variant and qty)

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • GET /products/shirt123/variants returns array with variants {id, options: {size: ‘S’, color: ‘red’}, in_stock: true, price_cents: 1500, image: ’…’, sku: ‘SHIRT-S-RED’}.
  • A product with only two valid variants (S-Red, L-Blue) does not list M-Red or S-Blue as options (invalid combos are not returned).
  • Selecting a variant marked in_stock=false disables the selection and shows ‘Out of Stock’; customer cannot add it to cart.
  • Selecting variant with variant.image=‘shirt-red.jpg’ updates the main product image to ‘shirt-red.jpg’.
  • A variant with price_cents=1200 (different from product.price_cents=1500) shows the variant price when selected, not the product price.
  • sold_individually=true on a product limits qty picker to max 1; qty selector shows only ‘1’ option.
  • Keyboard navigation: arrow keys move focus between options; Enter selects; Tab moves to qty selector.
  • Screen reader announces: ‘Size selector, currently selected: Large, options: Small, Medium, Large (Out of Stock)’.

Risks

If variant options are incorrectly configured (e.g., same option value used for two different variants), picker shows ambiguous choices. If a variant has no image, image-swap breaks. If price or stock data is stale, picker shows incorrect info. If qty limit enforcement is missing at add-to-cart, overselling can occur.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: included (theme components); Magento: included

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.