[object Object]

← back to Designer Wallcoverings

Suncloth title cleanup: drop 'Wallcoverings' from 119 fabric titles (Steve approved)

61aa048a3152c78a2b752d38436548143aec948b · 2026-06-29 16:40:27 -0700 · Steve

'{Color} [Suncloth] Wallcoverings | Suncloth' -> '{Color} | Suncloth'. Banned-word
compliant, brand preserved, old->new backed up to data/ for rollback. 119 ok/0 fail.

Files touched

Diff

commit 61aa048a3152c78a2b752d38436548143aec948b
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jun 29 16:40:27 2026 -0700

    Suncloth title cleanup: drop 'Wallcoverings' from 119 fabric titles (Steve approved)
    
    '{Color} [Suncloth] Wallcoverings | Suncloth' -> '{Color} | Suncloth'. Banned-word
    compliant, brand preserved, old->new backed up to data/ for rollback. 119 ok/0 fail.
---
 data/suncloth-title-backup-1782776345511.json | 597 ++++++++++++++++++++++++++
 shopify/scripts/clean-suncloth-titles.js      | 115 +++++
 2 files changed, 712 insertions(+)

diff --git a/data/suncloth-title-backup-1782776345511.json b/data/suncloth-title-backup-1782776345511.json
new file mode 100644
index 00000000..f039f59c
--- /dev/null
+++ b/data/suncloth-title-backup-1782776345511.json
@@ -0,0 +1,597 @@
+[
+  {
+    "id": "gid://shopify/Product/7866951794739",
+    "old": "Turquoise on White Suncloth Wallcoverings | Suncloth",
+    "new": "Turquoise on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7866951827507",
+    "old": "Yellow on White Suncloth Wallcoverings | Suncloth",
+    "new": "Yellow on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7866951860275",
+    "old": "Orange on White Suncloth Wallcoverings | Suncloth",
+    "new": "Orange on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867367948339",
+    "old": "French Blue on White Suncloth Wallcoverings | Suncloth",
+    "new": "French Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867367981107",
+    "old": "Magenta on White Suncloth Wallcoverings | Suncloth",
+    "new": "Magenta on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867368046643",
+    "old": "Navy on White Suncloth Wallcoverings | Suncloth",
+    "new": "Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867429388339",
+    "old": "Green, Coral Wallcoverings | Suncloth",
+    "new": "Green, Coral | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867429421107",
+    "old": "Salmons, Yellow Wallcoverings | Suncloth",
+    "new": "Salmons, Yellow | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867429453875",
+    "old": "Pinks, Turq, Taupe on Tint Wallcoverings | Suncloth",
+    "new": "Pinks, Turq, Taupe on Tint | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867478671411",
+    "old": "Multi Blues Wallcoverings | Suncloth",
+    "new": "Multi Blues | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867478704179",
+    "old": "Pink, Lime Wallcoverings | Suncloth",
+    "new": "Pink, Lime | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867478736947",
+    "old": "Navy French Green Teal Aqua on White Wallcoverings | Suncloth",
+    "new": "Navy French Green Teal Aqua on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867531165747",
+    "old": "Brown Wallcoverings | Suncloth",
+    "new": "Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867531198515",
+    "old": "French Blue Wallcoverings | Suncloth",
+    "new": "French Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867531231283",
+    "old": "White on Cream Wallcoverings | Suncloth",
+    "new": "White on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867553382451",
+    "old": "Inca Gold Wallcoverings | Suncloth",
+    "new": "Inca Gold | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867553415219",
+    "old": "Leaf Green on White Wallcoverings | Suncloth",
+    "new": "Leaf Green on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867553447987",
+    "old": "French Blue Wallcoverings | Suncloth",
+    "new": "French Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867576090675",
+    "old": "Brown on White Wallcoverings | Suncloth",
+    "new": "Brown on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867576156211",
+    "old": "Pacific Blue on Tint Wallcoverings | Suncloth",
+    "new": "Pacific Blue on Tint | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867576221747",
+    "old": "Taupe Wallcoverings | Suncloth",
+    "new": "Taupe | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867617706035",
+    "old": "Marine Blue Wallcoverings | Suncloth",
+    "new": "Marine Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867617738803",
+    "old": "Navy on White Wallcoverings | Suncloth",
+    "new": "Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867617804339",
+    "old": "Inca Gold Wallcoverings | Suncloth",
+    "new": "Inca Gold | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867655159859",
+    "old": "French Blue Wallcoverings | Suncloth",
+    "new": "French Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867655192627",
+    "old": "Jungle Green Wallcoverings | Suncloth",
+    "new": "Jungle Green | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867655225395",
+    "old": "Shrimp Wallcoverings | Suncloth",
+    "new": "Shrimp | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867701198899",
+    "old": "Brown Wallcoverings | Suncloth",
+    "new": "Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867701231667",
+    "old": "Forest Green on White Wallcoverings | Suncloth",
+    "new": "Forest Green on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867701264435",
+    "old": "Brown on White Wallcoverings | Suncloth",
+    "new": "Brown on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867760705587",
+    "old": "Navy on White Wallcoverings | Suncloth",
+    "new": "Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867760738355",
+    "old": "Aqua Light Turquoise on White Wallcoverings | Suncloth",
+    "new": "Aqua Light Turquoise on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7867760771123",
+    "old": "New Blue Navy on White Wallcoverings | Suncloth",
+    "new": "New Blue Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868272672819",
+    "old": "Salmon on White Wallcoverings | Suncloth",
+    "new": "Salmon on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868272738355",
+    "old": "Taupe Wallcoverings | Suncloth",
+    "new": "Taupe | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868272803891",
+    "old": "French Blue Wallcoverings | Suncloth",
+    "new": "French Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868815474739",
+    "old": "Multi Blues on Cream Wallcoverings | Suncloth",
+    "new": "Multi Blues on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868815507507",
+    "old": "Navy Blue Red Wallcoverings | Suncloth",
+    "new": "Navy Blue Red | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868815540275",
+    "old": "Jungle Green Taupe Wallcoverings | Suncloth",
+    "new": "Jungle Green Taupe | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868923936819",
+    "old": "Multi Lilac/Plum/Gold Wallcoverings | Suncloth",
+    "new": "Multi Lilac/Plum/Gold | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868923969587",
+    "old": "Multi Salmon Green Gold Wallcoverings | Suncloth",
+    "new": "Multi Salmon Green Gold | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868924166195",
+    "old": "Pale Aqua Wallcoverings | Suncloth",
+    "new": "Pale Aqua | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868940943411",
+    "old": "Orange Wallcoverings | Suncloth",
+    "new": "Orange | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868940976179",
+    "old": "French Blue Wallcoverings | Suncloth",
+    "new": "French Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868941008947",
+    "old": "New Shrimp Wallcoverings | Suncloth",
+    "new": "New Shrimp | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868963815475",
+    "old": "Camel II Wallcoverings | Suncloth",
+    "new": "Camel II | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868963848243",
+    "old": "Yellow Wallcoverings | Suncloth",
+    "new": "Yellow | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7868963913779",
+    "old": "Navy Wallcoverings | Suncloth",
+    "new": "Navy | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869010575411",
+    "old": "Brown Wallcoverings | Suncloth",
+    "new": "Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869010608179",
+    "old": "Royal Blue Wallcoverings | Suncloth",
+    "new": "Royal Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869010640947",
+    "old": "Bali Blue Wallcoverings | Suncloth",
+    "new": "Bali Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869204824115",
+    "old": "Black Wallcoverings | Suncloth",
+    "new": "Black | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869204856883",
+    "old": "Beige Wallcoverings | Suncloth",
+    "new": "Beige | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869204889651",
+    "old": "Green Wallcoverings | Suncloth",
+    "new": "Green | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869235363891",
+    "old": "Magenta Wallcoverings | Suncloth",
+    "new": "Magenta | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869235396659",
+    "old": "Orange Wallcoverings | Suncloth",
+    "new": "Orange | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869235429427",
+    "old": "Camel Wallcoverings | Suncloth",
+    "new": "Camel | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869371547699",
+    "old": "Sky Blue Wallcoverings | Suncloth",
+    "new": "Sky Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869371711539",
+    "old": "Yellow on White Wallcoverings | Suncloth",
+    "new": "Yellow on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869371809843",
+    "old": "Orange on White Wallcoverings | Suncloth",
+    "new": "Orange on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869423452211",
+    "old": "Royal Blue on White Wallcoverings | Suncloth",
+    "new": "Royal Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869423484979",
+    "old": "Green on White Wallcoverings | Suncloth",
+    "new": "Green on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869423517747",
+    "old": "Magenta on White Wallcoverings | Suncloth",
+    "new": "Magenta on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869454614579",
+    "old": "Navy on White Wallcoverings | Suncloth",
+    "new": "Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869454680115",
+    "old": "Camel on White Wallcoverings | Suncloth",
+    "new": "Camel on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869454712883",
+    "old": "Sky on White Wallcoverings | Suncloth",
+    "new": "Sky on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869766959155",
+    "old": "French Blue on White Wallcoverings | Suncloth",
+    "new": "French Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869766991923",
+    "old": "Brown on White Wallcoverings | Suncloth",
+    "new": "Brown on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869767024691",
+    "old": "Multi Blues, Navy Wallcoverings | Suncloth",
+    "new": "Multi Blues, Navy | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869813129267",
+    "old": "Multi Rose Turquoise Wallcoverings | Suncloth",
+    "new": "Multi Rose Turquoise | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869813162035",
+    "old": "Multi Turquoise Wallcoverings | Suncloth",
+    "new": "Multi Turquoise | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869813194803",
+    "old": "Multi Browns Turquoise Wallcoverings | Suncloth",
+    "new": "Multi Browns Turquoise | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869843406899",
+    "old": "Greens Wallcoverings | Suncloth",
+    "new": "Greens | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869843472435",
+    "old": "Blues Beige Wallcoverings | Suncloth",
+    "new": "Blues Beige | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869843505203",
+    "old": "Lime on White Wallcoverings | Suncloth",
+    "new": "Lime on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869893247027",
+    "old": "Navy / French Blue on White Wallcoverings | Suncloth",
+    "new": "Navy / French Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869893279795",
+    "old": "French Blue / Navy on White Wallcoverings | Suncloth",
+    "new": "French Blue / Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869893312563",
+    "old": "French Green Brown on White Wallcoverings | Suncloth",
+    "new": "French Green Brown on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869943218227",
+    "old": "White on White Suncloth Wallcoverings | Suncloth",
+    "new": "White on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869943283763",
+    "old": "New Jungle Wallcoverings | Suncloth",
+    "new": "New Jungle | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869943316531",
+    "old": "New Shrimp on White Wallcoverings | Suncloth",
+    "new": "New Shrimp on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869981294643",
+    "old": "Navy on White Wallcoverings | Suncloth",
+    "new": "Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869981327411",
+    "old": "New Brown Wallcoverings | Suncloth",
+    "new": "New Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7869981360179",
+    "old": "Black Wallcoverings | Suncloth",
+    "new": "Black | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870004035635",
+    "old": "White on Cream Suncloth Wallcoverings | Suncloth",
+    "new": "White on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870004068403",
+    "old": "Camel II Wallcoverings | Suncloth",
+    "new": "Camel II | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870004101171",
+    "old": "New Navy on White Wallcoverings | Suncloth",
+    "new": "New Navy on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870040703027",
+    "old": "Shrimp Brown on White Wallcoverings | Suncloth",
+    "new": "Shrimp Brown on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870040768563",
+    "old": "Taxicab on White Wallcoverings | Suncloth",
+    "new": "Taxicab on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870040801331",
+    "old": "New Blue Wallcoverings | Suncloth",
+    "new": "New Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870100635699",
+    "old": "Gray on White Wallcoverings | Suncloth",
+    "new": "Gray on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870100701235",
+    "old": "Grass Green Leaf Wallcoverings | Suncloth",
+    "new": "Grass Green Leaf | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870100734003",
+    "old": "Blue Wallcoverings | Suncloth",
+    "new": "Blue | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870218272819",
+    "old": "Camels on Cream Wallcoverings | Suncloth",
+    "new": "Camels on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870218436659",
+    "old": "Corals on Cream Wallcoverings | Suncloth",
+    "new": "Corals on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870218698803",
+    "old": "Leaf Greens on Cream Wallcoverings | Suncloth",
+    "new": "Leaf Greens on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870288232499",
+    "old": "Dark Greens on Brown Wallcoverings | Suncloth",
+    "new": "Dark Greens on Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870288363571",
+    "old": "French Blue on White Wallcoverings | Suncloth",
+    "new": "French Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870349967411",
+    "old": "French Blue on Cream Wallcoverings | Suncloth",
+    "new": "French Blue on Cream | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870350000179",
+    "old": "Turquoise Wallcoverings | Suncloth",
+    "new": "Turquoise | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870350065715",
+    "old": "Pistachio on White Wallcoverings | Suncloth",
+    "new": "Pistachio on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870399840307",
+    "old": "Taupe on Tint Wallcoverings | Suncloth",
+    "new": "Taupe on Tint | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870399873075",
+    "old": "Light Turquoise on White Wallcoverings | Suncloth",
+    "new": "Light Turquoise on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870399905843",
+    "old": "Turquoise Wallcoverings | Suncloth",
+    "new": "Turquoise | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870466523187",
+    "old": "French Blue on White Wallcoverings | Suncloth",
+    "new": "French Blue on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870466555955",
+    "old": "Brown Wallcoverings | Suncloth",
+    "new": "Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870466588723",
+    "old": "Inca Wallcoverings | Suncloth",
+    "new": "Inca | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870517772339",
+    "old": "Shrimp on White Wallcoverings | Suncloth",
+    "new": "Shrimp on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870517936179",
+    "old": "Jungle Green on Off White Wallcoverings | Suncloth",
+    "new": "Jungle Green on Off White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870518100019",
+    "old": "Brown Wallcoverings | Suncloth",
+    "new": "Brown | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870559092787",
+    "old": "Turquoise on White Wallcoverings | Suncloth",
+    "new": "Turquoise on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870559158323",
+    "old": "Lavender on White Wallcoverings | Suncloth",
+    "new": "Lavender on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870559191091",
+    "old": "Inca Gold on White Wallcoverings | Suncloth",
+    "new": "Inca Gold on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870592745523",
+    "old": "Camel on White Wallcoverings | Suncloth",
+    "new": "Camel on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870592811059",
+    "old": "New Melon on White Wallcoverings | Suncloth",
+    "new": "New Melon on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870592843827",
+    "old": "Fern Green Wallcoverings | Suncloth",
+    "new": "Fern Green | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870614241331",
+    "old": "Orange on White Wallcoverings | Suncloth",
+    "new": "Orange on White | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870614274099",
+    "old": "New Blue New Shrimp Wallcoverings | Suncloth",
+    "new": "New Blue New Shrimp | Suncloth"
+  },
+  {
+    "id": "gid://shopify/Product/7870614306867",
+    "old": "New Shrimp Grass Green Wallcoverings | Suncloth",
+    "new": "New Shrimp Grass Green | Suncloth"
+  }
+]
\ No newline at end of file
diff --git a/shopify/scripts/clean-suncloth-titles.js b/shopify/scripts/clean-suncloth-titles.js
new file mode 100644
index 00000000..c1a823b8
--- /dev/null
+++ b/shopify/scripts/clean-suncloth-titles.js
@@ -0,0 +1,115 @@
+#!/usr/bin/env node
+/**
+ * clean-suncloth-titles.js — drop "Wallcoverings" from the 119 Suncloth (now Fabric)
+ * titles. "Brown Wallcoverings | Suncloth" → "Brown | Suncloth". Also strips the
+ * redundant line-word "Suncloth" that some titles carry before "Wallcoverings"
+ * ("Turquoise on White Suncloth Wallcoverings | Suncloth" → "Turquoise on White | Suncloth").
+ *
+ * Banned-word compliant (removes "Wallcoverings"), keeps brand "| Suncloth", never empties
+ * the title, never introduces "Unknown". DRY-RUN by default; --execute to write.
+ * Backs up old→new titles to data/suncloth-title-backup-<ts>.json before any write.
+ *
+ * Usage:  node clean-suncloth-titles.js [--execute]
+ */
+const https = require('https');
+const fs = require('fs');
+const path = require('path');
+(() => { const e = path.join(__dirname, '..', '..', '.env');
+  if (fs.existsSync(e)) for (const l of fs.readFileSync(e, 'utf8').split('\n')) {
+    const m = l.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/); if (m && !process.env[m[1]]) process.env[m[1]] = m[2].replace(/^["']|["']$/g, ''); } })();
+
+const STORE = 'designer-laboratory-sandbox.myshopify.com';
+const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
+const VER = '2024-10';
+const EXECUTE = process.argv.includes('--execute');
+const BATCH = 25;
+const sleep = ms => new Promise(r => setTimeout(r, ms));
+
+function gql(query) {
+  return new Promise((resolve, reject) => {
+    const body = JSON.stringify({ query });
+    const req = https.request({ hostname: STORE, path: `/admin/api/${VER}/graphql.json`, method: 'POST',
+      headers: { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } },
+      res => { let d = ''; res.on('data', c => d += c); res.on('end', () => {
+        if (res.statusCode === 429) return resolve({ throttled: true, retryAfter: parseFloat(res.headers['retry-after'] || '2') });
+        try { resolve(JSON.parse(d)); } catch { reject(new Error('parse: ' + d.slice(0, 200))); } }); });
+    req.on('error', reject); req.write(body); req.end();
+  });
+}
+
+// "X [Suncloth] Wallcoverings | Suncloth" -> "X | Suncloth"
+function cleanTitle(title) {
+  const parts = title.split('|');
+  if (parts.length < 2) return title;
+  const brand = parts.slice(1).join('|').trim();      // "Suncloth"
+  let left = parts[0].trim();
+  left = left.replace(/\s*Wallcoverings?\s*$/i, '').trim();   // drop trailing Wallcovering(s)
+  const stripped = left.replace(/\s+Suncloth\s*$/i, '').trim(); // drop redundant trailing line-word
+  if (stripped) left = stripped;                       // ...only if something remains
+  left = left.replace(/\s{2,}/g, ' ').replace(/[,\s]+$/, '').trim();
+  if (!left) return title;                             // never empty
+  return `${left} | ${brand}`;
+}
+
+async function fetchAll() {
+  const all = []; let cur = null;
+  for (;;) {
+    const after = cur ? `, after:"${cur}"` : '';
+    let r = await gql(`{ products(first:100, query:"vendor:Suncloth"${after}){ pageInfo{hasNextPage endCursor} edges{ node{ id title } } } }`);
+    if (r.throttled) { await sleep(r.retryAfter * 1000); continue; }
+    if (r.errors) throw new Error(JSON.stringify(r.errors));
+    r.data.products.edges.forEach(e => all.push(e.node));
+    if (!r.data.products.pageInfo.hasNextPage) break;
+    cur = r.data.products.pageInfo.endCursor; await sleep(300);
+  }
+  return all;
+}
+
+async function pushBatch(items) {
+  const muts = items.map((p, i) =>
+    `p${i}: productUpdate(input: {id:"${p.id}", title:${JSON.stringify(p.newTitle)}}) { product{ id title } userErrors{ message } }`).join('\n');
+  let a = 0;
+  while (a < 4) {
+    const r = await gql(`mutation { ${muts} }`);
+    if (r.throttled) { await sleep(r.retryAfter * 1000); a++; continue; }
+    if (r.errors) { if (r.errors.find(e => /Throttled/i.test(e.message || ''))) { await sleep(2500); a++; continue; } throw new Error(JSON.stringify(r.errors)); }
+    return items.map((p, i) => { const n = r.data?.[`p${i}`]; const ue = n?.userErrors || [];
+      return { id: p.id, ok: ue.length === 0 && n?.product?.title === p.newTitle, err: ue.map(e => e.message).join('; ') }; });
+  }
+  return items.map(p => ({ id: p.id, ok: false, err: 'throttled-out' }));
+}
+
+(async () => {
+  if (!TOKEN) { console.error('Missing SHOPIFY_ADMIN_TOKEN'); process.exit(2); }
+  console.log(`\nSUNCLOTH title cleanup  [${EXECUTE ? 'EXECUTE' : 'DRY-RUN'}]\n`);
+  const all = await fetchAll();
+  const changes = all.map(p => ({ ...p, newTitle: cleanTitle(p.title) })).filter(p => p.newTitle !== p.title);
+  const stillBanned = changes.filter(p => /wallcoverings?/i.test(p.newTitle)).length;
+
+  console.log(`vendor:Suncloth total = ${all.length}`);
+  console.log(`titles needing change = ${changes.length}`);
+  console.log(`new titles still containing "Wallcovering(s)" = ${stillBanned} (must be 0)\n`);
+  changes.slice(0, 12).forEach(p => console.log(`  "${p.title}"\n    → "${p.newTitle}"`));
+  if (changes.length > 12) console.log(`  …and ${changes.length - 12} more`);
+
+  if (!changes.length) { console.log('\nNothing to change. ✅'); process.exit(0); }
+  if (stillBanned > 0) { console.error('\nABORT: some new titles still contain the banned word.'); process.exit(1); }
+  if (!EXECUTE) { console.log('\nDRY-RUN only. Re-run with --execute to apply.'); process.exit(0); }
+
+  const bdir = path.join(__dirname, '..', '..', 'data'); fs.mkdirSync(bdir, { recursive: true });
+  const bfile = path.join(bdir, `suncloth-title-backup-${Date.now()}.json`);
+  fs.writeFileSync(bfile, JSON.stringify(changes.map(c => ({ id: c.id, old: c.title, new: c.newTitle })), null, 2));
+  console.log(`\nBacked up ${changes.length} old→new titles → ${bfile}`);
+
+  let ok = 0, fail = 0;
+  for (let i = 0; i < changes.length; i += BATCH) {
+    const res = await pushBatch(changes.slice(i, i + BATCH));
+    res.forEach(r => { if (r.ok) ok++; else { fail++; console.log(`  FAIL ${r.id}: ${r.err}`); } });
+    console.log(`  batch ${i / BATCH + 1}: ${ok} ok / ${fail} fail`);
+    await sleep(600);
+  }
+  const after = await fetchAll();
+  const remaining = after.filter(p => /wallcoverings?/i.test(p.title)).length;
+  console.log(`\nDone: ${ok} ok, ${fail} fail. vendor:Suncloth titles still containing "Wallcovering(s)" = ${remaining}`);
+  process.exit(remaining === 0 && fail === 0 ? 0 : 1);
+})().catch(e => { console.error('ERROR:', e.message); process.exit(2); });

← a7ce3afe auto-save: 2026-06-29T16:24:37 (3 files) — pending-approval/  ·  back to Designer Wallcoverings  ·  Quadrille-house cadence: type-by-row from staging table (mos 7ba76ce7 →