[object Object]

← back to Sample Followup Sweep

yoloforever c1: Cody FIX-FIRST — sent.json freshness indicator + build-fleet date fix

e8bc50a520a339eaa82d77049eedfd1b0d823c5e · 2026-08-15 08:04:18 -0700 · Steve Abrams

- server.js: console meta now shows Sent-snapshot age ('Sent data Nh ago',
  ⚠ + re-harvest hint past 24h) so a stale sent.json can't silently mislabel rows
- scripts/build-fleet.js: 'today' defaults to new Date() (was hardcoded
  2026-08-14) so re-running against fresh FM data gives correct ages;
  optional argv[3] as-of date for reproducible snapshots
- staged 3 addressed-but-unsent vendors to send-queue.json; all ready=false
  (missing account_number) -> gated send memo in pending-approval

Files touched

Diff

commit e8bc50a520a339eaa82d77049eedfd1b0d823c5e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sat Aug 15 08:04:18 2026 -0700

    yoloforever c1: Cody FIX-FIRST — sent.json freshness indicator + build-fleet date fix
    
    - server.js: console meta now shows Sent-snapshot age ('Sent data Nh ago',
      ⚠ + re-harvest hint past 24h) so a stale sent.json can't silently mislabel rows
    - scripts/build-fleet.js: 'today' defaults to new Date() (was hardcoded
      2026-08-14) so re-running against fresh FM data gives correct ages;
      optional argv[3] as-of date for reproducible snapshots
    - staged 3 addressed-but-unsent vendors to send-queue.json; all ready=false
      (missing account_number) -> gated send memo in pending-approval
---
 scripts/build-fleet.js |  4 +++-
 server.js              | 10 +++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/scripts/build-fleet.js b/scripts/build-fleet.js
index 5f0c351..9b8e71b 100644
--- a/scripts/build-fleet.js
+++ b/scripts/build-fleet.js
@@ -7,7 +7,9 @@ const path = require('path');
 const src = process.argv[2];
 if (!src) { console.error('usage: node scripts/build-fleet.js <fm-result.txt>'); process.exit(1); }
 const j = JSON.parse(fs.readFileSync(src, 'utf8'));
-const today = new Date('2026-08-14T00:00:00');
+// "today" drives every age calc. Default = now (correct on every re-run against fresh FM data).
+// Optional argv[3] = an explicit as-of date (YYYY-MM-DD) to reproduce a past snapshot.
+const today = process.argv[3] ? new Date(process.argv[3] + 'T00:00:00') : new Date();
 
 // Best-effort vid → display name. Editable in the viewer; unknowns show the raw vid.
 const NAME = {
diff --git a/server.js b/server.js
index 7b8f057..8a7b0b0 100644
--- a/server.js
+++ b/server.js
@@ -209,7 +209,15 @@ let S={fleet:{vendors:[]},contacts:{},sent:{byEmail:{}}};
 const sortKey=localStorage.getItem('sfsort')||'items';
 async function load(){const r=await fetch('/api/state');S=await r.json();if(!S.sent)S.sent={byEmail:{}};document.getElementById('sort').value=sortKey;render();
  const nSent=S.fleet.vendors.filter(v=>sentInfo(v).sent).length;
- document.getElementById('meta').textContent=S.fleet.vendors.length+' vendors · '+S.fleet.totalItems+' items · window '+S.fleet.window+' · '+nSent+' emailed / '+(S.fleet.vendors.length-nSent)+' not yet';}
+ const meta=document.getElementById('meta');
+ meta.textContent=S.fleet.vendors.length+' vendors · '+S.fleet.totalItems+' items · window '+S.fleet.window+' · '+nSent+' emailed / '+(S.fleet.vendors.length-nSent)+' not yet';
+ // Freshness of the Sent-folder snapshot — a stale sent.json silently mislabels rows, so surface its age.
+ const h=S.sent&&S.sent.harvested?new Date(S.sent.harvested):null;
+ if(h){const hrs=(Date.now()-h.getTime())/3.6e6;const label=hrs<1?'just now':hrs<24?Math.round(hrs)+'h ago':Math.round(hrs/24)+'d ago';
+   const span=document.createElement('span');span.style.marginLeft='8px';
+   span.style.color=hrs>24?'#9a6b12':'#999';span.title='sent.json harvested '+S.sent.harvested;
+   span.textContent=(hrs>24?'⚠ ':'')+'· Sent data '+label+(hrs>24?' — re-harvest recommended':'');
+   meta.appendChild(span);}}
 function ready(v){const c=S.contacts[v.slug]||{};return c.sample_email&&c.account_number;}
 // Resolve whether this vendor's follow-up was actually emailed, from the Sent-folder snapshot.
 // Matches the vendor's recipient address(es) (contacts.sample_email) against sent.byEmail.

← 29a0213 Console: per-vendor Send button (fires exact letter via Geor  ·  back to Sample Followup Sweep  ·  auto-data-snapshot: 2026-08-15T08:12:28 (1 data files) — dat 46f2853 →