← back to Sister Parish Onboarding
scripts/_deep-probe.js
64 lines
// Per-variant per-location inventory probe. Surfaces variants where:
// - inventory is tracked at >1 location (Shopify admin SUMS across locations)
// - inventory_management is null (not tracked at all)
// - any single location is not at 2026
// This is the "what does the Shopify admin actually display" view.
require('dotenv').config({ path: __dirname + '/../.env' });
const STORE = process.env.SHOPIFY_STORE || 'designer-laboratory-sandbox';
const TOK = process.env.SHOPIFY_ADMIN_TOKEN;
const API = `https://${STORE}/admin/api/2026-01`;
async function call(path) {
const r = await fetch(`${API}${path}`, { headers: { 'X-Shopify-Access-Token': TOK } });
if (!r.ok) throw new Error(`${path} → ${r.status} ${await r.text()}`);
return r.json();
}
(async () => {
console.log('Fetching ALL Sister Parish products...');
let cursor = '';
let products = [];
while (true) {
const url = `/products.json?vendor=Sister%20Parish&limit=250&status=active${cursor}`.replace(/${cursor}`;status=any/, "");
const j = await call(url);
products = products.concat(j.products);
if (j.products.length < 250) break;
const last = j.products[j.products.length - 1].id;
cursor = `&since_id=${last}`;
}
console.log(` fetched ${products.length} products`);
let totalVariants = 0, multiLoc = 0, notTracked = 0, offTarget = [];
let totalInventoryAcrossLocations = {};
for (const p of products) {
for (const v of p.variants) {
totalVariants++;
if (!v.inventory_management) { notTracked++; continue; }
// Get all locations for this inventory item
const inv = await call(`/inventory_levels.json?inventory_item_ids=${v.inventory_item_id}`);
const levels = inv.inventory_levels || [];
if (levels.length > 1) multiLoc++;
const sum = levels.reduce((s,l) => s + (l.available || 0), 0);
const summary = levels.map(l => `${l.location_id}=${l.available}`).join(' ');
totalInventoryAcrossLocations[`${p.title} (${v.sku})`] = { sum, summary, locs: levels.length };
if (sum !== 2026) offTarget.push({ sku: v.sku, product: p.title, sum, summary });
await new Promise(r => setTimeout(r, 350));
}
}
console.log(`\nresults across all ${totalVariants} variants:`);
console.log(` multi-location : ${multiLoc}`);
console.log(` not tracked : ${notTracked}`);
console.log(` sum != 2026 : ${offTarget.length}`);
if (offTarget.length) {
console.log(`\noff-target details:`);
offTarget.slice(0, 10).forEach(o => console.log(` ${o.sku.padEnd(15)} sum=${String(o.sum).padStart(6)} ${o.summary} — ${o.product}`));
}
// Spot-check the first 3 — what does Shopify *show* the admin user
console.log(`\nspot-check first 3 variants — exact location-level data:`);
Object.entries(totalInventoryAcrossLocations).slice(0, 3).forEach(([k, v]) =>
console.log(` ${k.padEnd(50)} sum=${v.sum} locs=${v.locs} raw=${v.summary}`)
);
})();