[object Object]

← back to Homesonspec

collectors: add Mattamy Homes — cracked the 'bucket-D' national via Sitecore JSS feed

5c09c6903fb35a437603ce3ff036cad595cbb262 · 2026-07-29 09:13:58 -0700 · Steve Abrams

Prior recon marked Mattamy bucket-D-hard (map feed not isolated). Wrong: its Sitecore JSS layout API
(GET /sitecore/api/layout/render/jss?item=/search-data&sc_apikey={anon-public-key}&market=<State>&IsState=1)
returns a whole state's QMI inventory per call — anonymous key (not a credential), honest-UA, no anti-bot,
robots-allowed. Emits qmiCards (per-home), ignores planCards/communityCards (aggregates). 4 US states
(AZ/FL/NC/TX). DB-verified: 767 homes, 100% price/beds/baths/sqft/geo, 0 bad-bbox pins, 767 distinct
addresses. New builder -> created Builder + SourceRegistry (FK). Every-sweep in the loop. Built via
isolated subagent + serial gated integration. (Richmond American: reachable but Blazor-SSR -> needs a
shared browser RenderFetcher, deferred w/ RECON.md.)

Files touched

Diff

commit 5c09c6903fb35a437603ce3ff036cad595cbb262
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jul 29 09:13:58 2026 -0700

    collectors: add Mattamy Homes — cracked the 'bucket-D' national via Sitecore JSS feed
    
    Prior recon marked Mattamy bucket-D-hard (map feed not isolated). Wrong: its Sitecore JSS layout API
    (GET /sitecore/api/layout/render/jss?item=/search-data&sc_apikey={anon-public-key}&market=<State>&IsState=1)
    returns a whole state's QMI inventory per call — anonymous key (not a credential), honest-UA, no anti-bot,
    robots-allowed. Emits qmiCards (per-home), ignores planCards/communityCards (aggregates). 4 US states
    (AZ/FL/NC/TX). DB-verified: 767 homes, 100% price/beds/baths/sqft/geo, 0 bad-bbox pins, 767 distinct
    addresses. New builder -> created Builder + SourceRegistry (FK). Every-sweep in the loop. Built via
    isolated subagent + serial gated integration. (Richmond American: reachable but Blazor-SSR -> needs a
    shared browser RenderFetcher, deferred w/ RECON.md.)
---
 apps/workers/package.json |  3 ++-
 apps/workers/src/cli.ts   |  2 ++
 pnpm-lock.yaml            | 25 +++++++++++++++++++++++++
 scripts/build-loop.sh     |  5 ++++-
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/apps/workers/package.json b/apps/workers/package.json
index 4a1300fc..906c8375 100644
--- a/apps/workers/package.json
+++ b/apps/workers/package.json
@@ -45,7 +45,8 @@
     "@homesonspec/collector-holt-homes": "workspace:*",
     "@homesonspec/collector-fischer-homes": "workspace:*",
     "@homesonspec/collector-fulton-homes": "workspace:*",
-    "@homesonspec/collector-gl-homes": "workspace:*"
+    "@homesonspec/collector-gl-homes": "workspace:*",
+    "@homesonspec/collector-mattamy": "workspace:*"
   },
   "devDependencies": {
     "tsx": "^4.19.2",
diff --git a/apps/workers/src/cli.ts b/apps/workers/src/cli.ts
index 582ac70b..1d06a2d6 100644
--- a/apps/workers/src/cli.ts
+++ b/apps/workers/src/cli.ts
@@ -26,6 +26,7 @@ import { holtHomesAdapter } from "@homesonspec/collector-holt-homes";
 import { fischerHomesAdapter } from "@homesonspec/collector-fischer-homes";
 import { fultonHomesAdapter } from "@homesonspec/collector-fulton-homes";
 import { glHomesAdapter } from "@homesonspec/collector-gl-homes";
+import { mattamyAdapter } from "@homesonspec/collector-mattamy";
 import { runPipeline } from "./pipeline";
 import { recordSourceRun } from "./verify";
 
@@ -61,6 +62,7 @@ const ADAPTERS = {
   [fischerHomesAdapter.key]: fischerHomesAdapter,
   [fultonHomesAdapter.key]: fultonHomesAdapter,
   [glHomesAdapter.key]: glHomesAdapter,
+  [mattamyAdapter.key]: mattamyAdapter,
 };
 
 async function main() {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f7808598..b001946e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -196,6 +196,9 @@ importers:
       '@homesonspec/collector-lgi-homes':
         specifier: workspace:*
         version: link:../../collectors/lgi-homes
+      '@homesonspec/collector-mattamy':
+        specifier: workspace:*
+        version: link:../../collectors/mattamy
       '@homesonspec/collector-meridian-homes':
         specifier: workspace:*
         version: link:../../collectors/meridian-homes
@@ -676,6 +679,28 @@ importers:
         specifier: ^4.0.0
         version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
 
+  collectors/mattamy:
+    dependencies:
+      '@homesonspec/collectors-common':
+        specifier: workspace:*
+        version: link:../common
+      '@homesonspec/schemas':
+        specifier: workspace:*
+        version: link:../../packages/schemas
+      '@homesonspec/shared':
+        specifier: workspace:*
+        version: link:../../packages/shared
+    devDependencies:
+      '@types/node':
+        specifier: ^22.10.5
+        version: 22.20.1
+      typescript:
+        specifier: ^5.7.2
+        version: 5.9.3
+      vitest:
+        specifier: ^4.0.0
+        version: 4.1.10(@types/node@22.20.1)(vite@8.1.5(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.1))
+
   collectors/meridian-homes:
     dependencies:
       '@homesonspec/collectors-common':
diff --git a/scripts/build-loop.sh b/scripts/build-loop.sh
index 36c0a7b8..a3a44ba3 100644
--- a/scripts/build-loop.sh
+++ b/scripts/build-loop.sh
@@ -133,6 +133,8 @@ sweep_fischer() { FISCHER_PAGE_LIMIT=20  CLI fischer-homes-site     | sed "s/^/
 # Extracts own-home price/beds/sqft + geo from each page's ld+json (fixed 2026-07-29). Honest-null
 # where a page lacks its own home in ld+json.
 sweep_dreamfinders() { DREAMFINDERS_PAGE_LIMIT=600 CLI dream-finders-site | sed "s/^/  df  NATIONAL: /"; }
+# Mattamy = Sitecore JSS layout API, 4 fast state GETs (AZ/FL/NC/TX, ~767 homes) — every sweep.
+sweep_mattamy() { MATTAMY_PAGE_LIMIT=10 CLI mattamy-site | sed "s/^/  mat NATIONAL: /"; }
 
 # metro-iterating adapters (footprint = METROS, not states) — scoped to served metros only
 # (Cody WAF-lesson from the start). Ashton Woods publishes per-metro quick-move-in homes.
@@ -152,7 +154,7 @@ while pgrep -f "cli.ts --adapter" 2>/dev/null | grep -qv "^$$\$"; do sleep 20; d
 # a transient failure shouldn't permanently sideline a chosen builder, and genuine breakage is
 # surfaced by the dashboard's per-source failed_runs + the freshness canary (not silent). To
 # retire a builder, remove it from THIS list (don't rely on auto-pause surviving a restart).
-for k in dr-horton-site kb-home-site pultegroup-site tri-pointe-site lennar-site toll-brothers-site david-weekley-site taylor-morrison-site ashton-woods-site discovery-homes-site meritage-homes-site ryan-homes-site highland-homes-site landsea-homes-site shea-homes-site lgi-homes-site century-communities-site beazer-site drees-homes-site perry-homes-site brookfield-site holt-homes-site fulton-homes-site gl-homes-site fischer-homes-site dream-finders-site; do
+for k in dr-horton-site kb-home-site pultegroup-site tri-pointe-site lennar-site toll-brothers-site david-weekley-site taylor-morrison-site ashton-woods-site discovery-homes-site meritage-homes-site ryan-homes-site highland-homes-site landsea-homes-site shea-homes-site lgi-homes-site century-communities-site beazer-site drees-homes-site perry-homes-site brookfield-site holt-homes-site fulton-homes-site gl-homes-site fischer-homes-site dream-finders-site mattamy-site; do
   PSQL "update \"SourceRegistry\" set active=true, health='HEALTHY', \"consecutiveFailures\"=0 where key='$k';" >/dev/null
 done
 
@@ -172,6 +174,7 @@ while [ ! -f "$STOP" ] && [ "$sweep" -lt "$MAX_SWEEPS" ]; do
   sweep_shea        &
   sweep_perry       &
   sweep_brookfield  &
+  sweep_mattamy     &
   sweep_fulton      &
   sweep_gl          &
   # heavy crawlers: throttled to every 4th sweep (hundreds of GETs each, slow-changing data)

← 718fc16b auto-save: 2026-07-29T09:07:36 (1 files) — collectors/mattam  ·  back to Homesonspec  ·  auto-save: 2026-07-29T09:37:47 (1 files) — collectors/richmo 63d56d74 →