← back to Dandeana Hub
land records: live county parcel pull — tract recorded as Lyon Estates, all 10 lots sold; lot-by-lot table with owners/assessed/deed refs; daily re-pull
e31e5a5372b041bbde6299a6b9a9096bb757c568 · 2026-07-22 12:32:35 -0700 · Steve Abrams
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Files touched
A data/parcels.jsonM data/records.jsonM data/timeline.jsonM public/index.htmlA scripts/pull-parcels.jsM server.js
Diff
commit e31e5a5372b041bbde6299a6b9a9096bb757c568
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 22 12:32:35 2026 -0700
land records: live county parcel pull — tract recorded as Lyon Estates, all 10 lots sold; lot-by-lot table with owners/assessed/deed refs; daily re-pull
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---
data/parcels.json | 211 ++++++++++++++++++++++++++++++++++++++++++++++++
data/records.json | 3 +-
data/timeline.json | 5 +-
public/index.html | 33 +++++++-
scripts/pull-parcels.js | 58 +++++++++++++
server.js | 10 ++-
6 files changed, 314 insertions(+), 6 deletions(-)
diff --git a/data/parcels.json b/data/parcels.json
new file mode 100644
index 0000000..9489f63
--- /dev/null
+++ b/data/parcels.json
@@ -0,0 +1,211 @@
+{
+ "pulledAt": "2026-07-22T19:31:17.310Z",
+ "source": "San Diego County ARCC public parcel layer (gis-public.sandiegocounty.gov)",
+ "tract": "POWAY TCT NO 16-005 (Larchmont St) — marketed as \"Lyon Estates\" by New Pointe Communities",
+ "lots": [
+ {
+ "apn": "314-032-01-00",
+ "lot": "LOT B",
+ "owner": "LYON ESTATES HOMEOWNERS ASSOCIATION",
+ "acreage": 40.15,
+ "assessedLand": 0,
+ "assessedImprovements": 0,
+ "assessedTotal": 0,
+ "deedDoc": "2024/2025 series doc #086616",
+ "deedDocNumber": "086616",
+ "deedDate": "2025-04-04",
+ "address": null,
+ "livingArea": null,
+ "bedrooms": 0,
+ "baths": 0,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-01-00",
+ "lot": "LOT 1",
+ "owner": "MUNIR SUFIAN",
+ "acreage": 1.52,
+ "assessedLand": 1587650,
+ "assessedImprovements": 1013349,
+ "assessedTotal": 2600999,
+ "deedDoc": "2024/2025 series doc #156440",
+ "deedDocNumber": "156440",
+ "deedDate": "2024-06-20",
+ "address": "15101 LARCHMONT ST",
+ "livingArea": 3761,
+ "bedrooms": 4,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-02-00",
+ "lot": "LOT 2",
+ "owner": "POLACKAL FAMILY TRUST 10-21-25",
+ "acreage": 1.75,
+ "assessedLand": 1662559,
+ "assessedImprovements": 938440,
+ "assessedTotal": 2600999,
+ "deedDoc": "2024/2025 series doc #330652",
+ "deedDocNumber": "330652",
+ "deedDate": "2025-11-21",
+ "address": "15117 LARCHMONT ST",
+ "livingArea": 3501,
+ "bedrooms": 4,
+ "baths": 3.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-03-00",
+ "lot": "LOT 3",
+ "owner": "SAPERA LANCE S&MICHELLE L LIVING TRUST 04-04-17",
+ "acreage": 1.37,
+ "assessedLand": 759438,
+ "assessedImprovements": 359027,
+ "assessedTotal": 1118465,
+ "deedDoc": "2024/2025 series doc #066182",
+ "deedDocNumber": "066182",
+ "deedDate": "2025-03-14",
+ "address": "15110 LARCHMONT ST",
+ "livingArea": 3501,
+ "bedrooms": 4,
+ "baths": 3.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-04-00",
+ "lot": "LOT 4",
+ "owner": "PASEO ZAFIROS LLC",
+ "acreage": 1.27,
+ "assessedLand": 1402500,
+ "assessedImprovements": 1020000,
+ "assessedTotal": 2422500,
+ "deedDoc": "2024/2025 series doc #116241",
+ "deedDocNumber": "116241",
+ "deedDate": "2025-05-02",
+ "address": "15120 LARCHMONT ST",
+ "livingArea": 3501,
+ "bedrooms": 4,
+ "baths": 3.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-05-00",
+ "lot": "LOT 5",
+ "owner": "NUDURUPATI SAIKIRAN&SUPRIYA",
+ "acreage": 1.32,
+ "assessedLand": 1412700,
+ "assessedImprovements": 1086300,
+ "assessedTotal": 2499000,
+ "deedDoc": "2024/2025 series doc #172956",
+ "deedDocNumber": "172956",
+ "deedDate": "2025-06-30",
+ "address": "15130 LARCHMONT ST",
+ "livingArea": 3967,
+ "bedrooms": 5,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-06-00",
+ "lot": "LOT 6",
+ "owner": "GREEN FAMILY TRUST 04-17-20",
+ "acreage": 8.36,
+ "assessedLand": 1973700,
+ "assessedImprovements": 1035300,
+ "assessedTotal": 3009000,
+ "deedDoc": "2024/2025 series doc #057880",
+ "deedDocNumber": "057880",
+ "deedDate": "2025-03-06",
+ "address": "15148 LARCHMONT ST",
+ "livingArea": 3967,
+ "bedrooms": 5,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-07-00",
+ "lot": "LOT 7",
+ "owner": "NGUYEN FAMILY TRUST 08-19-24",
+ "acreage": 7.44,
+ "assessedLand": 1688100,
+ "assessedImprovements": 1065900,
+ "assessedTotal": 2754000,
+ "deedDoc": "2024/2025 series doc #052157",
+ "deedDocNumber": "052157",
+ "deedDate": "2025-02-28",
+ "address": "15139 LARCHMONT ST",
+ "livingArea": 3761,
+ "bedrooms": 4,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-08-00",
+ "lot": "LOT 8",
+ "owner": "KOTERA DWAYNE&LISA REVOCABLE TRUST 10-01-21",
+ "acreage": 7.32,
+ "assessedLand": 1800000,
+ "assessedImprovements": 800000,
+ "assessedTotal": 2600000,
+ "deedDoc": "2024/2025 series doc #339717",
+ "deedDocNumber": "339717",
+ "deedDate": "2025-12-02",
+ "address": "15123 LARCHMONT ST",
+ "livingArea": 3967,
+ "bedrooms": 5,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-09-00",
+ "lot": "LOT 9",
+ "owner": "BOSLEY BRADFORD L LIVING TRUST 10-26-10",
+ "acreage": 4.78,
+ "assessedLand": 1903594,
+ "assessedImprovements": 908214,
+ "assessedTotal": 2811808,
+ "deedDoc": "2024/2025 series doc #132936",
+ "deedDocNumber": "132936",
+ "deedDate": "2024-05-28",
+ "address": "15111 SUMMIT TRAIL RD",
+ "livingArea": 3761,
+ "bedrooms": 4,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-10-00",
+ "lot": "LOT 10",
+ "owner": "KIM BRIAN&BROOKE",
+ "acreage": 4.51,
+ "assessedLand": 2122416,
+ "assessedImprovements": 1114656,
+ "assessedTotal": 3237072,
+ "deedDoc": "2024/2025 series doc #123602",
+ "deedDocNumber": "123602",
+ "deedDate": "2024-05-16",
+ "address": "15105 SUMMIT TRAIL RD",
+ "livingArea": 3967,
+ "bedrooms": 5,
+ "baths": 4.5,
+ "taxable": true
+ },
+ {
+ "apn": "314-870-11-00",
+ "lot": "LOT A",
+ "owner": "LYON ESTATES HOMEOWNERS ASSOCIATION",
+ "acreage": 0.54,
+ "assessedLand": 0,
+ "assessedImprovements": 0,
+ "assessedTotal": 0,
+ "deedDoc": "2024/2025 series doc #122433",
+ "deedDocNumber": "122433",
+ "deedDate": "2024-05-15",
+ "address": null,
+ "livingArea": null,
+ "bedrooms": null,
+ "baths": null,
+ "taxable": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/data/records.json b/data/records.json
index 7c579d0..03aaa3e 100644
--- a/data/records.json
+++ b/data/records.json
@@ -18,7 +18,8 @@
"category": "Deeds / Recorded Documents",
"items": [
{ "label": "Grantor/Grantee deed index", "value": "San Diego County Recorder (ARCC)", "detail": "Search recorded deeds, deeds of trust, easements, and maps under \"Dandeana Larchmont\" (grantee, ~2015 acquisition era) or by APN. Index is free to search; official copies are ordered from ARCC ($ per page).", "url": "https://arcc.sdcounty.ca.gov/Pages/grantorgrantee.aspx", "urlLabel": "ARCC grantor/grantee index search" },
- { "label": "Recorded final map (when filed)", "value": "TTM 16-005 → final tract map", "detail": "The approved tentative map converts to a recorded final map at ARCC before lots can be sold; none observed as recorded yet — watch this index.", "url": "https://www.sdarcc.gov/content/arcc/home/divisions/recorder-clerk.html", "urlLabel": "ARCC Recorder/Clerk division" }
+ { "label": "Final tract map — RECORDED", "value": "POWAY TCT NO 16-005 (Larchmont St) — on the county rolls", "detail": "The subdivision recorded and the original APNs were retired: the 10 residential lots renumbered to the 314-870-01 … 314-870-10 series (plus HOA Lots A/B). Marketed and built out as \"Lyon Estates\" by New Pointe Communities.", "url": "https://arcc.sdcounty.ca.gov/Pages/grantorgrantee.aspx", "urlLabel": "ARCC recorded-document index" },
+ { "label": "Buildout & sales — COMPLETE", "value": "All 10 homes built and sold to individual owners (deeds May 2024 – Dec 2025)", "detail": "Per the county parcel rolls: 3,500–3,967 sf homes, assessed $2.4M–$3.2M each. Open-space Lot A deeded to the Lyon Estates HOA May 15, 2024 (doc #122433) and 40.15-acre Lot B on April 4, 2025 (doc #086616). Full lot-by-lot detail in the Land Records panel.", "url": "https://www.sdarcc.gov/content/arcc/home/divisions/assessor/property-records.html", "urlLabel": "County assessor property records" }
]
},
{
diff --git a/data/timeline.json b/data/timeline.json
index b323619..b55bcc7 100644
--- a/data/timeline.json
+++ b/data/timeline.json
@@ -7,5 +7,8 @@
{ "date": "2018-03-20", "title": "City Council APPROVES TTM 16-005", "detail": "Poway City Council approves the Larchmont Street Subdivision tentative tract map — 10 lots, gated entry, ~59 acres preserved open space with public trails.", "url": "https://poway.org/AgendaCenter" },
{ "date": "2020-04-27", "title": "Opposition campaign on Instagram", "detail": "@inside_sustainability_socal posts against the 10-house development citing the creek ecosystem, calling for supporters to attend the May 5 City Council hearing and demanding the project be reduced to 2–3 rural residential units with a new Environmental Impact Report.", "url": "https://www.instagram.com/p/B_ehempJHbg/" },
{ "date": "2020-05-05", "title": "Council grants one-year map extension", "detail": "Despite the opposition campaign, the City Council unanimously approves a one-year extension of TTM 16-005 (reported by the San Diego Union-Tribune, May 7, 2020).", "url": "https://poway.org/AgendaCenter" },
- { "date": "2015-07-09", "title": "Dandeana Larchmont, LLC formed", "detail": "California LLC #201519410218 registered (Marina del Rey; manager/CEO Daniel Ginzburg) — the acquisition/development entity for the Poway site.", "url": "https://bizfileonline.sos.ca.gov/search/business" }
+ { "date": "2015-07-09", "title": "Dandeana Larchmont, LLC formed", "detail": "California LLC #201519410218 registered (Marina del Rey; manager/CEO Daniel Ginzburg) — the acquisition/development entity for the Poway site.", "url": "https://bizfileonline.sos.ca.gov/search/business" },
+ { "date": "2024-05-15", "title": "Final map recorded; first closings — \"Lyon Estates\"", "detail": "The tract records as POWAY TCT NO 16-005; open-space Lot A deeds to the Lyon Estates HOA (doc #122433) and the first homes close (Lots 9/10 deeds May 2024). Built by New Pointe Communities.", "url": "https://arcc.sdcounty.ca.gov/Pages/grantorgrantee.aspx" },
+ { "date": "2025-04-04", "title": "40-acre open space deeded to HOA", "detail": "Lot B (40.15 acres, the preserved open space at the heart of the 2016 trails controversy) records to the Lyon Estates Homeowners Association (doc #086616), tax-exempt/unassessed.", "url": "https://arcc.sdcounty.ca.gov/Pages/grantorgrantee.aspx" },
+ { "date": "2025-12-02", "title": "Final lot sales close out the tract", "detail": "Last individual-owner deeds record (Lot 8 Dec 2, 2025; Lot 2 Nov 21, 2025) — all 10 residential lots now held by private owners; buildout and sell-through complete.", "url": "https://arcc.sdcounty.ca.gov/Pages/grantorgrantee.aspx" }
]
diff --git a/public/index.html b/public/index.html
index d482c34..8529933 100644
--- a/public/index.html
+++ b/public/index.html
@@ -104,6 +104,10 @@ main { max-width:1200px; margin:0 auto; padding:22px 28px 60px; display:grid; gr
<div id="errors"></div>
<div id="feed"></div>
</section>
+ <section class="panel" style="margin-top:22px" id="p-parcels">
+ <h2>Land Records — Recorded Tract</h2>
+ <div class="body" id="parcels"></div>
+ </section>
<section class="panel" style="margin-top:22px" id="p-timeline">
<h2>Project Timeline</h2>
<div class="body" id="timeline"></div>
@@ -169,6 +173,31 @@ function renderRecords(groups) {
</div>`).join('') || '<div class="empty">No records loaded.</div>';
}
+function renderParcels(p) {
+ if (!p.lots || !p.lots.length) { $('#parcels').innerHTML = '<div class="empty">No parcel data pulled yet.</div>'; return; }
+ const money = n => n ? '$' + n.toLocaleString() : '—';
+ const rows = p.lots.map(l => `
+ <tr>
+ <td><b>${esc(l.lot)}</b><br><span style="color:var(--dim);font-size:11.5px">${esc(l.apn)}</span></td>
+ <td>${esc(l.owner)}<br><span style="color:var(--dim);font-size:11.5px">${esc(l.address || 'no address (open space)')}</span></td>
+ <td style="text-align:right">${l.acreage} ac</td>
+ <td style="text-align:right">${money(l.assessedTotal)}</td>
+ <td>${l.deedDate ? `<span title="Recorded doc #${esc(l.deedDocNumber)}">${esc(l.deedDate)}</span><br><span style="color:var(--dim);font-size:11.5px">#${esc(l.deedDocNumber)}</span>` : '—'}</td>
+ <td>${l.livingArea ? `${l.livingArea.toLocaleString()} sf · ${l.bedrooms}bd/${l.baths}ba` : '<span style="color:var(--dim)">open space</span>'}</td>
+ </tr>`).join('');
+ $('#parcels').innerHTML = `
+ <div style="font-size:13px;margin-bottom:8px">${esc(p.tract)}</div>
+ <div style="overflow-x:auto"><table style="width:100%;border-collapse:collapse;font-size:12.5px">
+ <thead><tr style="color:var(--dim);text-transform:uppercase;font-size:10.5px;letter-spacing:.08em;text-align:left">
+ <th style="padding:6px 8px">Lot / APN</th><th style="padding:6px 8px">Owner / Situs</th><th style="padding:6px 8px;text-align:right">Acres</th><th style="padding:6px 8px;text-align:right">Assessed</th><th style="padding:6px 8px">Deed recorded</th><th style="padding:6px 8px">Improvements</th>
+ </tr></thead>
+ <tbody>${rows}</tbody>
+ </table></div>
+ <div style="color:var(--dim);font-size:11.5px;margin-top:8px" title="${esc(p.pulledAt)}">Source: ${esc(p.source)} · pulled ${esc(fmt(p.pulledAt))} · refreshes daily</div>`;
+ // rows get border styling via JS to keep CSS compact
+ document.querySelectorAll('#parcels tbody td').forEach(td => { td.style.borderTop = '1px solid var(--line)'; td.style.padding = '7px 8px'; td.style.verticalAlign = 'top'; });
+}
+
function renderDocs(d) {
$('#docs').innerHTML = d.map(x => `
<div class="doc">
@@ -223,8 +252,8 @@ $('#btnRefresh').onclick = async () => {
};
(async () => {
- const [proj, tl, docs, recs] = await Promise.all([j('/api/project'), j('/api/timeline'), j('/api/documents'), j('/api/records')]);
- renderDossier(proj); renderTimeline(tl); renderDocs(docs); renderRecords(recs);
+ const [proj, tl, docs, recs, parc] = await Promise.all([j('/api/project'), j('/api/timeline'), j('/api/documents'), j('/api/records'), j('/api/parcels')]);
+ renderDossier(proj); renderTimeline(tl); renderDocs(docs); renderRecords(recs); renderParcels(parc);
await loadItems();
})();
</script>
diff --git a/scripts/pull-parcels.js b/scripts/pull-parcels.js
new file mode 100644
index 0000000..7f3e9bb
--- /dev/null
+++ b/scripts/pull-parcels.js
@@ -0,0 +1,58 @@
+// Pulls the recorded tract's parcel records (owners, assessed values, deed refs)
+// from San Diego County's public ARCC parcel layer into data/parcels.json. $0.
+const fs = require('fs');
+const path = require('path');
+
+const LAYER = 'https://gis-public.sandiegocounty.gov/arcgis/rest/services/ARCC/apprmapr/MapServer/2/query';
+const WHERE = "SUBNAME LIKE 'POWAY TCT NO 16-005%'";
+const FIELDS = 'APN,OWN_NAME1,OWN_NAME2,LEGLDESC,ACREAGE,ASR_LAND,ASR_IMPR,ASR_TOTAL,DOCNMBR,DOCDATE,TAXSTAT,SITUS_ADDRESS,SITUS_STREET,SITUS_SUFFIX,TOTAL_LVG_AREA,BEDROOMS,BATHS';
+
+function fmtDocDate(mmddyy) {
+ if (!mmddyy || mmddyy.length !== 6) return null;
+ const [mm, dd, yy] = [mmddyy.slice(0, 2), mmddyy.slice(2, 4), mmddyy.slice(4, 6)];
+ return `20${yy}-${mm}-${dd}`;
+}
+
+async function pullParcels(DATA) {
+ const url = `${LAYER}?where=${encodeURIComponent(WHERE)}&outFields=${FIELDS}&returnGeometry=false&orderByFields=APN&f=json`;
+ const r = await fetch(url, { headers: { 'User-Agent': 'DandeanaHub/1.0' } });
+ if (!r.ok) throw new Error(`county GIS HTTP ${r.status}`);
+ const j = await r.json();
+ if (j.error) throw new Error(`county GIS error: ${JSON.stringify(j.error)}`);
+ const lots = (j.features || []).map(f => {
+ const a = f.attributes;
+ const lot = (a.LEGLDESC || '').replace(/\\.*/, '').trim();
+ return {
+ apn: a.APN.replace(/^(\d{3})(\d{3})(\d{2})(\d{2})$/, '$1-$2-$3-$4'),
+ lot,
+ owner: [a.OWN_NAME1, a.OWN_NAME2].filter(Boolean).join(' / ').trim(),
+ acreage: a.ACREAGE,
+ assessedLand: a.ASR_LAND,
+ assessedImprovements: a.ASR_IMPR,
+ assessedTotal: a.ASR_TOTAL || (a.ASR_LAND + a.ASR_IMPR),
+ deedDoc: a.DOCNMBR ? `2024/2025 series doc #${a.DOCNMBR}` : null,
+ deedDocNumber: a.DOCNMBR || null,
+ deedDate: fmtDocDate(a.DOCDATE),
+ address: a.SITUS_ADDRESS ? `${a.SITUS_ADDRESS} ${a.SITUS_STREET || ''} ${a.SITUS_SUFFIX || ''}`.replace(/\s+/g, ' ').trim() : null,
+ livingArea: a.TOTAL_LVG_AREA || null,
+ bedrooms: a.BEDROOMS ? parseInt(a.BEDROOMS, 10) : null,
+ baths: a.BATHS ? parseInt(a.BATHS, 10) / 10 : null,
+ taxable: a.TAXSTAT === 'T',
+ };
+ });
+ const out = {
+ pulledAt: new Date().toISOString(),
+ source: 'San Diego County ARCC public parcel layer (gis-public.sandiegocounty.gov)',
+ tract: 'POWAY TCT NO 16-005 (Larchmont St) — marketed as "Lyon Estates" by New Pointe Communities',
+ lots,
+ };
+ fs.writeFileSync(path.join(DATA, 'parcels.json'), JSON.stringify(out, null, 2));
+ console.log(`parcels: ${lots.length} lots written`);
+ return out;
+}
+
+module.exports = { pullParcels };
+
+if (require.main === module) {
+ pullParcels(path.join(__dirname, '..', 'data')).catch(e => { console.error(e); process.exit(1); });
+}
diff --git a/server.js b/server.js
index 68e5cd0..30598d9 100644
--- a/server.js
+++ b/server.js
@@ -4,6 +4,7 @@ const express = require('express');
const fs = require('fs');
const path = require('path');
const { runRefresh } = require('./scripts/refresh');
+const { pullParcels } = require('./scripts/pull-parcels');
const PORT = process.env.PORT || 9917;
const DATA = path.join(__dirname, 'data');
@@ -44,6 +45,7 @@ app.get('/api/project', (_req, res) => res.json(readJson('project.json', {})));
app.get('/api/timeline', (_req, res) => res.json(readJson('timeline.json', [])));
app.get('/api/documents', (_req, res) => res.json(readJson('documents.json', [])));
app.get('/api/records', (_req, res) => res.json(readJson('records.json', [])));
+app.get('/api/parcels', (_req, res) => res.json(readJson('parcels.json', { lots: [] })));
app.get('/api/items', (_req, res) => {
const meta = readJson('refresh-meta.json', {});
res.json({ lastRefresh: meta.lastRefresh || null, items: readItems() });
@@ -65,5 +67,9 @@ app.listen(PORT, '127.0.0.1', () => console.log(`dandeana-hub listening on 127.0
// Daily self-refresh so the hub stays current with zero external schedulers.
const DAY = 24 * 60 * 60 * 1000;
-setInterval(() => { runRefresh(DATA).catch(e => console.error('scheduled refresh failed:', e.message)); }, DAY);
-setTimeout(() => { runRefresh(DATA).catch(e => console.error('startup refresh failed:', e.message)); }, 15 * 1000);
+function dailyPull() {
+ runRefresh(DATA).catch(e => console.error('scheduled refresh failed:', e.message));
+ pullParcels(DATA).catch(e => console.error('parcel pull failed:', e.message));
+}
+setInterval(dailyPull, DAY);
+setTimeout(dailyPull, 15 * 1000);
← 5fe0295 add Public Records panel — LLC/SOS entity, assessor APNs, de
·
back to Dandeana Hub
·
auto-save: 2026-07-22T12:44:11 (2 files) — data/parcels.json adc8144 →