← back to Commercialrealestate
docs/data-integration-plan.md
80 lines
# Data Integration Plan — assumable-loan signal & credentialed sources
LA County CRE control panel. This plan covers the four credentialed data
sources that sharpen the **assumable FHA/VA loan** signal and the broader warrantability / valuation work,
plus the recommended sequencing.
## The assumable-loan feature, today (shipped)
FHA & VA loans are **assumable** — a qualified buyer can take over the seller's existing low-rate note
instead of originating a new loan at today's rate. A listing likely carrying a sub-4% assumable FHA/VA
loan is a notable signal worth flagging.
We ship a transparent **heuristic** now (`scripts/assumable-heuristic.js` → `cre.assumable_estimate`):
- **Inputs we already have ($0, local):** property type (condo/SFR are FHA/VA-eligible; commercial isn't),
price band (LA County 2024 FHA ceiling ≈ **$1,149,825**; VA uncapped but jumbo-VA rare), and purchase era
(when a listing's address matches `closed_sale`, the sale year dates the loan; 2020-2022 → sub-4% era).
- **Rate proxy:** `assumable_rate_proxy` maps recording year → an **approximate** historical-average 30yr
fixed rate (2016-2026), labelled approximate everywhere.
- **Output per property:** `{ assumable_likelihood: low|medium|high, est_assumable_rate, est_sale_year,
basis, confidence:'heuristic — verify in title records', signals }`.
**Honest labeling (hard rule):** every estimate is a screening signal, not a title-verified fact. The
heuristic CAN misfire (a 2020-2022 sale may have been cash/conventional, not FHA/VA). It exists to
**prioritize calls**, never to assert an assumption.
**Known limitation (recorded dissent, in data):** the for-sale feed and the recently-sold feed barely
overlap (~6 address matches across 10,392 properties), so the era signal is sparse today — most properties
score on price-band only. This is exactly the gap **title records** close: title carries the recorded
deed-of-trust date for *every* property, not just ones that recently re-sold.
---
## Source 1 — TITLE RECORDS (adapter: `scripts/sources/title-records.js`) ★ recommended first
| | |
|---|---|
| **Data it provides** | The recorded **deed of trust** per property: lender, loan **type** (FHA / VA / Conventional), **recording date**, original amount. Rate is inferable from program + date. This is the **authoritative** assumable-loan signal. |
| **Access / credential needed** | A title-company recorded-document login — `TITLE_RECORDS_API_KEY` (API key or session token) for one of **TitlePro247 / Property360 / DataTrace / ResWare / SoftPro**, plus `TITLE_RECORDS_PROVIDER` (which system) and `TITLE_RECORDS_BASE_URL` (API base). Steve can likely get a login. |
| **Integration design** | Adapter exports `getRecordedLoans({address,city,zip}) → { available, matched, loans[] }`. The heuristic calls it **first** for every property; on an FHA/VA recorded loan it flips the estimate to `confidence:'title-verified'` (`basis:'title'`). Uncredentialed → `{available:false}` and the heuristic runs. **Zero rework** when the login lands — only the provider response mapping in the marked INTEGRATION POINT. |
| **Why first** | Highest leverage: converts the whole assumable feature from screening-heuristic to ground truth, and closes the sparse-era gap above. Steve can plausibly get the login. |
## Source 2 — APPRAISAL PANEL (adapter: `scripts/sources/appraisal-panel.js`)
| | |
|---|---|
| **Data it provides** | Near-guaranteed **supportable value** on LA-area properties — the gold standard vs our Census-rent / closed-sale estimate. |
| **Access / credential needed** | `APPRAISAL_PANEL_API_KEY` + `APPRAISAL_PANEL_BASE_URL`, OR confirmation of how Steve pulls values (manual portal vs API). Steve has **direct access**. |
| **Integration design** | `getSupportableValue({address,city,zip}) → { available, matched, value, confidence, asOf }`. Where present, replaces the Census/closed-sale value estimate on a card and relabels it "supportable (appraisal panel)". |
| **Sequencing** | Second. Steve already has access (low friction), and it upgrades valuation across the whole grid — but it's value, not the assumable signal, so it follows title. |
## Source 3 — FNMA Condo Project Manager (CPM) (adapter: `scripts/sources/fnma-cpm.js`)
| | |
|---|---|
| **Data it provides** | Per-complex Fannie Mae condo-project **approval / rejection / conditions** — beyond our HUD FHA-approved list (FHA only). Authoritative warrantability for the `standard-condo` segment. |
| **Access / credential needed** | `FNMA_CPM_API_KEY` (lender CPM credential / session token, or a marker that lookups are manual + exported) and optional `FNMA_CPM_BASE_URL`. Credentialed and **partly manual** (lender portal, no public API). |
| **Integration design** | `getProjectStatus({project,address,city,zip}) → { available, matched, status, date, conditions }`. Best fed by a periodic CPM **export** this adapter reads, keyed by project name + zip; upgrades condo warrantability from FHA-proxy to Fannie-authoritative. |
| **Sequencing** | Third. Highest friction (manual/lender-gated, no API) and narrower (condos only). |
## Source 4 — (in place) HUD FHA-approved condo list
Already loaded (`cre.fha_condo`, 2,661 rows) as the warrantability **proxy**. CPM (Source 3) supersedes it
where available; until then it stays the labeled FHA-only proxy.
---
## Recommended sequencing (highest leverage first)
1. **TITLE RECORDS** — turns the assumable feature into ground truth and closes the sparse-era gap. Plausibly obtainable. **Light this up first.**
2. **APPRAISAL PANEL** — Steve already has access; upgrades valuation grid-wide. Low friction.
3. **FNMA CPM** — narrower (condos) and partly manual; do after the two above.
All four adapters share one contract: read credential from a config slot (env / `.env`), return
`{available:false, needs:'<exact credential>'}` until configured, and expose a fixed return shape so the
moment a login is dropped in it plugs in with zero caller rework.
**Cost:** the assumable heuristic and all adapter scaffolding are **$0 (local)**. The credentialed
integrations themselves carry whatever per-lookup cost the provider charges — surfaced when wired.