[object Object]

← back to Rentv

feat(brief): auto-refresh the Boomer 'Deal of the Day' — pull-deals chains generateBrief() after writing deals.json (dedupe-guarded → spends ~$0.15 ONLY when the top deal changes; NON-FATAL so a TTS error never breaks the crawl). Keeps /brief current on prod via the existing pull-deals cron — no crontab edit. gen-deal-brief refactored to export generateBrief() + run standalone only when invoked directly. 64/0.

ab40d2bf418ef9426f14e30508932147344c5ce9 · 2026-08-06 16:31:28 -0700 · Steve

Files touched

Diff

commit ab40d2bf418ef9426f14e30508932147344c5ce9
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Aug 6 16:31:28 2026 -0700

    feat(brief): auto-refresh the Boomer 'Deal of the Day' — pull-deals chains generateBrief() after writing deals.json (dedupe-guarded → spends ~$0.15 ONLY when the top deal changes; NON-FATAL so a TTS error never breaks the crawl). Keeps /brief current on prod via the existing pull-deals cron — no crontab edit. gen-deal-brief refactored to export generateBrief() + run standalone only when invoked directly. 64/0.
---
 scripts/gen-deal-brief.mjs | 7 +++++--
 scripts/pull-deals.mjs     | 5 +++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/scripts/gen-deal-brief.mjs b/scripts/gen-deal-brief.mjs
index c1982bf6..ceefafe8 100644
--- a/scripts/gen-deal-brief.mjs
+++ b/scripts/gen-deal-brief.mjs
@@ -62,7 +62,7 @@ async function tts(text, out) {
   writeFileSync(out, Buffer.from(await res.arrayBuffer()));
 }
 
-async function main() {
+export async function generateBrief() {
   const deals = JSON.parse(readFileSync(join(DATA, 'deals.json'), 'utf8')).deals || [];
   const top = pickTopDeal(deals);
   if (!top) { console.log('no priced deal — skip (nothing to narrate)'); return; }
@@ -90,4 +90,7 @@ async function main() {
   console.log(`✓ /public/audio/deal-brief.mp3 written · actual ~$${est.toFixed(3)}`);
 }
 
-main().catch(e => { console.error('gen-deal-brief failed:', e.message); process.exit(1); });
+// Run standalone only when invoked directly (not when imported by pull-deals.mjs).
+if (import.meta.url === `file://${process.argv[1]}`) {
+  generateBrief().catch(e => { console.error('gen-deal-brief failed:', e.message); process.exit(1); });
+}
diff --git a/scripts/pull-deals.mjs b/scripts/pull-deals.mjs
index 609d7053..9031d173 100644
--- a/scripts/pull-deals.mjs
+++ b/scripts/pull-deals.mjs
@@ -71,6 +71,11 @@ try {
   const withAmt = deals.filter((d) => d.amount).length;
   console.log(`OK: parsed ${deals.length} deal listings (${withAmt} with $ amount)`);
   console.log(`registry: +${reg.added} new · ${reg.changed} changed · ${reg.unchanged} unchanged · ${reg.total} total deals ever found`);
+  // Refresh the Boomer "Deal of the Day" audio brief off the just-written deals. Dedupe-guarded so it
+  // only spends (~$0.15) when the TOP deal actually changes; NON-FATAL so a TTS error never breaks the
+  // deal crawl. This is what keeps /brief current on prod via the existing pull-deals cron.
+  try { const { generateBrief } = await import('./gen-deal-brief.mjs'); await generateBrief(); }
+  catch (e) { console.error('deal-brief refresh skipped:', e.message); }
 } catch (e) {
   console.error('deals pull failed:', e.message, '— last-good deals.json kept');
   process.exitCode = 1;

← 6574a4ff feat(services): Property Management now registry-backed (162  ·  back to Rentv  ·  auto-data-snapshot: 2026-08-06T16:33:58 (8 data files) — .de 35d978b2 →