[object Object]

← back to Filemaker Mcp

Harden sales-summary against silent fetch truncation

073ebdde123e8703fff725a9ca74d9276aa8d478 · 2026-07-28 20:11:59 -0700 · Steve Abrams

Same failure class as the MTD window bug: if the query ever returns more
than the page cap, MTD would undercount with no warning. Raise cap to 5000
(~600 records/mo today) and throw loudly if it is ever hit.

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

Files touched

Diff

commit 073ebdde123e8703fff725a9ca74d9276aa8d478
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 28 20:11:59 2026 -0700

    Harden sales-summary against silent fetch truncation
    
    Same failure class as the MTD window bug: if the query ever returns more
    than the page cap, MTD would undercount with no warning. Raise cap to 5000
    (~600 records/mo today) and throw loudly if it is ever hit.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 scripts/sales-summary.mjs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/scripts/sales-summary.mjs b/scripts/sales-summary.mjs
index b5cc24e..92eb4a6 100644
--- a/scripts/sales-summary.mjs
+++ b/scripts/sales-summary.mjs
@@ -27,6 +27,7 @@ const EXCLUDE_INVOICES = new Set(['999999']); // test/demo records
 const LEDGER_PATH = join(dirname(fileURLToPath(import.meta.url)), '..', 'data', 'sales-summary-ledger.json');
 const LOOKBACK_DAYS = 10;   // how far back we pull to catch backdated entries
 const PRUNE_DAYS = 60;      // drop ledger entries not seen in this many days
+const FETCH_LIMIT = 5000;   // page cap; guarded below so truncation is never silent (~600/mo today)
 
 const pad = (n) => String(n).padStart(2, '0');
 const fmDate = ({ y, m, d }) => `${pad(m)}/${pad(d)}/${y}`; // FM returns zero-padded
@@ -61,9 +62,15 @@ async function main() {
   const { records } = await findRecords(
     DB, LAYOUT,
     [{ [DATE_FIELD]: `${from}...${m}/${d}/${y}` }],
-    { limit: 2000, sort: [{ fieldName: DATE_FIELD, sortOrder: 'ascend' }] },
+    { limit: FETCH_LIMIT, sort: [{ fieldName: DATE_FIELD, sortOrder: 'ascend' }] },
   );
 
+  // Guard: a silently-truncated fetch is the same failure class as the old MTD
+  // window bug — it would undercount without warning. Fail LOUD if we ever hit the cap.
+  if (records.length >= FETCH_LIMIT) {
+    throw new Error(`Fetch hit FETCH_LIMIT (${FETCH_LIMIT}) for window ${from}..${m}/${d}/${y} — MTD would truncate. Raise FETCH_LIMIT or paginate before trusting this run.`);
+  }
+
   // A BOOKED order (= a real sale) has money received (PAID ON ACCOUNT ≠ 0).
   // No payment yet = an open QUOTE, which must NOT count as sales.
   const isBooked = (f) => {

← 57f06a3 auto-save: 2026-07-28T17:01:56 (1 files) — scripts/post-mtd-  ·  back to Filemaker Mcp  ·  Reports bot: visible truncation warning + stop counting refu bbd7473 →