[object Object]

← back to Rentv

search-index: resolve psql by full path so launchd (minimal PATH) keeps the usre source — TK-10253

97ad44f2b7d0b5ed57d3000fd74ccaf354db31ec · 2026-08-05 13:51:45 -0700 · Steve Abrams

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

Files touched

Diff

commit 97ad44f2b7d0b5ed57d3000fd74ccaf354db31ec
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 5 13:51:45 2026 -0700

    search-index: resolve psql by full path so launchd (minimal PATH) keeps the usre source — TK-10253
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 scripts/build-search-index.mjs | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/scripts/build-search-index.mjs b/scripts/build-search-index.mjs
index 4dae9629..73f33155 100644
--- a/scripts/build-search-index.mjs
+++ b/scripts/build-search-index.mjs
@@ -59,10 +59,18 @@ function crcpEdgar() {
   const arr = jload(join(PROJ, 'commercialrealestate', 'data', 'edgar-reit-deals.json'), []);
   return (Array.isArray(arr) ? arr : []).map((x, i) => ({ build: 'crcp', type: 'reit-filing', id: 'edgar-' + (x.cik || i) + '-' + i, title: [x.company, x.property].filter(Boolean).join(' — '), subtitle: [x.ticker, x.form].filter(Boolean).join(' · '), date: x.filed || null, city: null, region: null, amount: +x.price || null, amount_label: money(x.price), parties: x.company || null, url: x.filing_url || null, text: blob(x.company, x.ticker, x.property, x.form) }));
 }
+// Resolve psql explicitly — launchd runs with a minimal PATH that doesn't include Homebrew, so a
+// bare `psql` throws under the scheduled job and silently drops the usre source. Full path + fallbacks.
+const PSQL = (() => {
+  for (const p of [process.env.PSQL_BIN, '/opt/homebrew/opt/postgresql@14/bin/psql', '/opt/homebrew/bin/psql', '/usr/local/bin/psql', 'psql'].filter(Boolean)) {
+    try { if (p === 'psql' || existsSync(p)) return p; } catch { /* next */ }
+  }
+  return 'psql';
+})();
 function usreDeals() {
   try {
     const sql = "SELECT address,city,county_name,ctype,sale_price,sale_date,sqft,year_built FROM recent_commercial_deals ORDER BY sale_date DESC NULLS LAST LIMIT 20000";
-    const out = execSync(`psql -h /tmp usre -tA -F '\t' -c "${sql}"`, { encoding: 'utf8', timeout: 20000 });
+    const out = execSync(`${PSQL} -h /tmp usre -tA -F '\t' -c "${sql}"`, { encoding: 'utf8', timeout: 20000 });
     return out.trim().split('\n').filter(Boolean).map((line, i) => {
       const [address, city, county, ctype, price, date, sqft, yb] = line.split('\t');
       return { build: 'usre', type: 'deal', id: 'usre-' + i, title: address || 'Commercial sale', subtitle: [ctype, sqft ? (+sqft).toLocaleString() + ' SF' : null].filter(Boolean).join(' · '), date: (date || '').slice(0, 10) || null, city: city || null, region: county || null, amount: +price || null, amount_label: money(price), parties: null, url: null, text: blob(address, city, county, ctype, yb) };

← ddbcba2e RENTV: launchd job for unified search index rebuild (all bui  ·  back to Rentv  ·  ops: persistent (launchd) RENTV build loop — sandboxed claud 80e38cfe →