← back to York Reprice 2026 08
cadence: dual image-drawer onboard lookup + naturals-aware drift (no false MAP re-break) + collision-aware 2-factor onboard
9ee51a3a58bc4d58a4e029aab490c5355de6605a · 2026-07-12 11:43:47 -0700 · Steve
Files touched
M cadence/york-cadence.mjs
Diff
commit 9ee51a3a58bc4d58a4e029aab490c5355de6605a
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jul 12 11:43:47 2026 -0700
cadence: dual image-drawer onboard lookup + naturals-aware drift (no false MAP re-break) + collision-aware 2-factor onboard
---
cadence/york-cadence.mjs | 45 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 9 deletions(-)
diff --git a/cadence/york-cadence.mjs b/cadence/york-cadence.mjs
index cd1704e..26bdc3d 100644
--- a/cadence/york-cadence.mjs
+++ b/cadence/york-cadence.mjs
@@ -21,37 +21,64 @@ const gql=async(query,v)=>{for(let a=0;a<8;a++){let j;try{const r=await fetch(UR
const norm=s=>String(s||'').toUpperCase().trim();
const words=s=>new Set(String(s||'').toLowerCase().replace(/[^a-z0-9 ]/g,' ').split(/\s+/).filter(w=>w.length>2));
const share=(a,b)=>{const A=words(a),B=words(b);for(const w of A)if(B.has(w))return true;return false;};
+const cents=x=>Math.round(Number(x)*100);
+const priceOff=(a,b)=>Math.abs(cents(a)-cents(b))>1; // "off" = more than a 1-cent rounding gap
// 1. master: mfr_sku -> {price,status,pattern,color}
const M=new Map();
for(const line of q(`select concat_ws(chr(31), upper(trim(export_sku)), coalesce(us_map,round(us_msrp*0.75,2)), sku_status, pattern_name, colorway) from york_master_aug2026 where export_sku is not null`).split('\n').filter(Boolean)){
const [s,p,st,pat,col]=line.split(String.fromCharCode(31)); if(!M.has(s)) M.set(s,{price:parseFloat(p),status:st,pattern:pat,color:col});
}
-// onboard-ready set from DB (master New, has york_catalog image, keyword-clear) — count only
-let onboardReady=0; try{ onboardReady=parseInt(q(`
- select count(*) from (select distinct on (upper(trim(export_sku))) upper(trim(export_sku)) s, pattern_name,product_name,book_name from york_master_aug2026 where sku_status='New' and export_sku is not null) n
- join york_catalog c on upper(trim(c.mfr_sku))=n.s
- where c.image_url is not null and c.image_url<>'' and lower(concat_ws(' ',n.pattern_name,n.product_name,n.book_name)) !~ 'banana|grape|bird|butterfly|palm|frond|leaf|foliage|botanical|floral|flower|tropical|jungle|vine|fern|bloom|garden|blossom'`)); }catch(e){}
+// naturals sell at a SINGLE-ROLL price (brewster_york_master.roll_price_single), NOT MAP — a second
+// valid price target. Without this the MAP-only drift check false-flags every correctly-priced
+// natural (grasscloth/sisal/paperweave/cork) as "drift" and would propose re-breaking it daily.
+const RPS=new Map();
+try{ for(const line of q(`select concat_ws(chr(31), upper(trim(mfr_sku)), roll_price_single) from brewster_york_master where roll_price_single is not null and roll_price_single>0`).split('\n').filter(Boolean)){
+ const [s,p]=line.split(String.fromCharCode(31)); if(!RPS.has(s)) RPS.set(s,parseFloat(p)); } }catch(e){}
+// onboard-ready CANDIDATES from DB (master 'New', settlement-keyword-clear, has a local image in
+// york_catalog OR brewster_catalog). york_catalog holds art for the archived York-branded line;
+// brewster_catalog holds it for the live Brewster/A-Street->Malibu line — every 'New' SKU is the
+// latter, so BOTH image drawers must be checked (checking only york_catalog is why this read 0).
+// 'Already live' is subtracted AFTER the live pagination below (liveMfr) so we never re-propose live SKUs.
+let onboardCand=[]; try{ onboardCand=q(`
+ select concat_ws(chr(31), n.s, n.pattern_name) from (select distinct on (upper(trim(export_sku))) upper(trim(export_sku)) s, pattern_name,product_name,book_name from york_master_aug2026 where sku_status='New' and export_sku is not null) n
+ left join york_catalog c on upper(trim(c.mfr_sku))=n.s
+ left join brewster_catalog b on upper(trim(b.mfr_sku))=n.s
+ where coalesce(nullif(c.image_url,''), nullif(b.image_url,'')) is not null
+ and lower(concat_ws(' ',n.pattern_name,n.product_name,n.book_name)) !~ 'banana|grape|bird|butterfly|palm|frond|leaf|foliage|botanical|floral|flower|tropical|jungle|vine|fern|bloom|garden|blossom'`)
+ .split('\n').map(x=>x.trim()).filter(Boolean)
+ .map(l=>{const [s,pat]=l.split(String.fromCharCode(31)); return {s,pat:pat||''};}); }catch(e){}
// 2. live Jeffrey Stevens
-let cur=null, reprice=[], disco=[], liveMfr=new Set();
+let cur=null, reprice=[], disco=[], liveMfr=new Set(), liveTitles=new Map();
for(let pg=0;pg<90;pg++){
const d=(await gql(`query($c:String){products(first:60,after:$c,query:"vendor:'Jeffrey Stevens'"){pageInfo{hasNextPage endCursor} nodes{status title dwc:metafield(namespace:"dwc",key:"manufacturer_sku"){value} cust:metafield(namespace:"custom",key:"manufacturer_sku"){value} variants(first:20){nodes{id sku price title}}}}}`,{c:cur}))?.products; if(!d)break;
for(const p of d.nodes){const mfr=norm(p.dwc?.value||p.cust?.value); if(!mfr)continue; liveMfr.add(mfr);
+ { const a=liveTitles.get(mfr)||[]; a.push(p.title||''); liveTitles.set(mfr,a); } // for collision-aware onboard 2-factor
const m=M.get(mfr); if(!m)continue;
const rolls=p.variants.nodes.filter(v=>!/sample|memo|-sample$/i.test((v.sku||'')+(v.title||''))); if(!rolls.length)continue;
const roll=rolls.reduce((a,b)=>parseFloat(b.price)>parseFloat(a.price)?b:a); const price=parseFloat(roll.price);
if(p.status==='ACTIVE'){
if(['Dead','Phasing'].includes(m.status)) disco.push({mfr,title:p.title,status:m.status});
- else if(['Active','New'].includes(m.status) && m.price>0 && Math.abs(price-m.price)>=0.01 && share(p.title,m.pattern))
- reprice.push({mfr,title:p.title,cur:price,map:m.price});
+ else if(['Active','New'].includes(m.status) && m.price>0 && share(p.title,m.pattern)){
+ const rps=RPS.get(mfr); // single-roll target (naturals)
+ const offMap=priceOff(price,m.price); // off from MAP
+ const offRps=rps?priceOff(price,rps):true; // off from single-roll (or none)
+ if(offMap && offRps) reprice.push({mfr,title:p.title,cur:price,map:m.price,rps:rps||null});
+ }
}
}
if(!d.pageInfo.hasNextPage)break; cur=d.pageInfo.endCursor;
}
+// collision-aware onboard-ready: a candidate is truly un-onboarded only if NO live product carrying its
+// code shares a title word with its master pattern. Bare code-match masks cross-brand collisions
+// (a New York code coinciding with an unrelated live Anna French/Thibaut SKU) as false 'already live'.
+const onboardObjs=onboardCand.filter(c=>{ const titles=liveTitles.get(c.s)||[]; return !titles.some(t=>share(t,c.pat)); });
+const onboardMfrs=onboardObjs.map(c=>c.s);
+const onboardReady=onboardMfrs.length;
const out={ts:new Date().toISOString(),live_js:liveMfr.size,
reprice_drift:reprice.length, onboard_ready:onboardReady, disco:disco.length,
- reprice_sample:reprice.slice(0,10), disco_sample:disco.slice(0,10)};
+ reprice_sample:reprice.slice(0,10), onboard_sample:onboardMfrs.slice(0,12), disco_sample:disco.slice(0,10)};
fs.mkdirSync(ROOT+'/cadence/data',{recursive:true});
fs.writeFileSync(ROOT+'/cadence/data/latest.json',JSON.stringify(out,null,2));
const actionable=reprice.length+onboardReady+disco.length;
← 40d2167 DTD-A grasscloth model: naturals-fix (revert 16 + relabel/re
·
back to York Reprice 2026 08
·
cadence: fix swallowed-SQL-error false-zero — onboard-ready 27f6dd0 →