← back to Tk10630 Sku Suffix Canary
leak-assess-all.mjs
33 lines
// Full-surface private-label leak assessment across ALL denylist terms. READ-ONLY.
// Per term: active-product counts in handle / title / tag (via reliable search-count),
// plus a sampled image-alt check on the biggest handle-leaker. No pagination (search only).
import { readFileSync } from 'node:fs';
import { gql } from './shopify.mjs';
const denylist = JSON.parse(readFileSync(`${process.env.HOME}/.claude/skills/dw-leak-scanner/denylist.json`, 'utf8'));
// distinctive single search token per term; skip 'york'/'yorkwall' (too noisy — New York etc., per-SKU nuance)
const NOISY = new Set(['york', 'yorkwall']);
const terms = [...new Set(denylist.terms.map(t => t.term.toLowerCase().split(/\s+/)[0]).filter(t => t.length >= 4 && !NOISY.has(t)))];
const mapsTo = Object.fromEntries(denylist.terms.map(t => [t.term.toLowerCase().split(/\s+/)[0], t.maps_to]));
const count = async q => (await gql(`query{ productsCount(query:"${q}"){ count } }`)).data.productsCount.count;
const rows = [];
for (const term of terms) {
const h = await count(`handle:*${term}* status:ACTIVE`);
const t = await count(`title:*${term}* status:ACTIVE`);
const g = await count(`tag:*${term}* status:ACTIVE`);
let alt = null;
if (h > 0) {
const d = await gql(`query{ products(first:20, query:"handle:*${term}* status:ACTIVE"){ nodes{ images(first:2){ nodes{ altText } } } } }`);
const re = new RegExp(term, 'i');
const n = d.data.products.nodes.filter(p => p.images.nodes.some(i => re.test(i.altText || ''))).length;
alt = `${n}/20`;
}
if (h || t || g) rows.push({ term, maps_to: mapsTo[term], handle: h, title: t, tag: g, alt_sample: alt });
}
rows.sort((a, b) => (b.handle + b.title + b.tag) - (a.handle + a.title + a.tag));
console.log(JSON.stringify({ terms_checked: terms.length, leaking_terms: rows.length, rows }, null, 2));
const totalActiveHandle = rows.reduce((a, r) => a + r.handle, 0);
console.log(`\nTOTAL active handle leaks across all terms: ${totalActiveHandle}`);
console.log('NOTE: york/yorkwall skipped (noisy, per-SKU nuance — needs manual).');