← back to Dw Domain Fleet

VENDOR_HANDLE_RENAME_PLAN.md

63 lines

# C — Vendor handle source-rename · CLOSED 2026-05-29: "A is enough" (Steve)

> **DECISION (2026-05-29): NOT doing C. The shipped render-time scrub (A) is the
> fix.** Evaluated C with a sandbox dry-run: the rename mechanic works
> (`productUpdate(handle:)` cleans the handle, Shopify auto-creates the 301).
> **But blind detection is unsafe** — even precise full-vendor-name matching
> can't distinguish the vendor **"Harlequin"** from a **"harlequin" diamond
> *pattern***, and it flags **house-brand** products (e.g. a Philippe Romano
> product whose pattern is "harlequin"). An autonomous live rename would corrupt
> legitimate product names + canonical Shopify URLs on the revenue store —
> higher blast radius than the leak it closes. A only affects fleet *display*
> (reversible, worst case cosmetic), so A wins. Live source handles left
> untouched. (One sandbox test product `zoe-s-zebra…scalamandre` was renamed
> during the dry-run — harmless test-store change, left as-is.) If C is ever
> revisited it MUST be a **human-reviewed, per-item-approved** migration, never
> an automated bulk rename. Everything below is the original (now-shelved) plan.

---

# C — Vendor handle source-rename (the durable fix) · PARKED, GATED

DTD verdict (2026-05-29) on the fleet vendor-leak fix was **A**: strengthen the
render-time slug scrub now (DONE — `scrubVendor()` in `shared/render.js`, 44/44
sites verified 0 leaks), and tee up **C** as the durable follow-up. This is C.

## Why C (not stop)
`scrubVendor` cleans every *displayed/URL* surface, but `data-handle` /
`data-sku` HTML attributes stay **raw** — they power the buy-sample CTA that
deep-links to `designerwallcoverings.com/products/<handle>`. So a vendor name
still sits in the served DOM source. The only way to close that without
breaking the cart is to **clean the handle at the source**.

## Blast radius — why this is GATED (do NOT auto-run)
The handle is shared across **the live DW Shopify store**, the 44 fleet sites,
the sandbox store, `rel=canonical`, and any external/SEO links. Renaming it:
- changes the **live customer-facing Shopify product URL** → needs 301s (Shopify
  auto-creates a redirect on handle change, but verify per product)
- must stay **in sync** between Shopify + `dw_unified` or the buy-sample CTA 404s
- is effectively **irreversible** for SEO/bookmarks
→ customer-facing + money-adjacent + hard-to-reverse = **Steve approves up front**.

## Scope (to confirm before a gated session)
1. **Identify** the vendor-carrying handles: query `dw_unified` products whose
   `handle` matches the `VENDORS_DENYLIST` (reuse `hasVendorToken` logic). Get
   the count + a sample (the audit saw brunschwig-fils, *-cole-son, *-romo,
   *-clarke-and-clarke, *-caroline-cecil-textiles, *-kravet, etc.).
2. **Decide the new handle form** per product: `productSlug()` already computes a
   clean deterministic slug — reuse it as the target (so fleet + source agree),
   or scrubbed-sku, or `design-<hash>` for all-vendor handles.
3. **Shopify rename** via Admin API `productUpdate(handle:)` — confirm Shopify
   auto-creates the 301; spot-check old URL → 301 → new.
4. **Sync `dw_unified`** handle + re-sync the fleet POOL.
5. **Verify**: data-handle/data-sku now clean in fleet DOM; buy-sample CTA 200;
   old `/products/<old-handle>` 301s on the DW store.

## Decision needed from Steve
- Run on the **sandbox store first** (designer-laboratory-sandbox) as a dry-run,
  then the live DW store? (recommended)
- Or is the render-time scrub (A, shipped) **enough** — leave source handles as-is
  given Shopify URLs carry SEO weight and the *visible* leak is already gone?

**Status: parked. Awaiting Steve's go on a gated session — not started.**