Note

    filters-variants-actions-status

    Filters, Variants, and Actions – Implementation Status (Post–Workstreams A–C) This document captures the current, implemented behavior of filt...

    Dates

    Created
    Not recorded
    Last updated
    Not recorded

    Filters, Variants, and Actions – Implementation Status (Post–Workstreams A–C)

    This document captures the current, implemented behavior of filters, variant targeting, and bulk actions, based on the code on staging plus docs/1001, docs/1002, and docs/1003.

    1. Filters and DSL → Shopify search

    • Variant price mapping

      • BaseField.variantPrice now compiles to Shopify’s documented price field.
      • Example: a DSL rule variantPrice between 10 and 20 compiles to price:>=10 price:<=20.
      • Covered by compileToShopifyQuery and filters.compile.test.ts ("maps variantPrice equals to price field").
    • Variant-only fields

      • variantName (variant title = combined option values), variantOption1/2/3 (individual option values), and variantPosition never compile into Shopify search tokens.
      • They are evaluated only by local logic (matchesVariantRule / matchesVariantFilter in bulkEditPreview.ts) for:
        • Preview.
        • Variant-level actions (price, SKU, barcode, variant add/delete/edit/replace).
      • Verified by tests that expect compileToShopifyQuery to produce an empty query when only variant-only fields are present.
    • Metafield filters

      • Metafield rules (type: "metafield", namespace, key, operator, value) are compiled into search tokens:
        • metafields.{namespace}.{key}:{value}, with appropriate operator handling (equals, contains, in, exists, etc.).
      • compileToShopifyQuery still returns metafieldRules alongside the query, but product selection is entirely driven by the compiled query string passed to products.
      • Net effect: metafield filters now truthfully limit which products are edited.
    • Status and multi-value syntax

      • Multi-status filters (e.g., "ACTIVE", "DRAFT") use the comma form status:ACTIVE,DRAFT instead of OR chains, matching Shopify examples.
    • Synced reference dropdowns

      • Collections, vendors, and product types share the same synced reference-data pattern (snapshot table + list/sync routes + support hooks).
      • Filter dropdowns show helper text with a Sync button (plus last-synced tooltip) so merchants can refresh the options in-place.
      • Collection actions reuse the same selector; automated collections stay disabled with explanatory tooltip, while manual collections remain selectable.

    2. Variant targeting behavior (Variant filter per action)

    • Two-step mental model

      • Step 1 – Product filter (Filter products card): decides which products enter the job.
      • Step 2 – Variant filter (per action): decides which variants on each matching product are edited.
    • Default behavior

      • For variant-aware actions (Price, SKU, Barcode, Variants & Options: Add/Edit/Delete/Clone), the card shows:
        • Variants to edit: All variants on each matching product [Change].
      • If the merchant never clicks Change, the job edits all variants on each matching product with no variant filter.
    • Variant filter layout

      • Inside Change:
        • Uses a variant-only DSL builder so only variant-level fields (variant title, option values, position, SKU, barcode, price) are available.
        • Common patterns:
          • All variants on each product: leave the variant filter blank.
          • By number: add rule Variant position equals N (1 = first, 2 = second, …).
          • By option: add rule(s) Variant option 1/2/3 equals … (for example, Option 2 (usually Color) equals “Red”).
    • Execution

      • ActionConfig stores only the variant filter DSL per action type (for example, priceVariantFilter, skuVariantFilter, variantDeleteFilter, variantEditFilter).
      • convertActionConfigsToBulkEditActions passes these through as { dsl: FilterDSL } without a separate selection object.
      • filterVariants applies:
        • Variant filter (variantFilter.dsl via matchesVariantFilter) to decide which variants are edited.
      • Covered by:
        • tests/variantSelection.test.ts (variant filter + filterVariants behavior).
        • Runner and preview code paths in bulkEditPreview.ts and bulkEditRunner.server.ts.

    3. Bulk actions and GraphQL helpers

    • Product update (productUpdate)

      • Helpers:
        • updateProductTitleSeo – title, SEO title, SEO description.
        • updateProductVendorTypeStatus – vendor, productType, status.
      • Mutation shape:
        • mutation UpdateProduct($product: ProductUpdateInput!) { productUpdate(product: $product) { userErrors { field message } } }
      • Status update flow:
        • Map "active" | "draft" | "archived""ACTIVE" | "DRAFT" | "ARCHIVED".
        • Call updateProductVendorTypeStatus.
        • Verify via fetchProductStatus and log errors if the status does not match.
    • Product create (productCreate)

      • Helper:
        • productCreate in adminMutations.server.ts.
      • Mutation shape:
        • mutation ProductCreate($product: ProductCreateInput!) { productCreate(product: $product) { product { id } userErrors { field message } } }
      • Payload:
    • Metafields

      • Set:
        • metafieldsSet(metafields: [MetafieldsSetInput!]!) with ownerId, namespace, key, type, value.
      • Delete:
        • metafieldDeleteByKey:
          • Lookup metafield by owner/namespace/key.
          • Call metafieldsDelete(metafields: [MetafieldIdentifierInput!]!).
    • Variant-level mutations

      • Use modern bulk variants APIs:
        • productVariantsBulkCreate(productId, variants: [ProductVariantsBulkInput!]!).
        • productVariantsBulkDelete(productId, variantsIds: [ID!]!).
        • productVariantsBulkUpdate(productId, variants: [ProductVariantsBulkInput!]!).
      • All price/SKU/barcode and variant add/delete/edit operations are routed through these helpers.
      • Clone uses productSet to replace options + variants, with a post-pass media update if enabled.

    4. Test coverage snapshot

    • Unit tests

      • filters.compile.test.ts:
        • Confirms variantPriceprice.
        • Validates metafield rule compilation and that variant-only fields do not appear in compiled queries.
      • variantSelection.test.ts:
        • Confirms selection wiring for all modes (including 1-based “By number”).
        • Exercises filterVariants and matchesVariantFilter for All/First/Last/ByIndex/ByOption.
      • adminMutations.test.ts:
        • Verifies productUpdate, productCreate, and metafieldsDelete helpers use the new schema shapes.
    • Playwright (tests/**/*.pw.spec.ts)

      • tests/bulk-tasks/*.pw.spec.ts:
        • Exercise the single-action editor (Tags/Price/Metafield) plus filter builder + task controls.
      • tests/bulk-variants/variant-actions.pw.spec.ts:
        • Covers variant add/edit/delete/replace using variant filters (position, options) to target specific variants.
      • tests/non-bulk/filters-and-usage.pw.spec.ts & tests/non-bulk/csv-flows.pw.spec.ts:
        • Validate OR/NOT filter combinations, variant filter helper copy, usage page developer tools, and CSV export/import flows.

    This document should be used alongside docs/1001_variant-simplifaction.md (UX and mental model) and docs/1003_filters-variants-actions-workstreams.md (planning) as the up-to-date reference for how filters, variants, and actions actually behave in the shipped app.

    Provenance

    Dataset Preview

    • Raw CSV row/table content is available in the source artifact.