← back to Designer Wallcoverings
pending-approval/done/tres-tintas-designer-descriptions-pilot.DONE.md
84 lines
# PENDING APPROVAL — Tres Tintas pilot: interior-designer descriptions + spec-metafield backfill (~554 products)
**Drafted:** 2026-06-23 · **Status:** ⏳ AWAITING STEVE — vp-dw-commerce SIGNED OFF (smoke-test-3-first path); Defect A closed.
**Owner officer:** vp-dw-commerce (DW catalog / Shopify / customer-facing)
**Officer sign-off (2026-06-23):** vp-dw-commerce reviewed memo + executor + live snippet (both mirrors). Verdict: SIGN OFF with smoke-test-3 first. Confirmed: banned-word guard, metafield-FIRST ordering, additive/skip-if-present writes, idempotent ledger + per-product backups, correct LIVE store, every written metafield key is read by the `dw-specs` snippet. **Defect A (Material was writing legacy `global.Contents`, read only via fallback tail) — CLOSED:** `SPEC_MAP` retargeted to the snippet's canonical `custom.*` keys (Material→`custom.material`, Repeat→`custom.pattern_repeat`, Care→`custom.care`, Origin→`custom.origin`; Width/Weight/Fire already canonical). Re-dry-ran clean. Residual low-risk notes for a post-run audit: products doubling via a non-`<h3>` wrapper aren't caught (the 554 is a floor); no-image products are skipped (need separate image backfill); `Type=Mural` not metafield-backfilled (snippet has no Type row anyway); API version `2024-01` vs house `2024-10` (cosmetic).
**Gate reason:** Customer-facing LIVE Shopify writes — rewrites `body_html` description + sets product metafields on ~554 live products on the production store (`designer-laboratory-sandbox.myshopify.com`).
## What this is
Tres Tintas products carry the vendor spec table baked into the `body_html`
description, while the theme separately renders a metafield-driven `dw-specs`
block — so **specs display twice** on every PDP (the "doubling" regression).
Audit: **554 of 592** Tres Tintas products are affected.
This pilot fixes all of them with the recipe **proven live on DWTB-11032**
(Giant Abstract M4905-1, 2026-06-23 — verified single clean specs table + new
designer-voice description, no doubling). Per product:
1. **Gemini image analysis** (`gemini-3.5-flash`) → precise trade colorways +
style + motif. Never invents a hue (DW image rule). Replaces the deprecated
`gemini-3.5-flash` (now 404).
2. **Backfill EVERY embedded-table spec → its `dw-specs` metafield** so stripping
the table loses nothing: Width→`custom.width`, Material→`global.Contents`,
Repeat→`global.repeat`, Weight→`custom.product_weight`, Fire→`custom.fire_rating`,
Care→`global.Cleaning`, Origin→`global.Country`. Pattern ref.→`pattern-ref-<sku>` tag.
3. **Replace the description** with interior-designer-voice prose (3 paragraphs,
real colorways, accurate specs, banned-word-guarded) — which removes the
embedded table, killing the doubling.
## Why metafield-FIRST (Steve's explicit rule)
A dry run caught that most Tres Tintas products have a *slimmer* table than the
hand-fixed one (Material/Type/Pattern ref./Origin — no Width/Weight/Care). The
executor backfills **whatever each product's table holds** before the rewrite,
so no spec is ever dropped from the page. (Verified per-product in dry run.)
## Proven on (DONE, live, safe to view)
- **DWTB-11032** — https://www.designerwallcoverings.com/products/giant-abstract-m4905-1-wallcovering-tres-tintas
- 0 embedded tables, 1 `dw-specs` block, all 8 spec rows render, new
Indigo/Terracotta/Cobalt/Alabaster designer description live.
## Dry-run sample (READ-ONLY, no writes — distinct real colorways per product)
- `Graffiti Stone` → Alabaster / Greige / Ochre / Celadon · Abstract Patchwork
- `Graffiti Park` → Sage / Celadon / Parchment / Chartreuse · Abstract
- `Graffiti Sky` → Indigo / Ochre / Alabaster / Slate · Patchwork
## Safety / reversibility
- **Idempotent** — skips products already done (ledger) and any whose body_html
no longer has the table. Re-runnable.
- **Backs up every original** `body_html` → `shopify/tres-tintas-desc-backups/<id>.body_html.bak`.
- Metafield sets are **additive** (skip-if-present); never deletes/overwrites.
- Honors banned-word rule (Wallcovering, never Wallpaper) — generated copy is
guarded; throws + skips on violation.
- Read-rate: ~110–200ms spacing between writes (well under Standard bucket).
## Cost
- **~$0.55** total Gemini (554 × ~$0.001 `gemini-3.5-flash` image call).
- Shopify writes: **$0** (unmetered Admin API). Local parsing/prose: **$0 (local)**.
## EXACT ready-to-run commands
```bash
cd ~/Projects/Designer-Wallcoverings/shopify/scripts
# 1) Smoke test — 3 live products, eyeball the result first:
LIMIT=3 APPLY=1 node tres-tintas-designer-descriptions.js
# 2) Full Tres Tintas run (idempotent; resumes via ledger if interrupted):
APPLY=1 node tres-tintas-designer-descriptions.js
```
Dry run (no writes, default): `node tres-tintas-designer-descriptions.js`
## Related (separate, NOT in this memo)
- **Snippet hardening** (`theme-5.0-duplicate/snippets/product-description-meta.liquid`)
— 3 case-fallbacks (`weight`/`cleaning`/`country`) so lowercase metafields render
fleet-wide. Theme change → stage on dev theme → Steve pushes live.
- **Gemini-2.0 deprecation sweep** — `gemini-3.5-flash` is 404 across the codebase;
worth a separate sweep to `gemini-3.5-flash`.
- **Wider rollout** — same recipe generalizes to the whole catalog once this pilot
is reviewed (~145K ≈ $87 Gemini), ramped at the daily cap.
## Verdict needed from Steve
☐ Approve smoke test (3) → review → approve full 554
☐ Approve full 554 directly
☐ Hold