← back to Mdc Onboard

README.md

76 lines

# mdc-onboard — MDC → Phillipe Romano (Type II) DRAFT onboard

Private-label onboard of the MDC WALLCOVERINGS Type II contract-vinyl line into the
LIVE DW Shopify store (`designer-laboratory-sandbox.myshopify.com`) as **DRAFTS**,
branded **Phillipe Romano** (world-capital collections). Source of truth =
`dw_unified.mdc_catalog` (4,728 deduped-by-mfr_sku rows). Modeled on
`vahallan-onboard` (quote-only) + `knoll-onboard` (private-label metafields) +
the CMO Paris onboard→activate pattern.

## HARD RULE — private label
`MDC` / `MDC Interior Solutions` / `mdcwall.com` and the real book & designer names
(Bolta, Vycon, Genon, Lentex, Nvolve, Candice Olson, Thom Filicia, Jonathan Mark,
Taniya Nayak) are **NEVER customer-facing**. The only real datum pushed to Shopify is
the opaque mfr SKU code, in hidden `custom.manufacturer_sku` + `dwc.manufacturer_sku`.
Full real-identity reconciliation lives in `dw_unified.mdc_catalog`.

## What `import-drafts.py` creates (per product)
- **status = draft** (activation is a separate gated step — see below)
- title = `mdc_catalog.dw_title` (title-cased `"… | Phillipe Romano"`; re-guarded: no `Wallpaper`/`Unknown`)
- vendor `Phillipe Romano` · type `Wallcovering`
- **Sample variant** `{DW_SKU}-Sample` @ **$4.25**, `inventory_management=null` (no inventory)
- **quote-only** → tags `quotes` + `contact-for-price` (no sellable/priced variant)
- metafields: `custom.manufacturer_sku`, `dwc.manufacturer_sku` (= mfr_sku), `global.Brand`,
  `global.width` (when known), `global.unit_of_measure`, `custom.color`/`real_color_name`
- ≥1 image (`image_url`); body_html = spec table built from the catalog spec columns

**BUDGET_CAT=backlog** — standalone importer; does NOT touch the shared upload/variant
budget (`budget.cjs`) and does NOT auto-activate. Drafts land as backlog for later
drip-activation under the activation-lane cap.

**PostgreSQL-first write-back** — `shopify_product_id` + `on_shopify=true` are written
back to `mdc_catalog` the instant each product is created → fully resumable, never
double-creates.

## Run
```sh
python3 import-drafts.py                 # DRY-RUN (prints 3 payloads)
python3 import-drafts.py --limit 3 --commit   # test batch
python3 import-drafts.py --commit             # full remaining (~43 min, $0 local)
node ../vahallan-onboard/gate-check.js <PID>  # prove a draft would pass activation
```
Cost: **$0 (local)** — unmetered Shopify Admin API + local PG parse. No browser/AI.

## Verified (test batch, 2026-07-26)
3 drafts created; PG write-back confirmed; created object has correct draft status,
`{DW}-Sample`@4.25 null-inventory, 1 image, custom+dwc manufacturer_sku + global.width
metafields; `gate-check.js` → **canonical PASS + fiveFieldExtra PASS → WOULD ACTIVATE: true**.

## Known flag for the activation gate (48 rows)
The `Dublin` collection (MDC book `vital-vycon`) has mfr pattern name **"Vital"**, so those
48 titles read `"Dublin Vital … | Phillipe Romano"`. "Vital" is a generic English adjective
(the distinctive mark "Vycon" never appears) so they were **not** blocked — but a human should
confirm "Vital" is acceptable customer-facing **before these 48 go ACTIVE**. See
`out/flagged-dublin-vital.jsonl`.

## Activation (2026-07-26)
The scheduled FLEET activator (`com.steve.dw-rotation-activator`, cap 500/day) already
drip-activates these MDC drafts — gate-passed + **ex-Google** (it excludes the Google
publication). Steve's call (2026-07-26): **"let it ride + protect Vital."**

- Dedicated activator built: `~/Projects/dw-rotation-activator/mdc-activate.js` (scoped to
  the exact `mdc_catalog` PID set; adds an MDC-coinage leak guard + Dublin-Vital hold on
  top of the settlement + 5-field gates; publishes ex-Google). DRY sample: 17/20 pass,
  settlement ≈ $0.0001/product (~$0.47 full).
- **48 "Dublin Vital" rows — RESOLVED (2026-07-26):** Steve ruled "do not use Vital." Renamed
  pattern `Dublin Vital` → `Dublin` across PG + Shopify (title/body/tags), dropped the hold
  tag + `internal.settlement_hold`, and un-archived to DRAFT so they rejoin the ex-Google
  drip like the rest. Zero "Vital" residual anywhere. (The `mdc-activate.js` vital-hold guard
  is now inert since no row matches `pattern ~* 'vital'` — left in as a harmless safety net.)

## To reach LIVE (Steve-gated — NOT done here)
Drafts only. Activation DRAFT→ACTIVE runs a CMO-Paris-style `mdc-activate.js`: real
settlement gate + 5-field gate + publish to all channels **ex-Google** (quote-only lines
stay off Google Shopping). The `mdc-wallcoverings` Shopify collection is populated at that
activation step, not here.