← back to Rentv 2026
harden(deals): parseAmount \s* binds magnitude across a typographic double space ($52 million→$52M, was $52); document range + billionaire as zero-occurrence follow-ons. Pure superset — real corpus uses ≤1 space, no existing input changes. +1 test, 60/0
971e9e4b1d8e5a6966c103a19bb4ea6e973fa9c3 · 2026-08-06 13:57:29 -0700 · Steve
Files touched
M scripts/lib/deal-parse.mjsM test/deals/parse.test.mjs
Diff
commit 971e9e4b1d8e5a6966c103a19bb4ea6e973fa9c3
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Aug 6 13:57:29 2026 -0700
harden(deals): parseAmount \s* binds magnitude across a typographic double space ($52 million→$52M, was $52); document range + billionaire as zero-occurrence follow-ons. Pure superset — real corpus uses ≤1 space, no existing input changes. +1 test, 60/0
---
scripts/lib/deal-parse.mjs | 9 ++++++++-
test/deals/parse.test.mjs | 8 ++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/scripts/lib/deal-parse.mjs b/scripts/lib/deal-parse.mjs
index fa870839..8c693f85 100644
--- a/scripts/lib/deal-parse.mjs
+++ b/scripts/lib/deal-parse.mjs
@@ -12,7 +12,14 @@
// as "$153"). If a title states only a per-X price, the total is unknown → null (honest-empty).
export function parseAmount(text) {
// Spelled words (mil/billion) tried before the bare single-letter M/B so "$52 Mil" → mil, "$150M" → m.
- const re = /\$\s?([\d,]+(?:\.\d+)?)\s?(bil|billion|mil|million|[mb]|k)?/gi;
+ // \s* (not \s?) before the magnitude so a typographic double space ("$52 million") still binds the
+ // suffix — \s? spanned only one space and silently dropped the magnitude ($52M → $52). Pure superset:
+ // every real-corpus amount uses ≤1 space, so this changes no existing input.
+ // KNOWN LIMITATIONS (zero occurrence in the live corpus — logged follow-ons, not fixed here to avoid
+ // regressing legit inputs): (a) a shared-magnitude range "$40-50 million" reads only the low bound
+ // unscaled ($40) — needs true range semantics; (b) the spelled word matches inside a larger word, so
+ // "$5 billionaire" would fabricate $5B — can't be tightened without breaking "$1.5MM" finance notation.
+ const re = /\$\s?([\d,]+(?:\.\d+)?)\s*(bil|billion|mil|million|[mb]|k)?/gi;
let m;
while ((m = re.exec(text)) !== null) {
const after = text.slice(m.index + m[0].length);
diff --git a/test/deals/parse.test.mjs b/test/deals/parse.test.mjs
index 82d610c5..feb8904c 100644
--- a/test/deals/parse.test.mjs
+++ b/test/deals/parse.test.mjs
@@ -98,6 +98,14 @@ test('parseAmount: broadened per-sf spellings (psf / sqft / per sq ft / per foot
for (const t of ['$153 psf', '$153 per sq ft', '$153 sqft', '$153 per foot'])
assert.equal(parseAmount(t).amount, null, t);
});
+test('parseAmount: a typographic double space still binds the magnitude (\\s* not \\s?)', () => {
+ // "$52 million" (two spaces) was dropping the suffix → $52; the magnitude must still attach.
+ assert.equal(parseAmount('$52 million deal').amount, 52000000);
+ assert.equal(parseAmount('$1.2 billion recap').amount, 1200000000);
+ // regression guard: the normal single-space and no-space forms are unchanged
+ assert.equal(parseAmount('$52 million').amount, 52000000);
+ assert.equal(parseAmount('$150M').amount, 150000000);
+});
// ── parseSize ─────────────────────────────────────────────────────────────────
test('parseSize: units / sf / acres', () => {
← 206b9954 Gate E (TK-10076): /services degraded-state banner on reales
·
back to Rentv 2026
·
auto-data-snapshot: 2026-08-06T13:58:45 (7 data files) — dat d0acfe5e →