[object Object]

← back to Sample Followup Sweep

yoloforever c3 (Cody): console honors no-chase (badge+grey Spoonflower), flags garbage mfr rows (*** ENTER MFR #), build-fleet SCHUMACHER->SCH vid merge

adaac2ffd7af6d3439dd42497813c597f304be89 · 2026-08-15 09:02:59 -0700 · Steve Abrams

Files touched

Diff

commit adaac2ffd7af6d3439dd42497813c597f304be89
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Aug 15 09:02:59 2026 -0700

    yoloforever c3 (Cody): console honors no-chase (badge+grey Spoonflower), flags garbage mfr rows (*** ENTER MFR #), build-fleet SCHUMACHER->SCH vid merge
---
 scripts/build-fleet.js |  4 +++-
 server.js              | 11 +++++++----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/scripts/build-fleet.js b/scripts/build-fleet.js
index 9b8e71b..4a36182 100644
--- a/scripts/build-fleet.js
+++ b/scripts/build-fleet.js
@@ -27,7 +27,9 @@ for (const r of j.records) {
   const d = r.fieldData;
   const rawvid = (d.vid || '').trim();
   if (!rawvid) { skippedNoVid++; continue; }
-  const vid = rawvid.toUpperCase();
+  // Merge duplicate vids for the same vendor (e.g. SCHUMACHER + SCH → one Schumacher row).
+  const VID_ALIAS = { SCHUMACHER: 'SCH' };
+  const vid = VID_ALIAS[rawvid.toUpperCase()] || rawvid.toUpperCase();
   const dt = d['today for client'];
   const age = dt ? Math.floor((today - new Date(dt)) / 86400000) : null;
   if (age === null || age <= 10 || age > 60) { skippedWindow++; continue; }
diff --git a/server.js b/server.js
index 3f41690..beeb36d 100644
--- a/server.js
+++ b/server.js
@@ -240,7 +240,9 @@ function sorted(){const k=document.getElementById('sort').value;localStorage.set
 function itemsTable(v){
  let h='<table class=detail><thead><tr><th>Pattern (Mfr#)</th><th>DW#</th><th>Client</th><th>Initial request</th><th>Re-req</th></tr></thead><tbody>';
  for(const i of v.items){
-   h+='<tr'+(i.reRequested?' class=rr':'')+'><td>'+esc(i.mfr)+'</td><td class=vid>'+esc(i.dw||'-')+'</td><td>'+esc(i.client||'')+'</td>'+
+   const badMfr=!i.mfr||/\*\*\*|enter mfr/i.test(i.mfr);
+   const mfrCell=badMfr?'<span class="badge need" title="FileMaker data-entry error — no real mfr number">⚠ needs mfr#</span>':esc(i.mfr);
+   h+='<tr'+(i.reRequested?' class=rr':'')+'><td>'+mfrCell+'</td><td class=vid>'+esc(i.dw||'-')+'</td><td>'+esc(i.client||'')+'</td>'+
       '<td>'+esc(i.initialReq||i.req||'-')+'</td>'+
       '<td>'+(i.reRequested?'<span class="badge rrb">RE-REQ ×'+i.timesRequested+'</span>':'')+'</td></tr>';
  }
@@ -250,13 +252,14 @@ function sentCell(v){const s=sentInfo(v);
  if(!s.sent)return '<span class=muted>— not sent</span>';
  return '<span class="badge sentb">SENT</span> <span class=dt title="'+esc(s.lastSent)+'">'+esc(fmtSent(s.lastSent))+'</span>'+(s.count>1?'<span class=sentx>×'+s.count+'</span>':'');}
 function render(){const t=document.getElementById('rows');t.innerHTML='';for(const v of sorted()){const c=S.contacts[v.slug]||{};const r=ready(v);
- const tr=document.createElement('tr');tr.innerHTML=
- '<td><input type=checkbox class=pick data-slug="'+v.slug+'"></td>'+
+ const noChase=c.disposition==='no-chase';
+ const tr=document.createElement('tr');if(noChase)tr.style.opacity='.5';tr.innerHTML=
+ '<td><input type=checkbox class=pick data-slug="'+v.slug+'"'+(noChase?' disabled':'')+'></td>'+
  '<td><b>'+esc(v.name)+'</b><div class=vid>'+esc(v.vid)+'</div></td>'+
  '<td><button class=exp data-exp="'+v.slug+'">▶ '+v.count+'</button></td>'+
  '<td>'+(v.reReqCount?'<span class="badge rrb">'+v.reReqCount+'</span>':'<span class=muted>–</span>')+'</td>'+
  '<td>'+v.items[0].age+'d</td>'+
- '<td><span class="badge '+(r?'ok':'need')+'">'+(r?'READY':'NEEDS')+'</span></td>'+
+ '<td>'+(noChase?'<span class="badge dead" title="'+esc(c.disposition_reason||'')+'">NO-CHASE</span>':'<span class="badge '+(r?'ok':'need')+'">'+(r?'READY':'NEEDS')+'</span>')+'</td>'+
  '<td class="sentcell">'+sentCell(v)+'</td>'+
  '<td><input class="em" data-slug="'+v.slug+'" data-f="sample_email" value="'+esc(c.sample_email||'')+'" placeholder="sample email"></td>'+
  '<td><input class="ac" data-slug="'+v.slug+'" data-f="account_number" value="'+esc(c.account_number||'')+'" placeholder="acct #"></td>'+

← e169d6d yoloforever c2: research vendor contacts (web+registry+sent)  ·  back to Sample Followup Sweep  ·  yoloforever c3: fix client-JS regex-in-template-literal erro 81464fe →