[object Object]

← back to Marketing Command Center

calendars: filter Schumacher (internal-only) out of both calendar layers at source

5ea8d24ed0fd7a049b131bb0021efaaf6a0351cc · 2026-07-20 14:07:46 -0700 · Steve Abrams

Schumacher is internal-only and must never surface on a front end. The All
Calendars feed re-projects from dw_unified every ~10min, so scrubbing the JSON
alone would be undone on the next regen. Added a HIDDEN_VENDORS source filter
applied to the activation layer (after date projection, so other vendors keep
their real go-live slots), the launched layer, and the snapshot-fallback path.
Verified: live regen yields 0 Schumacher (activation 20304 -> 20034).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 5ea8d24ed0fd7a049b131bb0021efaaf6a0351cc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 20 14:07:46 2026 -0700

    calendars: filter Schumacher (internal-only) out of both calendar layers at source
    
    Schumacher is internal-only and must never surface on a front end. The All
    Calendars feed re-projects from dw_unified every ~10min, so scrubbing the JSON
    alone would be undone on the next regen. Added a HIDDEN_VENDORS source filter
    applied to the activation layer (after date projection, so other vendors keep
    their real go-live slots), the launched layer, and the snapshot-fallback path.
    Verified: live regen yields 0 Schumacher (activation 20304 -> 20034).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 modules/calendars/lib.js | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/modules/calendars/lib.js b/modules/calendars/lib.js
index 82bc488..3e03665 100644
--- a/modules/calendars/lib.js
+++ b/modules/calendars/lib.js
@@ -103,6 +103,13 @@ function priceBand(p) {
   if (p < 500) return '$200–500'; if (p < 1000) return '$500–1,000'; return '$1,000+';
 }
 
+// Vendors that must NEVER surface on any front-end surface. Schumacher is
+// internal-only (see the schumacher-internal-only standing rule) — it is filtered
+// out of BOTH calendar layers at the source so a cache regeneration can't
+// reintroduce it. Matched case-insensitively against the resolved vendor.
+const HIDDEN_VENDORS = new Set(['schumacher']);
+const isHiddenVendor = (v) => HIDDEN_VENDORS.has(String(v || '').trim().toLowerCase());
+
 // Map a shopify_products row → the common filterable fields (shared by the
 // activation layer's enrichment join AND the launched layer's direct rows).
 function fieldsFrom(e) {
@@ -154,7 +161,7 @@ async function computeActivation() {
   } finally { c.release(); }
 
   // launched layer — one item per already-live product, on its launch date (LIVE)
-  const launched = launchedRows.map(r => {
+  const launched = launchedRows.filter(r => !isHiddenVendor(r.vendor)).map(r => {
     const d = new Date(r.created_at_shopify);
     return {
       key: r.shopify_id, layer: 'launched',
@@ -199,14 +206,18 @@ async function computeActivation() {
         shopify_id: r.shopify_id || '',
       };
     }
+    // drop internal-only vendors (e.g. Schumacher) AFTER date projection so the
+    // remaining SKUs keep their real go-live slots (never resequenced by a regen)
+    items = items.filter(it => !isHiddenVendor(it.vendor));
+    total = items.length;
     start_date = items[0]?.date || null;
     end_date = items[total - 1]?.date || null;
   } else {
     const disk = store.readJson(CACHE_FILE, null) || {};
-    items = disk.items || [];
-    total = disk.total || items.length;
-    start_date = disk.start_date || null;
-    end_date = disk.end_date || null;
+    items = (disk.items || []).filter(it => !isHiddenVendor(it.vendor));
+    total = items.length;
+    start_date = items[0]?.date || disk.start_date || null;
+    end_date = items[total - 1]?.date || disk.end_date || null;
   }
 
   const out = {

← 540ae08 chore: lint + refactor + v1.6.0 (session close — reel/FB-pag  ·  back to Marketing Command Center  ·  chore: v1.6.1 (session close — Schumacher calendar filter) 76de953 →