← back to Newmor Onboard
artifacts/METAFIELD-MAP.md
50 lines
# Newmor → Shopify spec→METAFIELD mapping (TK-10670)
HARD RULE (Steve, 2026-08-18): **all spec/metafield info goes into Shopify METAFIELDS, never body_html.**
`body_html` stays clean marketing prose only. This map is the enforcement contract for the
(gated) publish/backfill.
Source: `newmor_catalog` columns → Shopify metafield. Namespace defaults to `custom.*`;
FINAL namespace/keys must be reconciled against the existing DW live metafield schema
(verify from a live Newmor/commercial product in cycle 2 before any write) so we don't fork keys.
| catalog column | Shopify target | metafield type | notes |
|-----------------------|-----------------------------------|-------------------------|-------|
| width / width_inches | `custom.width` | dimension | coverage 787/1294 — gap |
| length | `custom.roll_length` | dimension | coverage 1045/1294 |
| coverage | `custom.coverage` | single_line_text_field | EMPTY (0) — needs refresh |
| repeat_v | `custom.pattern_repeat_vertical` | dimension | EMPTY (0) — needs refresh |
| repeat_h | `custom.pattern_repeat_horizontal`| dimension | EMPTY (0) — needs refresh |
| match_type | `custom.pattern_match` | single_line_text_field | EMPTY (0) — needs refresh |
| material | `custom.material` | single_line_text_field | coverage 617/1294 |
| finish | `custom.finish` | single_line_text_field | EMPTY (0) — needs refresh |
| fire_rating | `custom.fire_rating` | single_line_text_field | EMPTY (0) — commercial line, IMPORTANT |
| application | `custom.application` | single_line_text_field | EMPTY (0) — needs refresh |
| features | `custom.features` | list.single_line_text | |
| color_primary | `custom.color_primary` | single_line_text_field | |
| color_secondary | `custom.color_secondary` | single_line_text_field | |
| color_hex / dominant_color_hex | `custom.color_hex` | color | |
| us_distributor | `custom.us_distributor` | single_line_text_field | = "LBI Boyd" (Steve-confirmed) |
| product_type | Shopify **product_type** (native) | — | NOT a metafield |
| collection | Shopify **tag/collection** | — | NOT a metafield |
| product_url | `custom.vendor_url` | url | |
## ⚠️ NEVER-OVERWRITE-RICHER-LIVE rule (Cody-caught, verified cycle 1)
The 512/544 live products ALREADY carry richer metafields than the 2026 catalog:
`custom.manufacturer_sku` (512), `custom.fire_rating`="Inquire for more Information" (512),
`custom.width` (118), `custom.pattern_name` (541). The catalog's fire_rating/finish/etc are BLANK.
⇒ The backfill MUST be **fill-only, never clobber**: write a metafield from the catalog ONLY when
the live value is empty AND the catalog value is non-empty. Writing catalog blanks over live values
is a REGRESSION. Coverage numbers below describe the CATALOG source, not what to force onto live.
## body_html policy
- KEEP: marketing prose (pattern story, designer, base options). Current bodies are clean
(only 46/1284 mention a spec token) — light cleanup, not systemic.
- STRIP from body if present: width/repeat/fire-rating/match/coverage → move to the metafields above.
## Data-gap flag (feeds refresh branch)
repeat_v/repeat_h, finish, fire_rating, application, match_type, coverage are ALL empty in
`newmor_catalog`. For a **commercial** line, fire_rating + application + match are material specs.
→ the catalog REFRESH (via Norman/newmor-agent, currently DOWN) must recapture these before
the metafield backfill is meaningful.