← back to New Import Viewer

phase8-fix/phase8-create-publish.patch

105 lines

# Phase 8 REAL create+publish fix for full-monte
# Target: /root/DW-Agents/full-monte/full-monte-batch.js (Kamatera)
# Companion module: scp shopify-push.js → /root/DW-Agents/full-monte/shopify-push.js
#
# WHAT THIS FIXES
# Phase 8 today runs ONLY sub-phase 8a (metafield migration on EXISTING products)
# then stamps phase8_shopify_at=NOW() as if it pushed — it creates ZERO products.
# This adds sub-phase 8b: a real create+publish step that reuses the canonical,
# publish-gap-fixed pattern (publishablePublish → Online Store) from Mac2
# new-import-viewer/consumer.js (commit 96cd954).
#
# SAFETY
#  • Default DRAFT (no publish). Real ACTIVE+publish requires BOTH
#    PHASE8_PUSH_LIVE=1 (env ceiling) AND --allow-active (the Steve gate).
#  • Same THREE-SOURCE NEVER-DUPLICATE + image + sample-variant gates as consumer.js.
#  • token comes from full-monte/.env (already chmod-600 there); the cron line must
#    source it (it already does for 8a's token use).
#
# ── PATCH 1 of 4: load .env + require the push module (top of file, after `const tracking...`) ──
# FIND (line ~16):
const tracking = require('./tracking');
# REPLACE WITH:
const tracking = require('./tracking');
require('dotenv').config({ path: require('path').join(__dirname, '.env') }); // load SHOPIFY_ADMIN_TOKEN
const { pushVendor } = require('./shopify-push');                            // Phase 8b real push

# ── PATCH 2 of 4: add the --allow-active flag (in the arg switch, next to --full-monte ~line 149) ──
# FIND:
      case '--full-monte':
        opts.fullMonte = true;
        break;
# REPLACE WITH:
      case '--full-monte':
        opts.fullMonte = true;
        break;
      case '--allow-active':
        opts.allowActive = true;   // Phase 8b: create ACTIVE + publish (else DRAFT)
        break;

# ── PATCH 3 of 4: thread allowActive into runPhase (find the runPhase signature ~line 547) ──
# FIND:
async function runPhase(vendorCode, catalogTable, phase, limit) {
# REPLACE WITH:
async function runPhase(vendorCode, catalogTable, phase, limit, allowActive = false) {
#
# AND update the two call sites that invoke runPhase to pass opts.allowActive:
#   • in runFullMonte's loop:   await runPhase(vendorCode, catalogTable, phase, limit, allowActive)
#   • in the single-phase path: await runPhase(opts.vendor..., opts.phase, opts.limit, opts.allowActive)
# (grep -n 'runPhase(' full-monte-batch.js to find both; add the trailing arg.)

# ── PATCH 4 of 4: add sub-phase 8b inside `case 8:` (after the 8a try/catch, BEFORE the tracking UPDATE) ──
# FIND (the tracking update that currently ends case 8, ~line 697):
      // Update tracking
      await tracking.pool.query(`
        UPDATE enrichment_tracking
        SET phase8_shopify_at = NOW()
        WHERE vendor_code = $1 AND phase8_shopify_at IS NULL
      `, [vendorCode]);

      break;
    }
# REPLACE WITH:
      // Sub-phase 8b: REAL create + publish (the actual Shopify push).
      // DRAFT unless BOTH PHASE8_PUSH_LIVE=1 and --allow-active are present.
      const PUSH_LIVE = process.env.PHASE8_PUSH_LIVE === '1';
      if (PUSH_LIVE) {
        try {
          const token = process.env.SHOPIFY_ADMIN_TOKEN;
          const store = process.env.SHOPIFY_STORE || 'designer-laboratory-sandbox.myshopify.com';
          console.log(`  Phase 8b: create+publish for ${vendorCode} (allowActive=${!!allowActive})`);
          const res = await pushVendor(vendorCode, {
            pool: tracking.pool, token, store,
            limit: limit || 400, allowActive: !!allowActive, log: (m) => { console.log(m); log(m); },
          });
          log(`Phase 8b push ${vendorCode}: created ${res.created}, skipped ${res.skipped}, failed ${res.failed}`);
        } catch (err) {
          console.error(`  Phase 8b push error: ${err.message}`);
          log(`Phase 8b error: ${err.message}`);
        }
      } else {
        console.log(`  Phase 8b skipped (PHASE8_PUSH_LIVE != 1) — metafield-only run`);
      }

      // Update tracking (only after the push ran, real or skipped)
      await tracking.pool.query(`
        UPDATE enrichment_tracking
        SET phase8_shopify_at = NOW()
        WHERE vendor_code = $1 AND phase8_shopify_at IS NULL
      `, [vendorCode]);

      break;
    }

# ── INSTALL ──
# 1. scp shopify-push.js → /root/DW-Agents/full-monte/shopify-push.js
# 2. apply patches 1-4 above to /root/DW-Agents/full-monte/full-monte-batch.js
# 3. ensure dotenv is installed there:  (cd /root/DW-Agents/full-monte && npm ls dotenv || npm i dotenv)
# 4. add SHOPIFY_STORE=designer-laboratory-sandbox.myshopify.com to full-monte/.env (optional; default is hardcoded)
# 5. dry test (DRAFT, no publish):
#      cd /root/DW-Agents/full-monte && PHASE8_PUSH_LIVE=1 node full-monte-batch.js --vendor marburg --phase 8 --limit 5
#      (creates 5 DRAFTS — verify in Shopify admin, then archive the test 5)
# 6. live (Steve-gated): add --allow-active and keep --limit small until the daily
#    variant window is confirmed clear:
#      PHASE8_PUSH_LIVE=1 node full-monte-batch.js --vendor marburg --phase 8 --allow-active --limit 42