← back to Commercialrealestate
scripts/sources/appraisal-panel.js
60 lines
// sources/appraisal-panel.js — credentialed adapter for Steve's APPRAISAL PANEL.
//
// PURPOSE: Steve has direct access to an appraisal panel and can get near-guaranteed supportable values
// on LA-area properties — the gold standard versus our Census-rent / closed-sale value estimates. This
// adapter is the plug-in slot: once the panel's API/login is configured, getSupportableValue(address)
// returns a real supportable value + confidence; until then it is INERT and returns {available:false}.
//
// PLUG-IN CONTRACT:
// status() -> { available:boolean, needs?:string, provider?:string }
// getSupportableValue({address,city,zip})
// -> { available:false, needs:string } // not configured
// -> { available:true, matched:boolean, value?:number,
// confidence?:'supportable'|'indicative', asOf?:ISO, basis?:string }
//
// GATED: the appraisal-panel access is Steve-provided. Fabricates NOTHING with no credential.
'use strict';
const CREDENTIAL_ENV = 'APPRAISAL_PANEL_API_KEY'; // panel API key / login token
const BASE_URL_ENV = 'APPRAISAL_PANEL_BASE_URL'; // panel API base, when applicable
function readCredential() {
if (process.env[CREDENTIAL_ENV]) return { key: process.env[CREDENTIAL_ENV], baseUrl: process.env[BASE_URL_ENV] || null };
try {
const fs = require('fs'), path = require('path');
const env = fs.readFileSync(path.join(__dirname, '..', '..', '.env'), 'utf8');
const m = env.match(new RegExp('^' + CREDENTIAL_ENV + '=(.*)$', 'm'));
if (m) return {
key: m[1].replace(/['"]/g, '').trim(),
baseUrl: (env.match(new RegExp('^' + BASE_URL_ENV + '=(.*)$', 'm')) || [])[1]?.replace(/['"]/g, '').trim() || null
};
} catch (_) {}
return null;
}
const NEEDS = `appraisal-panel access — an ${CREDENTIAL_ENV} (the panel's API key or login token) and `
+ `${BASE_URL_ENV} (the panel API base URL), OR confirmation of how Steve pulls supportable values from `
+ `his panel (manual portal vs API). Steve has direct access; set these in .env once the integration path is chosen.`;
async function status() {
const cred = readCredential();
return cred ? { available: true } : { available: false, needs: NEEDS };
}
// Supportable value for one address. While uncredentialed, {available:false} -> caller uses the existing
// Census/closed-sale estimate and labels it as such.
async function getSupportableValue({ address, city, zip } = {}) {
const cred = readCredential();
if (!cred) return { available: false, needs: NEEDS };
// --- INTEGRATION POINT (wire when panel access exists) ----------------------------------------------
// const url = `${cred.baseUrl}/value?address=${encodeURIComponent(address)}&zip=${zip}`;
// const r = await fetch(url, { headers: { Authorization: `Bearer ${cred.key}` } });
// const j = await r.json();
// return { available:true, matched:true, value:j.supportableValue, confidence:'supportable',
// asOf:j.effectiveDate, basis:'appraisal-panel supportable value' };
return { available: true, matched: false, note: 'credential present; panel value mapping not yet wired' };
}
module.exports = { status, getSupportableValue, CREDENTIAL_ENV, BASE_URL_ENV, NEEDS };