Use Zillow parcel hints for CAD lookup

This commit is contained in:
2026-03-28 03:55:56 -05:00
parent ece8fc548f
commit b77134ced5
11 changed files with 438 additions and 18 deletions

View File

@@ -175,6 +175,16 @@ function buildCadSearchKeywords(address: string, year: number): string {
return `${collapseWhitespace(address)} Year:${year}`.trim();
}
function formatNuecesGeographicId(parcelId: string | null | undefined): string | null {
const normalized = collapseWhitespace(parcelId).replace(/[^0-9]/g, "");
if (!normalized) return null;
if (normalized.length <= 4) return normalized;
if (normalized.length <= 8) {
return `${normalized.slice(0, 4)}-${normalized.slice(4)}`;
}
return `${normalized.slice(0, 4)}-${normalized.slice(4, 8)}-${normalized.slice(8)}`;
}
function parseAddressForCadSearch(address: string): {
rawAddress: string;
streetNumber: string | null;
@@ -327,6 +337,7 @@ function pickBestCadResult(
async function enrichNuecesCadPropertyDetails(
address: string,
appraisalDistrictWebsite: string,
parcelId: string | null | undefined,
fetchText: FetchLike
): Promise<PropertyDetailsResolution | null> {
const parsedAddress = parseAddressForCadSearch(address);
@@ -341,10 +352,12 @@ async function enrichNuecesCadPropertyDetails(
if (!searchToken) return null;
const searchYear = parseCurrentYearFromSearchHome(searchHomeHtml);
const formattedGeographicId = formatNuecesGeographicId(parcelId);
const searchKeywords =
parsedAddress.streetNumber && parsedAddress.streetName
formattedGeographicId ||
(parsedAddress.streetNumber && parsedAddress.streetName
? `StreetNumber:${parsedAddress.streetNumber} StreetName:"${parsedAddress.streetName}"`
: buildCadSearchKeywords(address, searchYear);
: buildCadSearchKeywords(address, searchYear));
const fetchSearchPage = async (page: number): Promise<any> => {
const searchResultsUrl = `${normalizedPropertySearchUrl}/search/SearchResults?keywords=${encodeURIComponent(searchKeywords)}`;
@@ -478,6 +491,7 @@ async function enrichNuecesCadPropertyDetails(
async function tryEnrichPropertyDetails(
address: string,
parcelId: string | null | undefined,
appraisalDistrictWebsite: string | null,
fetchText: FetchLike
): Promise<PropertyDetailsResolution | null> {
@@ -487,7 +501,7 @@ async function tryEnrichPropertyDetails(
const normalizedWebsite = normalizeUrl(website).toLowerCase();
try {
if (normalizedWebsite.includes("nuecescad.net") || normalizedWebsite.includes("ncadistrict.com")) {
return await enrichNuecesCadPropertyDetails(address, website, fetchText);
return await enrichNuecesCadPropertyDetails(address, website, parcelId, fetchText);
}
} catch {
return null;
@@ -729,6 +743,7 @@ export async function resolvePublicRecords(
taxAssessorCollector = offices.taxAssessorCollector;
propertyDetails = await tryEnrichPropertyDetails(
address,
options.parcelId,
typeof offices.appraisalDistrict?.Website === "string"
? offices.appraisalDistrict.Website
: null,