[object Object]

← back to Dw Gemini Skip TK11321

Exclude samples, Gracie/bespoke vendors, and re-introductions from activation queue (TK-10446)

0117f7abf2db7c95776ec296b083a80d0de03c88 · 2026-08-10 21:22:34 -0700 · Steve

Files touched

Diff

commit 0117f7abf2db7c95776ec296b083a80d0de03c88
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Aug 10 21:22:34 2026 -0700

    Exclude samples, Gracie/bespoke vendors, and re-introductions from activation queue (TK-10446)
---
 lib/rotation-order.js | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/lib/rotation-order.js b/lib/rotation-order.js
index b2219b3..3446c58 100644
--- a/lib/rotation-order.js
+++ b/lib/rotation-order.js
@@ -46,6 +46,21 @@ const NOISE_REGEX =
   "how to|how-to|instructional|installation guide|hanging guide|care guide|" +
   "user guide|tutorial";
 
+// NEVER-ACTIVATE vendors (2026-08-10, TK-10446). These are bespoke / made-to-order /
+// quote-only / internal-only lines that must never auto-publish to the storefront:
+//   Gracie   — HARD RULE, Steve "do not show GRACIE EVER" (bespoke chinoiserie, quote-only)
+//   Fromental, Zuber, De Gournay — bespoke made-to-order, quote-only, settlement-heavy
+//   Astek    — internal line-viewer only, not on the DW Shopify store
+// (Schumacher is already excluded below as internal-only.)
+const NEVER_ACTIVATE_VENDORS = "gracie|fromental|zuber|de gournay|astek";
+
+// SAMPLE-SKU filter (2026-08-10, TK-10446). ~90% of the DRAFT pool are memo/sample
+// SKUs (…-Sample, …-S). Activating one publishes a standalone $4.25 memo listing
+// (Google-Merchant $4.25-leak / disapproval risk). Samples must NEVER activate as
+// their own live product — only real roll/sell SKUs do. Matched on the SKU suffix,
+// NOT on title (Phillipe Romano etc. use "memo"/"sample" as legit name tokens).
+const SAMPLE_SKU_REGEX = "-(sample|s)$";
+
 /*
  * The canonical ordered-DRAFT query. Emits every DRAFT (minus Schumacher + noise)
  * in the exact textures-first + vendor-round-robin order, with the columns both
@@ -70,10 +85,17 @@ WITH pool AS (
       coalesce(tags,'')         || ' ' ||
       coalesce(product_type,'')
     )                                               AS matstr
-  FROM shopify_products
+  FROM shopify_products sp
   WHERE status = 'DRAFT'
     AND vendor NOT ILIKE '%schumacher%'                     -- internal-only, never storefront
+    AND lower(coalesce(vendor,'')) !~ '${NEVER_ACTIVATE_VENDORS}' -- Gracie/Fromental/Zuber/De Gournay/Astek: bespoke/quote-only/internal, never auto-publish
     AND lower(coalesce(title,'')) !~ '${NOISE_REGEX}'       -- drop help-doc noise rows
+    AND lower(coalesce(sku, dw_sku, '')) !~ '${SAMPLE_SKU_REGEX}' -- exclude memo/sample SKUs (…-Sample / …-S): never a standalone live listing
+    AND NOT EXISTS (                                        -- re-introduction guard: skip a DRAFT whose title was EVER on the store
+      SELECT 1 FROM shopify_products a                      -- (ACTIVE now, or intentionally ARCHIVED/DELETED before) — no resurrecting retired patterns
+       WHERE a.status IN ('ACTIVE','ARCHIVED','DELETED_FROM_SHOPIFY')
+         AND a.title = sp.title AND a.shopify_id <> sp.shopify_id
+    )
 ),
 tiered AS (
   SELECT *,

← 6ec5f49 chore: refactor (summary label reflects COMMIT vs DRY mode),  ·  back to Dw Gemini Skip TK11321  ·  Save TK-10446 Tier-1 cleanup id list (943 rotation-published 7f4f53f →