From 35fce05b65dc3e0f4ab9df2827f56de67bb13172 Mon Sep 17 00:00:00 2001 From: PJ Date: Sun, 31 May 2026 15:49:45 +0530 Subject: [PATCH] fix(folio): extract balanceMatchesAddedSum predicate as testable helper Move the ledger-balance-vs-added-rows predicate into a pure helper module so the property's logic is unit-testable in isolation. Marks the sanderling example as an ES module so cross-package ESM imports resolve under node. --- examples/folio/sanderling/package.json | 1 + examples/folio/sanderling/predicates.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 examples/folio/sanderling/predicates.ts diff --git a/examples/folio/sanderling/package.json b/examples/folio/sanderling/package.json index 73c9a4a..32dc35f 100644 --- a/examples/folio/sanderling/package.json +++ b/examples/folio/sanderling/package.json @@ -1,6 +1,7 @@ { "name": "folio", "private": true, + "type": "module", "description": "Minimal sanderling integration example.", "devDependencies": { "@sanderling/spec": "file:../../../pkg/spec" diff --git a/examples/folio/sanderling/predicates.ts b/examples/folio/sanderling/predicates.ts new file mode 100644 index 0000000..04889b8 --- /dev/null +++ b/examples/folio/sanderling/predicates.ts @@ -0,0 +1,22 @@ +export interface LedgerRow { + key: string; + signed: number; +} + +// When new ledger rows appear, the balance delta must equal the SUM of the +// new rows' signed amounts. Single-row sums and multi-row sums BOTH must +// match the delta; a double-submit landing two rows whose total is twice +// the balance change trips the sum check. +export function balanceMatchesAddedSum( + previousRows: readonly LedgerRow[], + currentRows: readonly LedgerRow[], + previousBalance: number, + currentBalance: number, +): boolean { + const previousKeys = new Set(previousRows.map(row => row.key)); + const added = currentRows.filter(row => !previousKeys.has(row.key)); + if (added.length === 0) return true; + const delta = currentBalance - previousBalance; + const addedSum = added.reduce((sum, row) => sum + row.signed, 0); + return addedSum === delta; +}