← back to Dw Pairs Well
CLIP-3: hard link guarantee — every suggested SKU must be ACTIVE + online_store_published (all 5 suggestion queries + clipSimilarTop verified-row gate, 2x over-fetch); tools/live-link-check.sh audits suggested links against the live store
7fcb7a939d6f433d50ce3352e9dcb498f2e65e15 · 2026-07-13 00:52:49 -0700 · Steve Abrams
Files touched
M server.jsM tools/live-link-check.sh
Diff
commit 7fcb7a939d6f433d50ce3352e9dcb498f2e65e15
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 13 00:52:49 2026 -0700
CLIP-3: hard link guarantee — every suggested SKU must be ACTIVE + online_store_published (all 5 suggestion queries + clipSimilarTop verified-row gate, 2x over-fetch); tools/live-link-check.sh audits suggested links against the live store
---
server.js | 47 ++++++++++++++++++++++++++++++++---------------
tools/live-link-check.sh | 7 ++++++-
2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/server.js b/server.js
index d6e5867..9b32216 100644
--- a/server.js
+++ b/server.js
@@ -137,6 +137,7 @@ async function loadCandidates(source, limit = 600) {
FROM shopify_products AS sp
LEFT JOIN shopify_color_enrichment sce ON sce.shopify_id = sp.shopify_id
WHERE sp.status = 'ACTIVE'
+ AND sp.online_store_published IS TRUE
AND sp.image_url IS NOT NULL
AND sp.handle IS NOT NULL
AND sp.dw_sku IS NOT NULL
@@ -266,10 +267,15 @@ function paletteOverlap(sourcePalette, candPalette) {
// title, palette, vendor, handle). First row per dw_sku wins.
async function loadRowsByDwSkus(skus) {
if (!skus || !skus.length) return [];
+ // ACTIVE + Online-Store-published only: a CLIP result without a row here is NOT
+ // sellable/linkable on the live store and gets dropped by clipSimilarTop.
const q = `SELECT ${SOURCE_COLS}
FROM shopify_products sp
LEFT JOIN shopify_color_enrichment sce ON sce.shopify_id = sp.shopify_id
- WHERE sp.dw_sku = ANY($1)`;
+ WHERE sp.dw_sku = ANY($1)
+ AND sp.status = 'ACTIVE'
+ AND sp.online_store_published IS TRUE
+ AND sp.handle IS NOT NULL`;
const r = await pool.query(q, [skus]);
const seen = new Set(), out = [];
for (const row of r.rows) {
@@ -287,7 +293,9 @@ async function clipSimilarTop(source, k) {
if (!source.dw_sku) return null;
if (clipCircuitOpen()) return null; // service recently failed → skip, no latency hit
try {
- const body = { dw_sku: source.dw_sku, hex: source.dominant_hex || '', k };
+ // Over-fetch 2x: some results get dropped by the ACTIVE+published gate below,
+ // and the strip should still fill to k.
+ const body = { dw_sku: source.dw_sku, hex: source.dominant_hex || '', k: Math.min(k * 2, 50) };
const r = await fetch(`${VISUAL_SEARCH_URL}/similar`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -306,22 +314,29 @@ async function clipSimilarTop(source, k) {
const rowByS = new Map((await loadRowsByDwSkus(skus)).map(row => [row.dw_sku, row]));
const sourcePalette = paletteOf(source);
- return d.results.map(x => {
- const row = rowByS.get(x.dw_sku) || null;
- const candPalette = row ? paletteOf(row) : [];
+ // HARD LINK GUARANTEE: only products verified ACTIVE + Online-Store-published
+ // (loadRowsByDwSkus filters to exactly those) may be suggested — every /products/
+ // link the UI renders must resolve on the live store.
+ const out = [];
+ for (const x of d.results) {
+ if (out.length >= k) break;
+ const row = rowByS.get(x.dw_sku);
+ if (!row || !row.handle) continue;
+ const candPalette = paletteOf(row);
const overlap = paletteOverlap(sourcePalette, candPalette);
const why = [`Visual match (CLIP · cosine ${Number(x.score).toFixed(3)})`];
if (overlap.pickedUp.length) why.push(`Picks up: ${overlap.pickedUp.slice(0, 3).join(', ')}`);
- return {
+ out.push({
dw_sku: x.dw_sku,
- handle: x.handle || (row && row.handle) || null,
- title: (row && row.title) || x.pattern || x.dw_sku,
- vendor: x.vendor || (row && row.vendor) || null,
- image_url: x.image || (row && row.image_url) || null,
- pattern_name: x.pattern || (row && row.pattern_name) || null,
+ handle: row.handle,
+ title: row.title || x.pattern || x.dw_sku,
+ vendor: row.vendor || x.vendor || null,
+ image_url: row.image_url || x.image || null,
+ pattern_name: row.pattern_name || x.pattern || null,
_score: x.score, _palette: candPalette, _dE: overlap.avgDE, _why: why
- };
- });
+ });
+ }
+ return out.length ? out : null;
} catch (e) {
clipTrip(); // unreachable/slow → open the breaker
console.error('clipSimilarTop fallback →', e.message);
@@ -465,6 +480,7 @@ async function loadSimilarCandidates(source, limit = 1200) {
FROM shopify_products AS sp
LEFT JOIN shopify_color_enrichment sce ON sce.shopify_id = sp.shopify_id
WHERE sp.status = 'ACTIVE'
+ AND sp.online_store_published IS TRUE
AND sp.image_url IS NOT NULL
AND sp.handle IS NOT NULL
AND sp.dw_sku IS NOT NULL
@@ -747,7 +763,8 @@ app.get('/api/colorways', async (req, res) => {
sp.image_url, sp.metafields, sce.color_family, sce.dominant_hex, sce.background_hex
FROM shopify_products sp
LEFT JOIN shopify_color_enrichment sce ON sce.shopify_id = sp.shopify_id
- WHERE sp.status = 'ACTIVE' AND sp.title IS NOT NULL AND sp.handle IS NOT NULL
+ WHERE sp.status = 'ACTIVE' AND sp.online_store_published IS TRUE
+ AND sp.title IS NOT NULL AND sp.handle IS NOT NULL
AND sp.dw_sku IS NOT NULL
AND lower(regexp_replace(coalesce(sp.vendor,'∅'),'[^a-zA-Z0-9]+','-','g')) LIKE $1
`, [vendorSlug.replace(/[%_]/g, '\\$&') + '%']);
@@ -876,7 +893,7 @@ app.get('/api/collection-grouped', async (req, res) => {
const fam = familyKey(vendor) || familyKey(collHandle);
const params = [];
- let where = `sp.status = 'ACTIVE' AND sp.title IS NOT NULL AND sp.handle IS NOT NULL AND sp.dw_sku IS NOT NULL AND sp.image_url IS NOT NULL`;
+ let where = `sp.status = 'ACTIVE' AND sp.online_store_published IS TRUE AND sp.title IS NOT NULL AND sp.handle IS NOT NULL AND sp.dw_sku IS NOT NULL AND sp.image_url IS NOT NULL`;
if (fam && !all) {
params.push(fam + '%');
where += ` AND regexp_replace(lower(sp.vendor), '[^a-z0-9]', '', 'g') LIKE $${params.length}`;
diff --git a/tools/live-link-check.sh b/tools/live-link-check.sh
index 51f8623..7e15c6c 100644
--- a/tools/live-link-check.sh
+++ b/tools/live-link-check.sh
@@ -27,10 +27,15 @@ for p in d.get('pairs', d.get('similar', [])) or []:
if u: print(u)")
for U in $URLS; do
total=$((total+1))
- CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 -L "$STORE$U")
+ CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 -L -A 'Mozilla/5.0 (link-audit)' "$STORE$U")
+ if [ "$CODE" = "429" ]; then # store rate-limit, not a dead link — back off and retry once
+ sleep 12
+ CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 -L -A 'Mozilla/5.0 (link-audit)' "$STORE$U")
+ fi
if [ "$CODE" != "200" ]; then
bad=$((bad+1)); echo "FAIL $CODE $STORE$U (hero $SKU via ${EP%%\?*})"
fi
+ sleep 0.7 # stay under Shopify's throttle
done
done
done
← 79e1c62 auto-save: 2026-07-13T00:51:43 (1 files) — tools/live-link-c
·
back to Dw Pairs Well
·
audit: pipe-title backfill generator for malformed '| Vendor 263b80d →