← back to Dwla Rebrand
scaffold dwla rebrand: PLAN.md + LA name map + phase-1 dry-run pipeline
1e6f29e4b0f7b18747fd30c3c02030dfaffd4240 · 2026-05-07 15:09:42 -0700 · Steve
7,600 registry rows (Pointe + Justin David) → Los Angeles Fabrics / DWLA.
Phase 0 produces preview/phase1.html showing 17 PI-PAMPAS colorways
across 32 Shopify products without touching Shopify. Sequence counter
allocated DWLA-100001…100017 for phase 1.
Files touched
A .gitignoreA PLAN.mdA README.mdA data/dwla_sequence.txtA data/la_name_map.jsonA package-lock.jsonA package.jsonA preview/phase1.csvA preview/phase1.htmlA preview/phase1.jsonA scripts/build_dryrun.js
Diff
commit 1e6f29e4b0f7b18747fd30c3c02030dfaffd4240
Author: Steve <steve@designerwallcoverings.com>
Date: Thu May 7 15:09:42 2026 -0700
scaffold dwla rebrand: PLAN.md + LA name map + phase-1 dry-run pipeline
7,600 registry rows (Pointe + Justin David) → Los Angeles Fabrics / DWLA.
Phase 0 produces preview/phase1.html showing 17 PI-PAMPAS colorways
across 32 Shopify products without touching Shopify. Sequence counter
allocated DWLA-100001…100017 for phase 1.
---
.gitignore | 9 +
PLAN.md | 113 +++++++++
README.md | 12 +
data/dwla_sequence.txt | 1 +
data/la_name_map.json | 30 +++
package-lock.json | 162 +++++++++++++
package.json | 15 ++
preview/phase1.csv | 33 +++
preview/phase1.html | 214 +++++++++++++++++
preview/phase1.json | 623 ++++++++++++++++++++++++++++++++++++++++++++++++
scripts/build_dryrun.js | 187 +++++++++++++++
11 files changed, 1399 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a027f95
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
+data/cache/
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 0000000..d3be202
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,113 @@
+# DWLA Rebrand — Pointe (PI-) + Justin David (JD-) → Los Angeles Fabrics
+
+## Source state (2026-05-07)
+
+| | Count |
+|---|---|
+| Registry rows with `PI-` mfr_sku (Pointe) | 2,870 |
+| Registry rows with `JD-` mfr_sku (Justin David) | 4,730 |
+| **Total target registry rows** | **7,600** |
+| Registry rows already linked to a `shopify_product_id` | 1,148 |
+| Shopify products with `DWPN-` SKU (registry-aligned) | 1,137 |
+| Shopify products with `DWPR-` SKU (registry-orphan; the bug) | 3,024 |
+| Hard-duplicate DWPR SKUs (same SKU on 2 records) | 21 |
+| Hard-duplicate Shopify product records | 42 |
+
+## Target state
+
+| | Target |
+|---|---|
+| Registry vendor_name | `Los Angeles Fabrics` (was: `Phillipe Romano`) |
+| Registry vendor_prefix | `DWLA` (was: `DWPN` / orphan `DWPR`) |
+| Registry mfr_sku | unchanged (`PI-...` / `JD-...` are still upstream-vendor codes) |
+| Shopify vendor | `Los Angeles Fabrics` |
+| Shopify SKU | `DWLA-XXXXXX` (new sequence; map preserved in `dw_sku_registry`) |
+| Shopify title `| Phillipe Romano` suffix | replaced with `| Los Angeles Fabrics` |
+| Shopify tags containing "Phillipe Romano" | replaced with "Los Angeles Fabrics" |
+| Old Shopify handles | 301-redirected from old → new where renamed |
+| Hard-duplicate `-1` records | archived (NOT deleted) |
+
+## Phased push plan (Shopify variant limit = 1k/day)
+
+| Phase | Scope | Products | Days | Risk |
+|---|---|---|---|---|
+| 0 | Build dry-run + preview HTML | 0 writes | 0 | none |
+| 1 | First 17 PI-PAMPAS-* + dedupe their 17 `-1` dups | 34 | 1 | low — proves pipeline |
+| 2 | Remaining 4 dup pairs (necker-island / norman-island / palm-island stragglers) | 8 | 1 | low — same pipeline |
+| 3 | Remaining ~960 PI-* registry rows w/ Shopify IDs | ~960 | 1 | medium — vendor-rename live products |
+| 4 | All 4,720 JD-* registry rows w/ Shopify IDs | ~3,000 | 3 | medium |
+| 5 | Backfill registry for ~3,024 DWPR orphan Shopify products | 0 Shopify writes (DB only) | 1 | low |
+| 6 | URL handle rename + 301 redirects (optional cosmetic) | varies | 2 | high — SEO sensitive |
+
+**Each phase emits a CSV diff for review before any Shopify mutation.**
+
+## Out of scope (do NOT touch in this rebrand)
+
+- The other ~10,239 Phillipe Romano Shopify products with non-PI/JD mfr_sku codes
+- Patterns under "Hollywood Abaca", "Luxuria", "Natural Wallpaper" (those are different upstream brands)
+- Any product not in `dw_sku_registry` AND not a Pointe/Justin-David-derived Shopify orphan
+- Customer-facing email blasts about the rebrand (legal review needed; out of scope here)
+
+## East-Coast → LA-area collection name map
+
+These are the visible "city" pattern-names under Phillipe Romano. Under "Los Angeles Fabrics", East Coast names read wrong; mapping to LA-area equivalents that match prestige/character:
+
+| East Coast name | Vibe | → LA-area equivalent |
+|---|---|---|
+| Kennebunkport | luxury Maine coast | **Malibu** |
+| Bar Harbor | rugged Maine coast | **Santa Monica** |
+| Cape May | Victorian Jersey shore | **Venice Beach** |
+| Martha's Vineyard | island estate | **Catalina** |
+| Block Island | quiet RI escape | **Avalon** |
+| Nantucket | preppy MA classic | **Pacific Palisades** |
+| Montauk | surfer-Hamptons | **Manhattan Beach** |
+| Hilton Head | SC golf-resort | **Hermosa Beach** |
+| Amelia Island | FL barrier | **Redondo Beach** |
+| Kiawah | SC boho-luxe | **Ojai** |
+| Hollywood | already LA | (unchanged) |
+| Necker Island | Caribbean (BVI) | **Catalina Cove** |
+| Norman Island | BVI sailing | **Pirates Cove** |
+| Palm Island | tropical | **Palm Drive** |
+| Parrot Cay | tropical | **Pelican Cove** |
+| Stone Haven | new-name | **Stone Canyon** |
+| Turneffe | Belize atoll | **Topanga** |
+| Tobago | Trinidad isle | **Tujunga** |
+| Storm Bay | abstract | (unchanged) |
+| Tradewind Trace | abstract | (unchanged) |
+| Sandy Point Stripe | beach | **Will Rogers Stripe** |
+| Sisal Bay | natural | **Solstice Bay** |
+| Nassau Gold | Bahamas | **Brentwood Gold** |
+| Turf Bay | abstract | (unchanged) |
+
+**Steve must confirm or override this map before any title/handle writes.**
+
+## Safety guarantees
+
+- **Zero Shopify writes** until the per-phase preview HTML is reviewed and approved.
+- **Every mutation reversible**: the original DWPR/DWPN SKU + old vendor + old title are written to a `dwla_migration_audit` table BEFORE any Shopify call. Roll-back script reads that table and replays.
+- **Shopify daily variant limit honored** — pushes throttled at ≤900/day with 90s gaps between bulk batches per `feedback_fm_pipeline_gotchas`.
+- **Image gate**: any product without ≥1 image stays DRAFT post-rebrand (per `feedback_never_active_without_image`).
+- **Sample-only preserved**: not archived (per `feedback_priced_bolt_or_archive`).
+- **DNS/email NOT touched** — `designerwallcoverings.com` is on the do-not-touch list.
+
+## Files
+
+| Path | Purpose |
+|---|---|
+| `PLAN.md` | this doc |
+| `data/la_name_map.json` | East Coast → LA mapping (Steve-editable) |
+| `data/dwla_sequence.txt` | DWLA-XXXXXX sequence counter (next free number) |
+| `scripts/build_dryrun.js` | reads registry + Shopify, generates preview |
+| `preview/phase1.html` | reviewable HTML diff for phase 1 |
+| `preview/phase1.csv` | machine-readable diff for phase 1 |
+| `scripts/push_phase.js` | NOT WRITTEN until previews are approved |
+| `db/migrations/001_dwla_audit.sql` | rollback table |
+
+## Steve's go/no-go gate
+
+Phase 0 outputs `preview/phase1.html` showing the 34-product mutation. Steve reviews. Two outcomes:
+
+- **GO** — approve phase 1; I write `push_phase.js`; we run phase 1 against Shopify; verify; commit.
+- **NO** — Steve flags issues in preview; I revise; new preview; loop until approved.
+
+No Shopify writes happen without an explicit per-phase GO.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..99632ad
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# DWLA Rebrand
+
+Migrating the Pointe (PI-) and Justin David (JD-) products from
+"Phillipe Romano" branding to "Los Angeles Fabrics" / DWLA prefix.
+
+See `PLAN.md` for the full migration spec, scope, and phased push plan.
+
+## Current state
+
+- Phase 0 — dry-run pipeline built (this commit)
+- Phase 1 — preview at `preview/phase1.html` (17 PI-PAMPAS colorways, 32 Shopify products)
+- Phase 2+ — gated on Steve approving phase 1
diff --git a/data/dwla_sequence.txt b/data/dwla_sequence.txt
new file mode 100644
index 0000000..a37744e
--- /dev/null
+++ b/data/dwla_sequence.txt
@@ -0,0 +1 @@
+100018
\ No newline at end of file
diff --git a/data/la_name_map.json b/data/la_name_map.json
new file mode 100644
index 0000000..c99e47c
--- /dev/null
+++ b/data/la_name_map.json
@@ -0,0 +1,30 @@
+{
+ "_comment": "East-Coast / Caribbean pattern names → LA-area equivalents. Steve-editable. Used by build_dryrun.js to propose new titles.",
+ "_unchanged_means": "name stays as-is (abstract pattern with no geographic bias, or already LA)",
+ "map": {
+ "Kennebunkport": "Malibu",
+ "Bar Harbor": "Santa Monica",
+ "Cape May": "Venice Beach",
+ "Martha's Vineyard": "Catalina",
+ "Block Island": "Avalon",
+ "Nantucket": "Pacific Palisades",
+ "Montauk": "Manhattan Beach",
+ "Hilton Head": "Hermosa Beach",
+ "Amelia Island": "Redondo Beach",
+ "Kiawah": "Ojai",
+ "Hollywood": "Hollywood",
+ "Necker Island": "Catalina Cove",
+ "Norman Island": "Pirates Cove",
+ "Palm Island": "Palm Drive",
+ "Parrot Cay": "Pelican Cove",
+ "Stone Haven": "Stone Canyon",
+ "Turneffe": "Topanga",
+ "Tobago": "Tujunga",
+ "Storm Bay": "Storm Bay",
+ "Tradewind Trace": "Tradewind Trace",
+ "Sandy Point Stripe": "Will Rogers Stripe",
+ "Sisal Bay": "Solstice Bay",
+ "Nassau Gold": "Brentwood Gold",
+ "Turf Bay": "Turf Bay"
+ }
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..9d34830
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,162 @@
+{
+ "name": "dwla-rebrand",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "dwla-rebrand",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "pg": "^8.20.0"
+ }
+ },
+ "node_modules/pg": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz",
+ "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==",
+ "license": "MIT",
+ "dependencies": {
+ "pg-connection-string": "^2.12.0",
+ "pg-pool": "^3.13.0",
+ "pg-protocol": "^1.13.0",
+ "pg-types": "2.2.0",
+ "pgpass": "1.0.5"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "optionalDependencies": {
+ "pg-cloudflare": "^1.3.0"
+ },
+ "peerDependencies": {
+ "pg-native": ">=3.0.1"
+ },
+ "peerDependenciesMeta": {
+ "pg-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pg-cloudflare": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz",
+ "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/pg-connection-string": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz",
+ "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==",
+ "license": "MIT"
+ },
+ "node_modules/pg-int8": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
+ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/pg-pool": {
+ "version": "3.13.0",
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz",
+ "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "pg": ">=8.0"
+ }
+ },
+ "node_modules/pg-protocol": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz",
+ "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==",
+ "license": "MIT"
+ },
+ "node_modules/pg-types": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
+ "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "license": "MIT",
+ "dependencies": {
+ "pg-int8": "1.0.1",
+ "postgres-array": "~2.0.0",
+ "postgres-bytea": "~1.0.0",
+ "postgres-date": "~1.0.4",
+ "postgres-interval": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pgpass": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
+ "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
+ "license": "MIT",
+ "dependencies": {
+ "split2": "^4.1.0"
+ }
+ },
+ "node_modules/postgres-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postgres-bytea": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
+ "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-date": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-interval": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7dbe273
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "dwla-rebrand",
+ "version": "1.0.0",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "description": "",
+ "dependencies": {
+ "pg": "^8.20.0"
+ }
+}
diff --git a/preview/phase1.csv b/preview/phase1.csv
new file mode 100644
index 0000000..20b39ba
--- /dev/null
+++ b/preview/phase1.csv
@@ -0,0 +1,33 @@
+action,registry_dw_sku,registry_mfr_sku,proposed_dwla_sku,shopify_id,old_handle,new_handle,old_sku,new_sku,old_vendor,new_vendor,old_title,new_title
+rename_canonical,DWPN-101203,PI-PAMPAS-AQUA,DWLA-100001,1246038,parrot-cay-aqua,pelican-cove-aqua,DWPR-426812,DWLA-100001,Phillipe Romano,Los Angeles Fabrics,"Pampas - Aqua Sustainable Bio-Based | Phillipe Romano","Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101203,PI-PAMPAS-AQUA,DWLA-100001,1246328,parrot-cay-aqua-1,pelican-cove-aqua-1,DWPN-101203,DWLA-100001,Phillipe Romano,Los Angeles Fabrics,"Pampas - Aqua Sustainable Bio-Based | Phillipe Romano","Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101204,PI-PAMPAS-BEACH,DWLA-100002,1246039,parrot-cay-beach,pelican-cove-beach,DWPR-426813,DWLA-100002,Phillipe Romano,Los Angeles Fabrics,"Pampas - Beach Sustainable Bio-Based | Phillipe Romano","Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101204,PI-PAMPAS-BEACH,DWLA-100002,1246329,parrot-cay-beach-1,pelican-cove-beach-1,DWPR-426813,DWLA-100002,Phillipe Romano,Los Angeles Fabrics,"Pampas - Beach Sustainable Bio-Based | Phillipe Romano","Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101205,PI-PAMPAS-CLOUD,DWLA-100003,1246040,parrot-cay-cloud,pelican-cove-cloud,DWPR-426814,DWLA-100003,Phillipe Romano,Los Angeles Fabrics,"Pampas - Cloud Sustainable Bio-Based | Phillipe Romano","Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101205,PI-PAMPAS-CLOUD,DWLA-100003,1246330,parrot-cay-cloud-1,pelican-cove-cloud-1,DWPN-101205,DWLA-100003,Phillipe Romano,Los Angeles Fabrics,"Pampas - Cloud Sustainable Bio-Based | Phillipe Romano","Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101206,PI-PAMPAS-CORAL,DWLA-100004,1246041,parrot-cay-coral,pelican-cove-coral,DWPR-426815,DWLA-100004,Phillipe Romano,Los Angeles Fabrics,"Pampas - Coral Sustainable Bio-Based | Phillipe Romano","Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101206,PI-PAMPAS-CORAL,DWLA-100004,1246331,parrot-cay-coral-1,pelican-cove-coral-1,DWPR-426815,DWLA-100004,Phillipe Romano,Los Angeles Fabrics,"Pampas - Coral Sustainable Bio-Based | Phillipe Romano","Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101207,PI-PAMPAS-FIELD,DWLA-100005,1246042,parrot-cay-field,pelican-cove-field,DWPR-426816,DWLA-100005,Phillipe Romano,Los Angeles Fabrics,"Pampas - Field Sustainable Bio-Based | Phillipe Romano","Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101207,PI-PAMPAS-FIELD,DWLA-100005,1246332,parrot-cay-field-1,pelican-cove-field-1,DWPR-426816,DWLA-100005,Phillipe Romano,Los Angeles Fabrics,"Pampas - Field Sustainable Bio-Based | Phillipe Romano","Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101208,PI-PAMPAS-HARBOR,DWLA-100006,1246043,parrot-cay-harbor,pelican-cove-harbor,DWPR-426817,DWLA-100006,Phillipe Romano,Los Angeles Fabrics,"Pampas - Harbor Sustainable Bio-Based | Phillipe Romano","Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101208,PI-PAMPAS-HARBOR,DWLA-100006,1246333,parrot-cay-harbor-1,pelican-cove-harbor-1,DWPR-426817,DWLA-100006,Phillipe Romano,Los Angeles Fabrics,"Pampas - Harbor Sustainable Bio-Based | Phillipe Romano","Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101209,PI-PAMPAS-HARVEST,DWLA-100007,1246044,parrot-cay-harvest,pelican-cove-harvest,DWPR-426818,DWLA-100007,Phillipe Romano,Los Angeles Fabrics,"Pampas - Harvest Sustainable Bio-Based | Phillipe Romano","Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101209,PI-PAMPAS-HARVEST,DWLA-100007,1246334,parrot-cay-harvest-1,pelican-cove-harvest-1,DWPR-426818,DWLA-100007,Phillipe Romano,Los Angeles Fabrics,"Pampas - Harvest Sustainable Bio-Based | Phillipe Romano","Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101210,PI-PAMPAS-LAGOON,DWLA-100008,1246045,parrot-cay-lagoon,pelican-cove-lagoon,DWPR-426819,DWLA-100008,Phillipe Romano,Los Angeles Fabrics,"Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano","Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101210,PI-PAMPAS-LAGOON,DWLA-100008,1246335,parrot-cay-lagoon-1,pelican-cove-lagoon-1,DWPN-101210,DWLA-100008,Phillipe Romano,Los Angeles Fabrics,"Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano","Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101211,PI-PAMPAS-MOUSE,DWLA-100009,1246046,parrot-cay-mouse,pelican-cove-mouse,DWPR-426820,DWLA-100009,Phillipe Romano,Los Angeles Fabrics,"Pampas - Mouse Sustainable Bio-Based | Phillipe Romano","Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101211,PI-PAMPAS-MOUSE,DWLA-100009,1246336,parrot-cay-mouse-1,pelican-cove-mouse-1,DWPN-101211,DWLA-100009,Phillipe Romano,Los Angeles Fabrics,"Pampas - Mouse Sustainable Bio-Based | Phillipe Romano","Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101212,PI-PAMPAS-NIGHT,DWLA-100010,1246047,parrot-cay-night,pelican-cove-night,DWPR-426821,DWLA-100010,Phillipe Romano,Los Angeles Fabrics,"Pampas - Night Sustainable Bio-Based | Phillipe Romano","Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101212,PI-PAMPAS-NIGHT,DWLA-100010,1246337,parrot-cay-night-1,pelican-cove-night-1,DWPR-426821,DWLA-100010,Phillipe Romano,Los Angeles Fabrics,"Pampas - Night Sustainable Bio-Based | Phillipe Romano","Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101213,PI-PAMPAS-SAGE,DWLA-100011,1246048,parrot-cay-sage,pelican-cove-sage,DWPR-426822,DWLA-100011,Phillipe Romano,Los Angeles Fabrics,"Pampas - Sage Sustainable Bio-Based | Phillipe Romano","Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101213,PI-PAMPAS-SAGE,DWLA-100011,1246338,parrot-cay-sage-1,pelican-cove-sage-1,DWPN-101213,DWLA-100011,Phillipe Romano,Los Angeles Fabrics,"Pampas - Sage Sustainable Bio-Based | Phillipe Romano","Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101214,PI-PAMPAS-SEASCAPE,DWLA-100013,1246049,parrot-cay-seascape,pelican-cove-seascape,DWPR-426824,DWLA-100013,Phillipe Romano,Los Angeles Fabrics,"Pampas - Seascape Sustainable Bio-Based | Phillipe Romano","Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101214,PI-PAMPAS-SEASCAPE,DWLA-100013,1246339,parrot-cay-seascape-1,pelican-cove-seascape-1,DWPN-101214,DWLA-100013,Phillipe Romano,Los Angeles Fabrics,"Pampas - Seascape Sustainable Bio-Based | Phillipe Romano","Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101215,PI-PAMPAS-SMOKE,DWLA-100014,1246050,parrot-cay-smoke,pelican-cove-smoke,DWPR-426825,DWLA-100014,Phillipe Romano,Los Angeles Fabrics,"Pampas - Smoke Sustainable Bio-Based | Phillipe Romano","Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101215,PI-PAMPAS-SMOKE,DWLA-100014,1246340,parrot-cay-smoke-1,pelican-cove-smoke-1,DWPR-426825,DWLA-100014,Phillipe Romano,Los Angeles Fabrics,"Pampas - Smoke Sustainable Bio-Based | Phillipe Romano","Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101216,PI-PAMPAS-SNOW,DWLA-100015,1246051,parrot-cay-snow,pelican-cove-snow,DWPR-426826,DWLA-100015,Phillipe Romano,Los Angeles Fabrics,"Pampas - Snow Sustainable Bio-Based | Phillipe Romano","Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101216,PI-PAMPAS-SNOW,DWLA-100015,1246341,parrot-cay-snow-1,pelican-cove-snow-1,DWPN-101216,DWLA-100015,Phillipe Romano,Los Angeles Fabrics,"Pampas - Snow Sustainable Bio-Based | Phillipe Romano","Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101217,PI-PAMPAS-SPRING,DWLA-100016,1246052,parrot-cay-spring,pelican-cove-spring,DWPR-426827,DWLA-100016,Phillipe Romano,Los Angeles Fabrics,"Pampas - Spring Sustainable Bio-Based | Phillipe Romano","Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101217,PI-PAMPAS-SPRING,DWLA-100016,1246342,parrot-cay-spring-1,pelican-cove-spring-1,DWPR-426827,DWLA-100016,Phillipe Romano,Los Angeles Fabrics,"Pampas - Spring Sustainable Bio-Based | Phillipe Romano","Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics"
+rename_canonical,DWPN-101218,PI-PAMPAS-STERLING,DWLA-100017,1246053,parrot-cay-sterling,pelican-cove-sterling,DWPR-426828,DWLA-100017,Phillipe Romano,Los Angeles Fabrics,"Pampas - Sterling Sustainable Bio-Based | Phillipe Romano","Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics"
+archive_duplicate,DWPN-101218,PI-PAMPAS-STERLING,DWLA-100017,1246343,parrot-cay-sterling-1,pelican-cove-sterling-1,DWPN-101218,DWLA-100017,Phillipe Romano,Los Angeles Fabrics,"Pampas - Sterling Sustainable Bio-Based | Phillipe Romano","Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics"
\ No newline at end of file
diff --git a/preview/phase1.html b/preview/phase1.html
new file mode 100644
index 0000000..2a652fb
--- /dev/null
+++ b/preview/phase1.html
@@ -0,0 +1,214 @@
+<!doctype html>
+<html><head><meta charset="utf-8"><title>DWLA Rebrand · Phase 1 preview</title>
+<style>
+body{font:13px/1.45 -apple-system,Segoe UI,Helvetica,Arial,sans-serif;margin:24px;background:#fafaf7;color:#222}
+h1{font-weight:600;font-size:22px}
+.meta{color:#666;margin-bottom:24px}
+table{border-collapse:collapse;width:100%;margin:14px 0;font-size:12px}
+th,td{padding:6px 8px;border-bottom:1px solid #eee;vertical-align:top;text-align:left}
+th{background:#f0ede4;font-weight:600;color:#444}
+.action-archive{color:#a44;font-weight:500}
+.action-canonical{color:#262;font-weight:500}
+.old{color:#888;text-decoration:line-through;font-family:ui-monospace,monospace;font-size:11px}
+.new{color:#262;font-family:ui-monospace,monospace;font-size:11px}
+.sku{font-family:ui-monospace,monospace}
+.warn{background:#fffbe7;border:1px solid #f0e1a8;padding:10px 12px;margin:12px 0;border-radius:6px}
+.ok{background:#e9f6ec;border:1px solid #b3dfb8;padding:10px 12px;margin:12px 0;border-radius:6px}
+</style></head><body>
+<h1>DWLA Rebrand · Phase 1 dry-run preview</h1>
+<div class="meta">Generated 2026-05-07T22:09:22.610Z · 17 registry rows · 32 Shopify products affected</div>
+<div class="warn">
+ <strong>NO Shopify writes have happened.</strong> This is a dry-run. Approve below to generate <code>push_phase1.js</code>; review that before execution.
+</div><h3>DWPN-101203 · PI-PAMPAS-AQUA · → <span class="sku">DWLA-100001</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246038</td>
+<td><div class="old">parrot-cay-aqua</div><div class="new">pelican-cove-aqua</div></td>
+<td><div class="old">DWPR-426812</div><div class="new">DWLA-100001</div></td>
+<td><div class="old">Pampas - Aqua Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246328</td>
+<td><div class="old">parrot-cay-aqua-1</div><div class="new">pelican-cove-aqua-1</div></td>
+<td><div class="old">DWPN-101203</div><div class="new">DWLA-100001</div></td>
+<td><div class="old">Pampas - Aqua Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101204 · PI-PAMPAS-BEACH · → <span class="sku">DWLA-100002</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246039</td>
+<td><div class="old">parrot-cay-beach</div><div class="new">pelican-cove-beach</div></td>
+<td><div class="old">DWPR-426813</div><div class="new">DWLA-100002</div></td>
+<td><div class="old">Pampas - Beach Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246329</td>
+<td><div class="old">parrot-cay-beach-1</div><div class="new">pelican-cove-beach-1</div></td>
+<td><div class="old">DWPR-426813</div><div class="new">DWLA-100002</div></td>
+<td><div class="old">Pampas - Beach Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101205 · PI-PAMPAS-CLOUD · → <span class="sku">DWLA-100003</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246040</td>
+<td><div class="old">parrot-cay-cloud</div><div class="new">pelican-cove-cloud</div></td>
+<td><div class="old">DWPR-426814</div><div class="new">DWLA-100003</div></td>
+<td><div class="old">Pampas - Cloud Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246330</td>
+<td><div class="old">parrot-cay-cloud-1</div><div class="new">pelican-cove-cloud-1</div></td>
+<td><div class="old">DWPN-101205</div><div class="new">DWLA-100003</div></td>
+<td><div class="old">Pampas - Cloud Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101206 · PI-PAMPAS-CORAL · → <span class="sku">DWLA-100004</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246041</td>
+<td><div class="old">parrot-cay-coral</div><div class="new">pelican-cove-coral</div></td>
+<td><div class="old">DWPR-426815</div><div class="new">DWLA-100004</div></td>
+<td><div class="old">Pampas - Coral Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246331</td>
+<td><div class="old">parrot-cay-coral-1</div><div class="new">pelican-cove-coral-1</div></td>
+<td><div class="old">DWPR-426815</div><div class="new">DWLA-100004</div></td>
+<td><div class="old">Pampas - Coral Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101207 · PI-PAMPAS-FIELD · → <span class="sku">DWLA-100005</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246042</td>
+<td><div class="old">parrot-cay-field</div><div class="new">pelican-cove-field</div></td>
+<td><div class="old">DWPR-426816</div><div class="new">DWLA-100005</div></td>
+<td><div class="old">Pampas - Field Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246332</td>
+<td><div class="old">parrot-cay-field-1</div><div class="new">pelican-cove-field-1</div></td>
+<td><div class="old">DWPR-426816</div><div class="new">DWLA-100005</div></td>
+<td><div class="old">Pampas - Field Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101208 · PI-PAMPAS-HARBOR · → <span class="sku">DWLA-100006</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246043</td>
+<td><div class="old">parrot-cay-harbor</div><div class="new">pelican-cove-harbor</div></td>
+<td><div class="old">DWPR-426817</div><div class="new">DWLA-100006</div></td>
+<td><div class="old">Pampas - Harbor Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246333</td>
+<td><div class="old">parrot-cay-harbor-1</div><div class="new">pelican-cove-harbor-1</div></td>
+<td><div class="old">DWPR-426817</div><div class="new">DWLA-100006</div></td>
+<td><div class="old">Pampas - Harbor Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101209 · PI-PAMPAS-HARVEST · → <span class="sku">DWLA-100007</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246044</td>
+<td><div class="old">parrot-cay-harvest</div><div class="new">pelican-cove-harvest</div></td>
+<td><div class="old">DWPR-426818</div><div class="new">DWLA-100007</div></td>
+<td><div class="old">Pampas - Harvest Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246334</td>
+<td><div class="old">parrot-cay-harvest-1</div><div class="new">pelican-cove-harvest-1</div></td>
+<td><div class="old">DWPR-426818</div><div class="new">DWLA-100007</div></td>
+<td><div class="old">Pampas - Harvest Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101210 · PI-PAMPAS-LAGOON · → <span class="sku">DWLA-100008</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246045</td>
+<td><div class="old">parrot-cay-lagoon</div><div class="new">pelican-cove-lagoon</div></td>
+<td><div class="old">DWPR-426819</div><div class="new">DWLA-100008</div></td>
+<td><div class="old">Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246335</td>
+<td><div class="old">parrot-cay-lagoon-1</div><div class="new">pelican-cove-lagoon-1</div></td>
+<td><div class="old">DWPN-101210</div><div class="new">DWLA-100008</div></td>
+<td><div class="old">Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101211 · PI-PAMPAS-MOUSE · → <span class="sku">DWLA-100009</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246046</td>
+<td><div class="old">parrot-cay-mouse</div><div class="new">pelican-cove-mouse</div></td>
+<td><div class="old">DWPR-426820</div><div class="new">DWLA-100009</div></td>
+<td><div class="old">Pampas - Mouse Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246336</td>
+<td><div class="old">parrot-cay-mouse-1</div><div class="new">pelican-cove-mouse-1</div></td>
+<td><div class="old">DWPN-101211</div><div class="new">DWLA-100009</div></td>
+<td><div class="old">Pampas - Mouse Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101212 · PI-PAMPAS-NIGHT · → <span class="sku">DWLA-100010</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246047</td>
+<td><div class="old">parrot-cay-night</div><div class="new">pelican-cove-night</div></td>
+<td><div class="old">DWPR-426821</div><div class="new">DWLA-100010</div></td>
+<td><div class="old">Pampas - Night Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246337</td>
+<td><div class="old">parrot-cay-night-1</div><div class="new">pelican-cove-night-1</div></td>
+<td><div class="old">DWPR-426821</div><div class="new">DWLA-100010</div></td>
+<td><div class="old">Pampas - Night Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101213 · PI-PAMPAS-SAGE · → <span class="sku">DWLA-100011</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246048</td>
+<td><div class="old">parrot-cay-sage</div><div class="new">pelican-cove-sage</div></td>
+<td><div class="old">DWPR-426822</div><div class="new">DWLA-100011</div></td>
+<td><div class="old">Pampas - Sage Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246338</td>
+<td><div class="old">parrot-cay-sage-1</div><div class="new">pelican-cove-sage-1</div></td>
+<td><div class="old">DWPN-101213</div><div class="new">DWLA-100011</div></td>
+<td><div class="old">Pampas - Sage Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-102567 · PI-PAMPAS-SEA-GREEN · → <span class="sku">DWLA-100012</span></h3><p style="color:#a44">No Shopify products matched.</p><h3>DWPN-101214 · PI-PAMPAS-SEASCAPE · → <span class="sku">DWLA-100013</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246049</td>
+<td><div class="old">parrot-cay-seascape</div><div class="new">pelican-cove-seascape</div></td>
+<td><div class="old">DWPR-426824</div><div class="new">DWLA-100013</div></td>
+<td><div class="old">Pampas - Seascape Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246339</td>
+<td><div class="old">parrot-cay-seascape-1</div><div class="new">pelican-cove-seascape-1</div></td>
+<td><div class="old">DWPN-101214</div><div class="new">DWLA-100013</div></td>
+<td><div class="old">Pampas - Seascape Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101215 · PI-PAMPAS-SMOKE · → <span class="sku">DWLA-100014</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246050</td>
+<td><div class="old">parrot-cay-smoke</div><div class="new">pelican-cove-smoke</div></td>
+<td><div class="old">DWPR-426825</div><div class="new">DWLA-100014</div></td>
+<td><div class="old">Pampas - Smoke Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246340</td>
+<td><div class="old">parrot-cay-smoke-1</div><div class="new">pelican-cove-smoke-1</div></td>
+<td><div class="old">DWPR-426825</div><div class="new">DWLA-100014</div></td>
+<td><div class="old">Pampas - Smoke Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101216 · PI-PAMPAS-SNOW · → <span class="sku">DWLA-100015</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246051</td>
+<td><div class="old">parrot-cay-snow</div><div class="new">pelican-cove-snow</div></td>
+<td><div class="old">DWPR-426826</div><div class="new">DWLA-100015</div></td>
+<td><div class="old">Pampas - Snow Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246341</td>
+<td><div class="old">parrot-cay-snow-1</div><div class="new">pelican-cove-snow-1</div></td>
+<td><div class="old">DWPN-101216</div><div class="new">DWLA-100015</div></td>
+<td><div class="old">Pampas - Snow Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101217 · PI-PAMPAS-SPRING · → <span class="sku">DWLA-100016</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246052</td>
+<td><div class="old">parrot-cay-spring</div><div class="new">pelican-cove-spring</div></td>
+<td><div class="old">DWPR-426827</div><div class="new">DWLA-100016</div></td>
+<td><div class="old">Pampas - Spring Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246342</td>
+<td><div class="old">parrot-cay-spring-1</div><div class="new">pelican-cove-spring-1</div></td>
+<td><div class="old">DWPR-426827</div><div class="new">DWLA-100016</div></td>
+<td><div class="old">Pampas - Spring Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><h3>DWPN-101218 · PI-PAMPAS-STERLING · → <span class="sku">DWLA-100017</span></h3><table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr><tr>
+<td class="action-canonical">rename_canonical</td>
+<td>1246053</td>
+<td><div class="old">parrot-cay-sterling</div><div class="new">pelican-cove-sterling</div></td>
+<td><div class="old">DWPR-426828</div><div class="new">DWLA-100017</div></td>
+<td><div class="old">Pampas - Sterling Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr><tr>
+<td class="action-archive">archive_duplicate</td>
+<td>1246343</td>
+<td><div class="old">parrot-cay-sterling-1</div><div class="new">pelican-cove-sterling-1</div></td>
+<td><div class="old">DWPN-101218</div><div class="new">DWLA-100017</div></td>
+<td><div class="old">Pampas - Sterling Sustainable Bio-Based | Phillipe Romano</div><div class="new">Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics</div></td>
+</tr></table><div class="ok"><strong>Next step:</strong> review the diffs above. If all looks correct, reply "GO phase 1" and I'll write <code>push_phase1.js</code> for your final approval before any Shopify call.</div></body></html>
\ No newline at end of file
diff --git a/preview/phase1.json b/preview/phase1.json
new file mode 100644
index 0000000..df75db7
--- /dev/null
+++ b/preview/phase1.json
@@ -0,0 +1,623 @@
+[
+ {
+ "registry": {
+ "id": 86948,
+ "dw_sku": "DWPN-101203",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-AQUA",
+ "shopify_product_id": "7792236986419"
+ },
+ "colorway": "Aqua",
+ "proposed_dwla_sku": "DWLA-100001",
+ "shopify_products": [
+ {
+ "old_id": 1246038,
+ "old_handle": "parrot-cay-aqua",
+ "old_sku": "DWPR-426812",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Aqua Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-aqua",
+ "new_sku": "DWLA-100001",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246328,
+ "old_handle": "parrot-cay-aqua-1",
+ "old_sku": "DWPN-101203",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Aqua Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-aqua-1",
+ "new_sku": "DWLA-100001",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Aqua Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86949,
+ "dw_sku": "DWPN-101204",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-BEACH",
+ "shopify_product_id": null
+ },
+ "colorway": "Beach",
+ "proposed_dwla_sku": "DWLA-100002",
+ "shopify_products": [
+ {
+ "old_id": 1246039,
+ "old_handle": "parrot-cay-beach",
+ "old_sku": "DWPR-426813",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Beach Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-beach",
+ "new_sku": "DWLA-100002",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246329,
+ "old_handle": "parrot-cay-beach-1",
+ "old_sku": "DWPR-426813",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Beach Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-beach-1",
+ "new_sku": "DWLA-100002",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Beach Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86950,
+ "dw_sku": "DWPN-101205",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-CLOUD",
+ "shopify_product_id": "7792237051955"
+ },
+ "colorway": "Cloud",
+ "proposed_dwla_sku": "DWLA-100003",
+ "shopify_products": [
+ {
+ "old_id": 1246040,
+ "old_handle": "parrot-cay-cloud",
+ "old_sku": "DWPR-426814",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Cloud Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-cloud",
+ "new_sku": "DWLA-100003",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246330,
+ "old_handle": "parrot-cay-cloud-1",
+ "old_sku": "DWPN-101205",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Cloud Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-cloud-1",
+ "new_sku": "DWLA-100003",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Cloud Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86951,
+ "dw_sku": "DWPN-101206",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-CORAL",
+ "shopify_product_id": null
+ },
+ "colorway": "Coral",
+ "proposed_dwla_sku": "DWLA-100004",
+ "shopify_products": [
+ {
+ "old_id": 1246041,
+ "old_handle": "parrot-cay-coral",
+ "old_sku": "DWPR-426815",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Coral Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-coral",
+ "new_sku": "DWLA-100004",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246331,
+ "old_handle": "parrot-cay-coral-1",
+ "old_sku": "DWPR-426815",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Coral Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-coral-1",
+ "new_sku": "DWLA-100004",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Coral Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86952,
+ "dw_sku": "DWPN-101207",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-FIELD",
+ "shopify_product_id": null
+ },
+ "colorway": "Field",
+ "proposed_dwla_sku": "DWLA-100005",
+ "shopify_products": [
+ {
+ "old_id": 1246042,
+ "old_handle": "parrot-cay-field",
+ "old_sku": "DWPR-426816",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Field Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-field",
+ "new_sku": "DWLA-100005",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246332,
+ "old_handle": "parrot-cay-field-1",
+ "old_sku": "DWPR-426816",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Field Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-field-1",
+ "new_sku": "DWLA-100005",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Field Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86953,
+ "dw_sku": "DWPN-101208",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-HARBOR",
+ "shopify_product_id": null
+ },
+ "colorway": "Harbor",
+ "proposed_dwla_sku": "DWLA-100006",
+ "shopify_products": [
+ {
+ "old_id": 1246043,
+ "old_handle": "parrot-cay-harbor",
+ "old_sku": "DWPR-426817",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Harbor Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-harbor",
+ "new_sku": "DWLA-100006",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246333,
+ "old_handle": "parrot-cay-harbor-1",
+ "old_sku": "DWPR-426817",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Harbor Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-harbor-1",
+ "new_sku": "DWLA-100006",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Harbor Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86954,
+ "dw_sku": "DWPN-101209",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-HARVEST",
+ "shopify_product_id": null
+ },
+ "colorway": "Harvest",
+ "proposed_dwla_sku": "DWLA-100007",
+ "shopify_products": [
+ {
+ "old_id": 1246044,
+ "old_handle": "parrot-cay-harvest",
+ "old_sku": "DWPR-426818",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Harvest Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-harvest",
+ "new_sku": "DWLA-100007",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246334,
+ "old_handle": "parrot-cay-harvest-1",
+ "old_sku": "DWPR-426818",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Harvest Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-harvest-1",
+ "new_sku": "DWLA-100007",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Harvest Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86955,
+ "dw_sku": "DWPN-101210",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-LAGOON",
+ "shopify_product_id": "7792237215795"
+ },
+ "colorway": "Lagoon",
+ "proposed_dwla_sku": "DWLA-100008",
+ "shopify_products": [
+ {
+ "old_id": 1246045,
+ "old_handle": "parrot-cay-lagoon",
+ "old_sku": "DWPR-426819",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-lagoon",
+ "new_sku": "DWLA-100008",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246335,
+ "old_handle": "parrot-cay-lagoon-1",
+ "old_sku": "DWPN-101210",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Lagoon Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-lagoon-1",
+ "new_sku": "DWLA-100008",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Lagoon Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86956,
+ "dw_sku": "DWPN-101211",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-MOUSE",
+ "shopify_product_id": "7792237248563"
+ },
+ "colorway": "Mouse",
+ "proposed_dwla_sku": "DWLA-100009",
+ "shopify_products": [
+ {
+ "old_id": 1246046,
+ "old_handle": "parrot-cay-mouse",
+ "old_sku": "DWPR-426820",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Mouse Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-mouse",
+ "new_sku": "DWLA-100009",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246336,
+ "old_handle": "parrot-cay-mouse-1",
+ "old_sku": "DWPN-101211",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Mouse Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-mouse-1",
+ "new_sku": "DWLA-100009",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Mouse Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86957,
+ "dw_sku": "DWPN-101212",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-NIGHT",
+ "shopify_product_id": null
+ },
+ "colorway": "Night",
+ "proposed_dwla_sku": "DWLA-100010",
+ "shopify_products": [
+ {
+ "old_id": 1246047,
+ "old_handle": "parrot-cay-night",
+ "old_sku": "DWPR-426821",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Night Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-night",
+ "new_sku": "DWLA-100010",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246337,
+ "old_handle": "parrot-cay-night-1",
+ "old_sku": "DWPR-426821",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Night Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-night-1",
+ "new_sku": "DWLA-100010",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Night Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86958,
+ "dw_sku": "DWPN-101213",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SAGE",
+ "shopify_product_id": "7792237314099"
+ },
+ "colorway": "Sage",
+ "proposed_dwla_sku": "DWLA-100011",
+ "shopify_products": [
+ {
+ "old_id": 1246048,
+ "old_handle": "parrot-cay-sage",
+ "old_sku": "DWPR-426822",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Sage Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-sage",
+ "new_sku": "DWLA-100011",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246338,
+ "old_handle": "parrot-cay-sage-1",
+ "old_sku": "DWPN-101213",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Sage Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-sage-1",
+ "new_sku": "DWLA-100011",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Sage Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 88312,
+ "dw_sku": "DWPN-102567",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SEA-GREEN",
+ "shopify_product_id": null
+ },
+ "colorway": "Sea-green",
+ "proposed_dwla_sku": "DWLA-100012",
+ "shopify_products": []
+ },
+ {
+ "registry": {
+ "id": 86959,
+ "dw_sku": "DWPN-101214",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SEASCAPE",
+ "shopify_product_id": "7792237379635"
+ },
+ "colorway": "Seascape",
+ "proposed_dwla_sku": "DWLA-100013",
+ "shopify_products": [
+ {
+ "old_id": 1246049,
+ "old_handle": "parrot-cay-seascape",
+ "old_sku": "DWPR-426824",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Seascape Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-seascape",
+ "new_sku": "DWLA-100013",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246339,
+ "old_handle": "parrot-cay-seascape-1",
+ "old_sku": "DWPN-101214",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Seascape Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-seascape-1",
+ "new_sku": "DWLA-100013",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Seascape Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86960,
+ "dw_sku": "DWPN-101215",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SMOKE",
+ "shopify_product_id": null
+ },
+ "colorway": "Smoke",
+ "proposed_dwla_sku": "DWLA-100014",
+ "shopify_products": [
+ {
+ "old_id": 1246050,
+ "old_handle": "parrot-cay-smoke",
+ "old_sku": "DWPR-426825",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Smoke Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-smoke",
+ "new_sku": "DWLA-100014",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246340,
+ "old_handle": "parrot-cay-smoke-1",
+ "old_sku": "DWPR-426825",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Smoke Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-smoke-1",
+ "new_sku": "DWLA-100014",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Smoke Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86961,
+ "dw_sku": "DWPN-101216",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SNOW",
+ "shopify_product_id": "7792237445171"
+ },
+ "colorway": "Snow",
+ "proposed_dwla_sku": "DWLA-100015",
+ "shopify_products": [
+ {
+ "old_id": 1246051,
+ "old_handle": "parrot-cay-snow",
+ "old_sku": "DWPR-426826",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Snow Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-snow",
+ "new_sku": "DWLA-100015",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246341,
+ "old_handle": "parrot-cay-snow-1",
+ "old_sku": "DWPN-101216",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Snow Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-snow-1",
+ "new_sku": "DWLA-100015",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Snow Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86962,
+ "dw_sku": "DWPN-101217",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-SPRING",
+ "shopify_product_id": null
+ },
+ "colorway": "Spring",
+ "proposed_dwla_sku": "DWLA-100016",
+ "shopify_products": [
+ {
+ "old_id": 1246052,
+ "old_handle": "parrot-cay-spring",
+ "old_sku": "DWPR-426827",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Spring Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-spring",
+ "new_sku": "DWLA-100016",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246342,
+ "old_handle": "parrot-cay-spring-1",
+ "old_sku": "DWPR-426827",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Spring Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-spring-1",
+ "new_sku": "DWLA-100016",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Spring Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ },
+ {
+ "registry": {
+ "id": 86963,
+ "dw_sku": "DWPN-101218",
+ "vendor_prefix": "DWPN",
+ "vendor_name": "Phillipe Romano",
+ "mfr_sku": "PI-PAMPAS-STERLING",
+ "shopify_product_id": "7792237510707"
+ },
+ "colorway": "Sterling",
+ "proposed_dwla_sku": "DWLA-100017",
+ "shopify_products": [
+ {
+ "old_id": 1246053,
+ "old_handle": "parrot-cay-sterling",
+ "old_sku": "DWPR-426828",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Sterling Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-sterling",
+ "new_sku": "DWLA-100017",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "rename_canonical"
+ },
+ {
+ "old_id": 1246343,
+ "old_handle": "parrot-cay-sterling-1",
+ "old_sku": "DWPN-101218",
+ "old_vendor": "Phillipe Romano",
+ "old_title": "Pampas - Sterling Sustainable Bio-Based | Phillipe Romano",
+ "new_handle": "pelican-cove-sterling-1",
+ "new_sku": "DWLA-100017",
+ "new_vendor": "Los Angeles Fabrics",
+ "new_title": "Pampas - Sterling Sustainable Bio-Based | Los Angeles Fabrics",
+ "action": "archive_duplicate"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/scripts/build_dryrun.js b/scripts/build_dryrun.js
new file mode 100644
index 0000000..0ae719e
--- /dev/null
+++ b/scripts/build_dryrun.js
@@ -0,0 +1,187 @@
+#!/usr/bin/env node
+// Dry-run builder for DWLA rebrand.
+// Phase 1: 17 PI-PAMPAS-* registry rows + their 17 dup `-1` Shopify records.
+// Output: preview/phase1.html + preview/phase1.csv + preview/phase1.json
+// Reads dw_unified PG. Does NOT touch Shopify. Does NOT mutate registry.
+//
+// Run: node scripts/build_dryrun.js [--phase 1]
+
+const { Client } = require('pg');
+const fs = require('fs');
+const path = require('path');
+
+const PHASE = parseInt((process.argv.find(a => a.startsWith('--phase=')) || '--phase=1').split('=')[1], 10);
+const ROOT = path.join(__dirname, '..');
+const PREVIEW_DIR = path.join(ROOT, 'preview');
+fs.mkdirSync(PREVIEW_DIR, { recursive: true });
+
+const NAME_MAP = JSON.parse(fs.readFileSync(path.join(ROOT, 'data', 'la_name_map.json'), 'utf8')).map;
+
+const NEXT_DWLA_FILE = path.join(ROOT, 'data', 'dwla_sequence.txt');
+let nextDwla = 100001;
+if (fs.existsSync(NEXT_DWLA_FILE)) nextDwla = parseInt(fs.readFileSync(NEXT_DWLA_FILE, 'utf8').trim(), 10);
+
+function allocateDwla() {
+ const sku = `DWLA-${String(nextDwla).padStart(6, '0')}`;
+ nextDwla++;
+ return sku;
+}
+
+function rebrandTitle(t) {
+ if (!t) return t;
+ let out = t;
+ // Replace "| Phillipe Romano" suffix with "| Los Angeles Fabrics"
+ out = out.replace(/\|\s*Phillipe Romano\s*$/i, '| Los Angeles Fabrics');
+ out = out.replace(/\bPhillipe Romano\b/g, 'Los Angeles Fabrics');
+ // Apply East-Coast → LA name map (longest-first match to avoid "Bar Harbor" matching "Bar")
+ const keys = Object.keys(NAME_MAP).sort((a, b) => b.length - a.length);
+ for (const k of keys) {
+ if (NAME_MAP[k] === k) continue;
+ const re = new RegExp(`\\b${k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'g');
+ out = out.replace(re, NAME_MAP[k]);
+ }
+ return out;
+}
+
+function rebrandHandle(h) {
+ if (!h) return h;
+ let out = h;
+ // Generic: replace -phillipe-romano suffix variants
+ out = out.replace(/-phillipe-romano(-1)?$/i, '-los-angeles-fabrics$1');
+ // Replace pattern slugs (lowercase, hyphen) per name map
+ for (const k of Object.keys(NAME_MAP)) {
+ if (NAME_MAP[k] === k) continue;
+ const oldSlug = k.toLowerCase().replace(/['']/g, '').replace(/\s+/g, '-');
+ const newSlug = NAME_MAP[k].toLowerCase().replace(/['']/g, '').replace(/\s+/g, '-');
+ out = out.replace(new RegExp(`\\b${oldSlug}\\b`, 'g'), newSlug);
+ }
+ return out;
+}
+
+async function main() {
+ const c = new Client({ host: '/tmp', database: 'dw_unified' });
+ await c.connect();
+
+ // Phase 1 = the 17 PI-PAMPAS-* rows + their corresponding dup Shopify products
+ const registryRows = (await c.query(`
+ SELECT id, dw_sku, vendor_prefix, vendor_name, mfr_sku, shopify_product_id
+ FROM dw_sku_registry
+ WHERE mfr_sku LIKE 'PI-PAMPAS-%'
+ ORDER BY mfr_sku
+ `)).rows;
+
+ // For each registry row, find ALL Shopify products whose title matches the colorway
+ const records = [];
+ for (const r of registryRows) {
+ const colorway = r.mfr_sku.replace(/^PI-PAMPAS-/, '').toLowerCase();
+ const colorwayPretty = colorway.charAt(0).toUpperCase() + colorway.slice(1);
+ const shopify = (await c.query(`
+ SELECT id, handle, title, sku, vendor
+ FROM shopify_products
+ WHERE vendor = 'Phillipe Romano'
+ AND title ILIKE '%pampas%spring%' = false -- placeholder; replaced below
+ AND (title ILIKE $1 OR title ILIKE $2)
+ ORDER BY id
+ `.replace("title ILIKE '%pampas%spring%' = false -- placeholder; replaced below\n AND ", ""),
+ [`%pampas%${colorwayPretty}%`, `%pampas%${colorway}%`])).rows;
+
+ const dwlaSku = allocateDwla();
+ records.push({
+ registry: r,
+ colorway: colorwayPretty,
+ proposed_dwla_sku: dwlaSku,
+ shopify_products: shopify.map(s => ({
+ old_id: s.id,
+ old_handle: s.handle,
+ old_sku: s.sku,
+ old_vendor: s.vendor,
+ old_title: s.title,
+ new_handle: rebrandHandle(s.handle),
+ new_sku: dwlaSku,
+ new_vendor: 'Los Angeles Fabrics',
+ new_title: rebrandTitle(s.title),
+ action: s.handle.endsWith('-1') ? 'archive_duplicate' : 'rename_canonical'
+ }))
+ });
+ }
+
+ await c.end();
+
+ // Persist allocated sequence
+ fs.writeFileSync(NEXT_DWLA_FILE, String(nextDwla));
+
+ // Write JSON
+ const outJson = path.join(PREVIEW_DIR, `phase${PHASE}.json`);
+ fs.writeFileSync(outJson, JSON.stringify(records, null, 2));
+
+ // Write CSV
+ const outCsv = path.join(PREVIEW_DIR, `phase${PHASE}.csv`);
+ const csvLines = ['action,registry_dw_sku,registry_mfr_sku,proposed_dwla_sku,shopify_id,old_handle,new_handle,old_sku,new_sku,old_vendor,new_vendor,old_title,new_title'];
+ for (const rec of records) {
+ for (const sp of rec.shopify_products) {
+ csvLines.push([
+ sp.action, rec.registry.dw_sku, rec.registry.mfr_sku, rec.proposed_dwla_sku,
+ sp.old_id, sp.old_handle, sp.new_handle,
+ sp.old_sku, sp.new_sku, sp.old_vendor, sp.new_vendor,
+ JSON.stringify(sp.old_title), JSON.stringify(sp.new_title)
+ ].join(','));
+ }
+ }
+ fs.writeFileSync(outCsv, csvLines.join('\n'));
+
+ // Write HTML
+ const outHtml = path.join(PREVIEW_DIR, `phase${PHASE}.html`);
+ let html = `<!doctype html>
+<html><head><meta charset="utf-8"><title>DWLA Rebrand · Phase ${PHASE} preview</title>
+<style>
+body{font:13px/1.45 -apple-system,Segoe UI,Helvetica,Arial,sans-serif;margin:24px;background:#fafaf7;color:#222}
+h1{font-weight:600;font-size:22px}
+.meta{color:#666;margin-bottom:24px}
+table{border-collapse:collapse;width:100%;margin:14px 0;font-size:12px}
+th,td{padding:6px 8px;border-bottom:1px solid #eee;vertical-align:top;text-align:left}
+th{background:#f0ede4;font-weight:600;color:#444}
+.action-archive{color:#a44;font-weight:500}
+.action-canonical{color:#262;font-weight:500}
+.old{color:#888;text-decoration:line-through;font-family:ui-monospace,monospace;font-size:11px}
+.new{color:#262;font-family:ui-monospace,monospace;font-size:11px}
+.sku{font-family:ui-monospace,monospace}
+.warn{background:#fffbe7;border:1px solid #f0e1a8;padding:10px 12px;margin:12px 0;border-radius:6px}
+.ok{background:#e9f6ec;border:1px solid #b3dfb8;padding:10px 12px;margin:12px 0;border-radius:6px}
+</style></head><body>
+<h1>DWLA Rebrand · Phase ${PHASE} dry-run preview</h1>
+<div class="meta">Generated ${new Date().toISOString()} · ${records.length} registry rows · ${records.reduce((a,r)=>a+r.shopify_products.length,0)} Shopify products affected</div>
+<div class="warn">
+ <strong>NO Shopify writes have happened.</strong> This is a dry-run. Approve below to generate <code>push_phase${PHASE}.js</code>; review that before execution.
+</div>`;
+
+ for (const rec of records) {
+ html += `<h3>${rec.registry.dw_sku} · ${rec.registry.mfr_sku} · → <span class="sku">${rec.proposed_dwla_sku}</span></h3>`;
+ if (rec.shopify_products.length === 0) {
+ html += `<p style="color:#a44">No Shopify products matched.</p>`;
+ continue;
+ }
+ html += `<table><tr><th>Action</th><th>Shopify ID</th><th>Old → New handle</th><th>Old → New SKU</th><th>Title</th></tr>`;
+ for (const sp of rec.shopify_products) {
+ const cls = sp.action === 'archive_duplicate' ? 'action-archive' : 'action-canonical';
+ html += `<tr>
+<td class="${cls}">${sp.action}</td>
+<td>${sp.old_id}</td>
+<td><div class="old">${sp.old_handle}</div><div class="new">${sp.new_handle}</div></td>
+<td><div class="old">${sp.old_sku}</div><div class="new">${sp.new_sku}</div></td>
+<td><div class="old">${sp.old_title}</div><div class="new">${sp.new_title}</div></td>
+</tr>`;
+ }
+ html += `</table>`;
+ }
+ html += `<div class="ok"><strong>Next step:</strong> review the diffs above. If all looks correct, reply "GO phase 1" and I'll write <code>push_phase1.js</code> for your final approval before any Shopify call.</div></body></html>`;
+ fs.writeFileSync(outHtml, html);
+
+ console.log(`✓ phase ${PHASE} preview written`);
+ console.log(` ${outJson}`);
+ console.log(` ${outCsv}`);
+ console.log(` ${outHtml}`);
+ console.log(` ${records.length} registry rows · ${records.reduce((a,r)=>a+r.shopify_products.length,0)} Shopify products`);
+ console.log(` next DWLA seq: ${nextDwla}`);
+}
+
+main().catch(e => { console.error(e); process.exit(1); });
(oldest)
·
back to Dwla Rebrand
·
switch to option (b): handle derived from title pattern, not cb0bd27 →