[object Object]

← back to Gmc Titlefix

step-2: full-feed verifier + wait-for-scaleout-then-verify wrapper

78f9b569f832fe8feef7c0290e913800e53571e9 · 2026-06-18 16:20:52 -0700 · SteveStudio2

Files touched

Diff

commit 78f9b569f832fe8feef7c0290e913800e53571e9
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Thu Jun 18 16:20:52 2026 -0700

    step-2: full-feed verifier + wait-for-scaleout-then-verify wrapper
---
 step-e-verify-all.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 wait-and-verify.sh   | 17 +++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/step-e-verify-all.js b/step-e-verify-all.js
new file mode 100644
index 0000000..c7b2488
--- /dev/null
+++ b/step-e-verify-all.js
@@ -0,0 +1,49 @@
+// STEP 2 — READ-ONLY full verify. Pages the entire live Content feed once, then
+// confirms each of the 29,672 risky offers now has an effective title starting "Sample:".
+// Writes /tmp/gmc-verify-result.json + a human summary. Safe to re-run anytime.
+const {token,MERCHANT}=require('./_auth');
+const fs=require('fs');
+const list=require('./gmc_titlefix_list.json');
+const risky=new Map(list.map(r=>[r.offerId,r])); // offerId -> row
+const vendorOf=row=>{ const t=row.currentTitle||''; const m=t.match(/(?:by|\|)\s*([^|]+?)\s*$/); return (m&&m[1].trim())||'(unknown)'; };
+
+(async()=>{
+  let tok=await token(), tokAt=Date.now();
+  const title=new Map();              // offerId -> effective title (only for risky offers)
+  let page=0, pageToken=undefined, scanned=0;
+  do{
+    if(Date.now()-tokAt>50*60*1000){ tok=await token(); tokAt=Date.now(); }
+    const u=new URL(`https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT}/products`);
+    u.searchParams.set('maxResults','250'); if(pageToken) u.searchParams.set('pageToken',pageToken);
+    let r,j,tries=0;
+    do{ r=await fetch(u,{headers:{Authorization:'Bearer '+tok}}); j=await r.json();
+        if(r.status>=500){ tries++; await new Promise(s=>setTimeout(s,2000)); } else break; }while(tries<4);
+    if(!r.ok){ console.error('feed page',page,'HTTP',r.status,JSON.stringify(j).slice(0,200)); break; }
+    for(const p of (j.resources||[])){ scanned++; if(risky.has(p.offerId)) title.set(p.offerId, p.title||''); }
+    pageToken=j.nextPageToken; page++;
+    if(page%25===0) console.log(`  paged ${page} | scanned ${scanned} | matched ${title.size}/${risky.size}`);
+  }while(pageToken);
+
+  let flipped=0, notyet=0, missing=0;
+  const notFlipped=[], byVendorNot={};
+  for(const [offerId,row] of risky){
+    if(!title.has(offerId)){ missing++; continue; }
+    if(/^Sample:/.test(title.get(offerId))) flipped++;
+    else { notyet++; const v=vendorOf(row); byVendorNot[v]=(byVendorNot[v]||0)+1;
+           if(notFlipped.length<25) notFlipped.push({offerId, title:title.get(offerId).slice(0,80)}); }
+  }
+  const result={ ts:new Date().toISOString(), totalRisky:risky.size, feedOffersScanned:scanned,
+    flipped, notyet, missingFromFeed:missing,
+    flipRatePct:+(100*flipped/risky.size).toFixed(2),
+    byVendorNotFlipped:Object.fromEntries(Object.entries(byVendorNot).sort((a,b)=>b[1]-a[1]).slice(0,15)),
+    sampleNotFlipped:notFlipped };
+  fs.writeFileSync('/tmp/gmc-verify-result.json', JSON.stringify(result,null,2));
+  console.log('\n===== STEP-2 VERIFY =====');
+  console.log(`flipped:  ${flipped}/${risky.size}  (${result.flipRatePct}%)`);
+  console.log(`not yet:  ${notyet}`);
+  console.log(`missing from feed (deleted/archived since list built): ${missing}`);
+  if(notyet){ console.log('top vendors still unflipped:', JSON.stringify(result.byVendorNotFlipped)); }
+  const verdict = (flipped===risky.size) ? 'PASS' : (flipped+missing===risky.size) ? 'PASS* (all live offers flipped; rest gone from feed)' : 'PARTIAL';
+  console.log('VERDICT:', verdict);
+  fs.writeFileSync('/tmp/gmc-verify-verdict.txt', verdict);
+})().catch(e=>{ console.error('ERR',e.message); process.exit(1); });
diff --git a/wait-and-verify.sh b/wait-and-verify.sh
new file mode 100755
index 0000000..472f643
--- /dev/null
+++ b/wait-and-verify.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# STEP 2 wrapper — wait for the running step-d scale-out (PID arg) to exit,
+# allow Google reprocessing time, then run the full-feed verifier.
+set -u
+cd "$HOME/Projects/gmc-titlefix" || exit 1
+PID="${1:-2358}"
+BUFFER="${BUFFER:-900}"   # seconds to wait after step-d exits for Google to reprocess
+LOG=/tmp/gmc-verify.log
+exec >>"$LOG" 2>&1
+echo "[$(date)] wait-and-verify: watching step-d PID $PID, reprocessing buffer ${BUFFER}s"
+while kill -0 "$PID" 2>/dev/null; do sleep 60; done
+echo "[$(date)] step-d PID $PID has exited. last scale log:"; tail -3 /tmp/gmc-stepd-full.log
+echo "[$(date)] sleeping ${BUFFER}s for Google to reprocess supplemental overrides..."
+sleep "$BUFFER"
+echo "[$(date)] running step-e-verify-all.js ..."
+node step-e-verify-all.js
+echo "[$(date)] verify done. verdict: $(cat /tmp/gmc-verify-verdict.txt 2>/dev/null) — result: /tmp/gmc-verify-result.json"

← 278654a spotcheck: verify 500-batch title flips landed on Google (8/  ·  back to Gmc Titlefix  ·  step-e: DTD-B verify-and-retry — page processed feed, re-pus 85cc622 →