[object Object]

← back to Gmc Viewer

fix: MC status value is 'approved' not 'active' (approved count was 0); summary recomputes live from cache

3da85f732ac0156972e7e764bb4c406505bafc30 · 2026-07-09 08:32:07 -0700 · steve

Files touched

Diff

commit 3da85f732ac0156972e7e764bb4c406505bafc30
Author: steve <steve@designerwallcoverings.com>
Date:   Thu Jul 9 08:32:07 2026 -0700

    fix: MC status value is 'approved' not 'active' (approved count was 0); summary recomputes live from cache
---
 public/index.html |  2 +-
 server.js         | 28 ++++++++++++++++------------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/public/index.html b/public/index.html
index 6deb1c6..512830f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -22,7 +22,7 @@ input[type=range]{vertical-align:middle}
 .price{font-weight:700;font-size:13px}
 .price.s{color:#e0a93b}.price.r{color:#5fd08a}
 .st{display:inline-block;font-size:10px;padding:1px 6px;border-radius:10px;margin-top:4px}
-.st.active{background:#183a29;color:#5fd08a}.st.disapproved{background:#3a1a1a;color:#f08a8a}.st.pending{background:#3a331a;color:#e0c93b}.st.unknown{background:#232838;color:#8b93a3}
+.st.active,.st.approved{background:#183a29;color:#5fd08a}.st.disapproved{background:#3a1a1a;color:#f08a8a}.st.pending{background:#3a331a;color:#e0c93b}.st.unknown{background:#232838;color:#8b93a3}
 .load{grid-column:1/-1;text-align:center;padding:20px;color:#8b93a3}
 </style></head><body>
 <header>
diff --git a/server.js b/server.js
index 44f56d3..9cd6972 100644
--- a/server.js
+++ b/server.js
@@ -15,6 +15,19 @@ let refreshing = false;
 
 if (fs.existsSync(DATA)) { try { CATALOG = JSON.parse(fs.readFileSync(DATA, 'utf8')); console.log(`loaded ${CATALOG.items.length} cached offers`); } catch (e) {} }
 
+// Content API status values are 'approved' / 'disapproved' / 'pending' (NOT 'active').
+function computeSummary(items) {
+  return {
+    total: items.length,
+    approved: items.filter(i => i.status === 'approved').length,
+    disapproved: items.filter(i => i.status === 'disapproved').length,
+    pending: items.filter(i => i.status === 'pending').length,
+    at_425: items.filter(i => Math.abs(i.price - 4.25) < 0.01).length,
+    real_price: items.filter(i => i.price > 4.26).length,
+    by_country: items.reduce((a, i) => (a[i.country] = (a[i.country] || 0) + 1, a), {}),
+  };
+}
+
 async function pull() {
   if (refreshing) return; refreshing = true;
   console.log('refreshing from Content API...');
@@ -46,16 +59,7 @@ async function pull() {
       page = r.nextPageToken;
     } while (page);
     const items = [...byId.values()];
-    const summary = {
-      total: items.length,
-      approved: items.filter(i => i.status === 'active').length,
-      disapproved: items.filter(i => i.status === 'disapproved').length,
-      pending: items.filter(i => i.status === 'pending').length,
-      at_425: items.filter(i => Math.abs(i.price - 4.25) < 0.01).length,
-      real_price: items.filter(i => i.price > 4.26).length,
-      by_country: items.reduce((a, i) => (a[i.country] = (a[i.country] || 0) + 1, a), {}),
-    };
-    CATALOG = { generated_at: new Date().toISOString(), items, summary };
+    CATALOG = { generated_at: new Date().toISOString(), items, summary: computeSummary(items) };
     fs.writeFileSync(DATA, JSON.stringify(CATALOG));
     console.log(`refreshed: ${items.length} offers, ${summary.approved} approved, ${summary.disapproved} disapproved`);
   } catch (e) { console.error('pull failed', e.message); }
@@ -67,14 +71,14 @@ const send = (res, code, body, type = 'application/json') => { res.writeHead(cod
 const server = http.createServer((req, res) => {
   if (req.headers.authorization !== AUTH) { res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="gmc"' }); return res.end('auth'); }
   const u = new URL(req.url, 'http://x');
-  if (u.pathname === '/api/summary') return send(res, 200, JSON.stringify({ generated_at: CATALOG.generated_at, summary: CATALOG.summary, refreshing }));
+  if (u.pathname === '/api/summary') return send(res, 200, JSON.stringify({ generated_at: CATALOG.generated_at, summary: computeSummary(CATALOG.items), refreshing }));
   if (u.pathname === '/api/refresh') { pull(); return send(res, 200, JSON.stringify({ started: true })); }
   if (u.pathname === '/api/products') {
     const f = u.searchParams.get('filter') || 'all';
     const q = (u.searchParams.get('q') || '').toLowerCase();
     const limit = Math.min(2000, parseInt(u.searchParams.get('limit') || '500', 10));
     let items = CATALOG.items;
-    if (f === 'approved') items = items.filter(i => i.status === 'active');
+    if (f === 'approved') items = items.filter(i => i.status === 'approved');
     else if (f === 'disapproved') items = items.filter(i => i.status === 'disapproved');
     else if (f === 'pending') items = items.filter(i => i.status === 'pending');
     else if (f === 'at425') items = items.filter(i => Math.abs(i.price - 4.25) < 0.01);

← 7e32dc7 gmc-viewer: local read-only viewer of live Google Merchant c  ·  back to Gmc Viewer  ·  auto-save: 2026-07-09T14:10:49 (1 files) — dw-ga4-custom-pix a07e983 →