← back to Rentv 2026
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
M scripts/build-search-index.mjs
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 2026
·
ops: persistent (launchd) RENTV build loop — sandboxed claud 80e38cfe →