[object Object]

← back to Rentv 2026

pr/letters: Cody gate — lowercase-normalize extractMergeFields too, so the stored merge_fields metadata matches render()'s now-case-insensitive fill (they described the same template in two case dialects). Bonus: {{First_Name}} and {{first_name}} now dedupe to one field. merge_fields is display/validation metadata (not a key/join), forward-only, verified

035683ac33e2999c0d1e589b0605609f92bdae03 · 2026-08-05 22:25:58 -0700 · Steve

Files touched

Diff

commit 035683ac33e2999c0d1e589b0605609f92bdae03
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 5 22:25:58 2026 -0700

    pr/letters: Cody gate — lowercase-normalize extractMergeFields too, so the stored merge_fields metadata matches render()'s now-case-insensitive fill (they described the same template in two case dialects). Bonus: {{First_Name}} and {{first_name}} now dedupe to one field. merge_fields is display/validation metadata (not a key/join), forward-only, verified
---
 src/pr/services/letters.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pr/services/letters.js b/src/pr/services/letters.js
index aac7fff6..1fbf0d63 100644
--- a/src/pr/services/letters.js
+++ b/src/pr/services/letters.js
@@ -56,7 +56,7 @@ async function saveVersion(templateId, { subject_template, blocks, change_note,
 
 function extractMergeFields(blocks, subject) {
   const set = new Set();
-  const scan = (s) => { for (const m of String(s || '').matchAll(/\{\{\s*([a-z0-9_]+)\s*\}\}/gi)) set.add(m[1]); };
+  const scan = (s) => { for (const m of String(s || '').matchAll(/\{\{\s*([a-z0-9_]+)\s*\}\}/gi)) set.add(m[1].toLowerCase()); }; // lowercase-normalize so the stored merge_fields metadata matches render()'s case-insensitive fill
   scan(subject);
   (blocks || []).forEach((b) => scan(b.content));
   return [...set];

← bcf70d2e pr/letters: case-insensitive merge-field lookup in render().  ·  back to Rentv 2026  ·  auto-save: 2026-08-05T22:46:27 (7 files) — data/deals-regist e21420df →