← back to Nationalrealestate
USRE: searched address in a parcel-covered county deep-links to the property page (prefill+auto-search); graceful fallback to county market (v0.14.0)
7c0710ffac35aa9c2b1abbd31be5d450bded7496 · 2026-07-26 21:25:46 -0700 · Steve
Files touched
M package-lock.jsonM package.jsonM public/property.htmlM src/server/index.ts
Diff
commit 7c0710ffac35aa9c2b1abbd31be5d450bded7496
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jul 26 21:25:46 2026 -0700
USRE: searched address in a parcel-covered county deep-links to the property page (prefill+auto-search); graceful fallback to county market (v0.14.0)
---
package-lock.json | 4 ++--
package.json | 2 +-
public/property.html | 4 ++++
src/server/index.ts | 23 +++++++++++++++++++++--
4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 68254b3..7b9f6a3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "nationalrealestate",
- "version": "0.13.0",
+ "version": "0.14.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nationalrealestate",
- "version": "0.13.0",
+ "version": "0.14.0",
"dependencies": {
"better-sqlite3": "^13.0.1",
"dotenv": "^16.4.5",
diff --git a/package.json b/package.json
index 35be955..035c45f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "nationalrealestate",
- "version": "0.13.0",
+ "version": "0.14.0",
"private": true,
"type": "module",
"description": "USRealEstate — national U.S. residential market explorer. Free-data v1 (Redfin Data Center, Zillow Research, Census ACS, FHFA). Internal analyst tool behind basic auth.",
diff --git a/public/property.html b/public/property.html
index c3ef4f3..8eb247d 100644
--- a/public/property.html
+++ b/public/property.html
@@ -352,7 +352,11 @@ async function initCounties(){
initCounties();
const loc = qs.get('loc');
+const prefillQ = qs.get('q');
if (loc) load(loc);
+else if (prefillQ) { // deep-linked from the top location search — prefill + auto-run the address search
+ const qi = document.getElementById('q'); qi.value = prefillQ; search(prefillQ);
+}
</script>
<script src="/nav-drawer.js"></script>
<script src="/geo-search.js"></script>
diff --git a/src/server/index.ts b/src/server/index.ts
index c58f0bc..f10bd5e 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -122,6 +122,18 @@ app.get('/api/regions', async (req, res) => {
}
});
+// parcel-covered counties (parcel_source registry), cached — lets geo-search deep-link
+// an address to the property page only where we actually have parcels.
+let _coveredCache: { at: number; set: Set<string> } | null = null;
+async function coveredCounties(): Promise<Set<string>> {
+ if (_coveredCache && Date.now() - _coveredCache.at < 10 * 60_000) return _coveredCache.set;
+ try {
+ const r = await query<{ county_fips: string }>(`SELECT county_fips FROM parcel_source`);
+ _coveredCache = { at: Date.now(), set: new Set(r.rows.map(x => x.county_fips)) };
+ } catch { _coveredCache = { at: Date.now(), set: new Set() }; }
+ return _coveredCache.set;
+}
+
// universal location search — resolves a typed county / city / metro / state to a
// market page. National coverage via the region table (fast; ~4.2k rows). ZIP + exact
// street address are county-scoped and live on the property page (no national ZIP index).
@@ -154,10 +166,17 @@ app.get('/api/geo-search', async (req, res) => {
const r = await query<{ canonical_key: string; name: string; state_code: string | null }>(
`SELECT canonical_key, name, state_code FROM region WHERE fips = $1 AND region_type = 'county'`, [co.GEOID]);
if (r.rows.length) { const x = r.rows[0];
+ // property-level intent: if the county has parcel coverage, deep-link into the
+ // property page prefilled with the address; else fall back to the county market.
+ const covered = await coveredCounties();
+ const hasParcels = covered.has(co.GEOID);
+ const url = hasParcels
+ ? '/property.html?county=' + encodeURIComponent(co.GEOID) + '&q=' + encodeURIComponent(q)
+ : '/market.html?key=' + encodeURIComponent(x.canonical_key);
return res.json({ q, results: [{ type: 'address', name: m.matchedAddress || q, state: x.state_code || null,
- sub: x.name, key: x.canonical_key, url: '/market.html?key=' + encodeURIComponent(x.canonical_key) }] }); }
+ sub: hasParcels ? x.name + ' · view property →' : x.name, key: x.canonical_key, url }] }); }
}
- } catch (e) { /* geocoder timeout/failure → fall through to name search */ }
+ } catch (e) { /* geocoder timeout/failure → fall through to empty (client shows a hint) */ }
return res.json({ q, results: [] });
}
← e08091b USRE: geo-search now resolves ZIP (zip_county crosswalk) + s
·
back to Nationalrealestate
·
USRE geo-search: recent searches (localStorage) shown on emp 9ab361e →