← back to Trending Dw
scripts/attach-real-images.js
44 lines
#!/usr/bin/env node
// attach-real-images.js — merge qc-passed real product images into bestsellers.json.
// Fingerprint-keyed (survives the TR-id churn scout-to-bestsellers.js causes on refresh).
// Writes ONLY the realImage* fields. `image`/`imageSource`/`imageDesign`/`isOurOriginal` are
// our-own-design fields consumed by the Shopify staging flow and are NEVER touched here —
// competitor marketplace images must never become stageable product images.
// Run AFTER attach-images.js in any refresh (documented in refresh.sh + README).
const fs = require('fs');
const path = require('path');
const { ASSETS, fingerprint, loadBest, saveBest, loadLedger } = require('./real-lib');
const WRITE = process.argv.includes('--write');
const data = loadBest();
const ledger = loadLedger();
let attached = 0, cleared = 0, missingFile = 0;
const byMarket = {};
for (const it of data.items){
const fp = fingerprint(it);
const l = ledger[fp];
const mk = it.marketplace || '?';
byMarket[mk] = byMarket[mk] || { total: 0, real: 0 };
byMarket[mk].total++;
if (l && l.status === 'qc-pass' && l.file && fs.existsSync(path.join(ASSETS, l.file))){
it.realImage = '/assets/real/' + l.file;
it.realImageSource = mk + (l.sourceUrl ? ' — ' + new URL(l.sourceUrl).hostname.replace(/^www\./, '') : '');
it.realImageUrl = l.sourceUrl || null;
it.realImageFetchedAt = l.downloadedAt || l.updatedAt || null;
attached++; byMarket[mk].real++;
} else {
if (l && l.status === 'qc-pass') missingFile++;
if (it.realImage){ delete it.realImage; delete it.realImageSource; delete it.realImageUrl; delete it.realImageFetchedAt; cleared++; }
}
}
data.realImagesAttachedAt = new Date().toISOString();
console.log(`real images attached: ${attached} of ${data.items.length}${cleared ? ` (cleared ${cleared} stale)` : ''}${missingFile ? ` (${missingFile} qc-pass but file MISSING on disk!)` : ''}`);
console.log('coverage by marketplace:');
for (const [mk, s] of Object.entries(byMarket)) console.log(` ${mk.padEnd(20)} ${s.real}/${s.total}`);
if (WRITE){ saveBest(data); console.log('bestsellers.json updated (realImage* fields only).'); }
else console.log('(dry-run — pass --write to persist)');