[object Object]

← back to Homesonspec

add Legacy Alabama CPG collector

99a991d95e91d0b3c5b2f0251f6929129ecf245b · 2026-08-30 11:13:44 -0700 · Steve

Files touched

Diff

commit 99a991d95e91d0b3c5b2f0251f6929129ecf245b
Author: Steve <steve@designerwallcoverings.com>
Date:   Sun Aug 30 11:13:44 2026 -0700

    add Legacy Alabama CPG collector
---
 apps/workers/package.json                        |   3 +-
 apps/workers/src/cli.ts                          |   2 +
 collectors/BUILDERS.md                           |   6 +
 collectors/legacy-al/.gitignore                  |   8 +
 collectors/legacy-al/fixtures/homes/_urls.tsv    |   8 +
 collectors/legacy-al/fixtures/homes/home-01.html |  12 +
 collectors/legacy-al/fixtures/homes/home-02.html |  10 +
 collectors/legacy-al/fixtures/homes/home-03.html |  10 +
 collectors/legacy-al/fixtures/homes/home-04.html |  10 +
 collectors/legacy-al/fixtures/homes/home-05.html |   9 +
 collectors/legacy-al/fixtures/homes/home-06.html |  10 +
 collectors/legacy-al/fixtures/homes/home-07.html |   9 +
 collectors/legacy-al/fixtures/homes/home-08.html |  10 +
 collectors/legacy-al/package.json                |  15 +
 collectors/legacy-al/src/index.ts                | 408 +++++++++++++++++++++++
 collectors/legacy-al/src/selftest.test.ts        |  92 +++++
 collectors/legacy-al/tsconfig.json               |   1 +
 packages/database/prisma/seed-cpg-builders.ts    |  10 +-
 verification/TK-10487-legacy-al-e2e-proof.json   |  52 +++
 19 files changed, 683 insertions(+), 2 deletions(-)

diff --git a/apps/workers/package.json b/apps/workers/package.json
index eb7cb7c4..24d32b85 100644
--- a/apps/workers/package.json
+++ b/apps/workers/package.json
@@ -56,7 +56,8 @@
     "@homesonspec/collector-summit-homes-kc": "workspace:*",
     "@homesonspec/collector-mungo-homes": "workspace:*",
     "@homesonspec/collector-chafin-communities": "workspace:*",
-    "@homesonspec/collector-harris-doyle": "workspace:*"
+    "@homesonspec/collector-harris-doyle": "workspace:*",
+    "@homesonspec/collector-legacy-al": "workspace:*"
   },
   "devDependencies": {
     "tsx": "^4.19.2",
diff --git a/apps/workers/src/cli.ts b/apps/workers/src/cli.ts
index 105ee2e9..8bf5f0a1 100644
--- a/apps/workers/src/cli.ts
+++ b/apps/workers/src/cli.ts
@@ -37,6 +37,7 @@ import { summitHomesKcAdapter } from "@homesonspec/collector-summit-homes-kc";
 import { mungoHomesAdapter } from "@homesonspec/collector-mungo-homes";
 import { chafinCommunitiesAdapter } from "@homesonspec/collector-chafin-communities";
 import { harrisDoyleAdapter } from "@homesonspec/collector-harris-doyle";
+import { legacyAlAdapter } from "@homesonspec/collector-legacy-al";
 import { runPipeline } from "./pipeline";
 import { recordSourceRun } from "./verify";
 
@@ -83,6 +84,7 @@ const ADAPTERS = {
   [mungoHomesAdapter.key]: mungoHomesAdapter,
   [chafinCommunitiesAdapter.key]: chafinCommunitiesAdapter,
   [harrisDoyleAdapter.key]: harrisDoyleAdapter,
+  [legacyAlAdapter.key]: legacyAlAdapter,
 };
 
 async function main() {
diff --git a/collectors/BUILDERS.md b/collectors/BUILDERS.md
index 0a6734d8..9470c450 100644
--- a/collectors/BUILDERS.md
+++ b/collectors/BUILDERS.md
@@ -220,3 +220,9 @@ and DNS remain explicitly gated and were not performed.
 Harris Doyle is now fixture-backed and locally registered. Fourteen AL/FL detail fixtures produce
 distinct addresses and builder inventory IDs with complete core facts; status comes only from the
 explicit first-party `dataLayer.pageType` signal, while absent geo/stories remain honest nulls.
+
+Legacy Homes Alabama is now fixture-backed and locally registered. Eight North Alabama detail-page
+fixtures produce eight distinct addresses and builder inventory IDs from first-party Product JSON-LD;
+primary DetailOverview markup supplies beds/baths/sqft and explicitly published plan/story facts.
+Missing price/plan/stories/garage/lot/construction status remain honest nulls. Seed execution, ingest,
+activation, deploy, DNS, and remote push were not performed.
diff --git a/collectors/legacy-al/.gitignore b/collectors/legacy-al/.gitignore
new file mode 100644
index 00000000..3ffb8445
--- /dev/null
+++ b/collectors/legacy-al/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/collectors/legacy-al/fixtures/homes/_urls.tsv b/collectors/legacy-al/fixtures/homes/_urls.tsv
new file mode 100644
index 00000000..714a8395
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/_urls.tsv
@@ -0,0 +1,8 @@
+home-01.html	https://legacyhomesal.com/homes/harvest-al/abbington/106-virtue-way
+home-02.html	https://legacyhomesal.com/homes/harvest-al/riverstone-at-monrovia/203-allegro-circle
+home-03.html	https://legacyhomesal.com/homes/meridianville-al/colonial-pointe-n/104-speck-circle
+home-04.html	https://legacyhomesal.com/homes/athens-al/boardwalk-n/17367-chelsea-street
+home-05.html	https://legacyhomesal.com/homes/hazel-green-al/townsend-farms/139-hillis-lane
+home-06.html	https://legacyhomesal.com/homes/hunstville-al/trailhead-n/1610-calistoga-circle
+home-07.html	https://legacyhomesal.com/homes/new-market-al/bellview-n/173-saddle-street
+home-08.html	https://legacyhomesal.com/homes/harvest-al/charleston/28115-caperton-drive
diff --git a/collectors/legacy-al/fixtures/homes/home-01.html b/collectors/legacy-al/fixtures/homes/home-01.html
new file mode 100644
index 00000000..4fc41745
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-01.html
@@ -0,0 +1,12 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"106 Virtue Way Harvest, AL, 35749","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"106 Virtue Way","postalCode":"35749","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/harvest-al/abbington/106-virtue-way","mainEntityOfPage":"https://www.legacyhomesal.com/homes/harvest-al/abbington/106-virtue-way","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Abbington","description":"Welcome to Harvest!\nLegacy Homes is now offering beautiful, full brick homes on large, private home sites in Abbington! Enjoy the peaceful setting of living in a new home with stunning amenities and a lot of space! With convenient access to Highway 53 and Research Park Blvd, Abbington is minutes away from the Redstone Arsenal, and top employers like Dynetics, Toyota, Polaris, and more.  The highly-acclaimed Bridgestreet shopping center is only 9 miles away and the Publix Supermarket at Harvest Square is only 1.8 miles away. \nHomes for sale in Abbington Liberty Series range from 1,556 square feet to 4,001 square feet and feature 3-5 bedrooms with two-car garages. \nBuild Your Legacy.®","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"106 Virtue Way","postalCode":"35749","@type":"PostalAddress"},"geo":{"@type":"GeoCoordinates","latitude":34.859767,"longitude":-86.730233}},"image":"https://s3.amazonaws.com/buildercloud/c0c3db269bae6efa14abcc3bfde5c34c.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.859767,"longitude":-86.730233},"offers":[{"@type":"Offer","priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"productId":"64e371c74db0486a73410397","sku":"64e371c74db0486a73410397"}</script>
+<li class="DetailOverview_listItem" data-reactid="557"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="558"/><span class="DetailOverview_listItemValue" data-reactid="559">4</span><span class="DetailOverview_listItemLabel" data-reactid="560">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="561"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="562"/><span class="DetailOverview_listItemValue" data-reactid="563">2</span><span class="DetailOverview_listItemLabel" data-reactid="564">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="565"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="566"/><span class="DetailOverview_listItemValue" data-reactid="567">1</span><span class="DetailOverview_listItemLabel" data-reactid="568">Half Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="569"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="570"/><span class="DetailOverview_listItemValue" data-reactid="571">3,670</span><span class="DetailOverview_listItemLabel" data-reactid="572">Sq Ft</span></li>
+<li class="DetailOverview_listItem" data-reactid="573"><span class="DetailOverview_listItemValue" data-reactid="574">2</span><span class="DetailOverview_listItemLabel" data-reactid="575">Stories</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="577"><!-- react-text: 578 -->Community: <!-- /react-text --><a class="" href="/communities/harvest-al/abbington" data-reactid="579">Abbington</a></span>
+<span class="DetailOverview_sectionItem" data-reactid="580"><!-- react-text: 581 -->Floor Plan: <!-- /react-text --><a class="" href="/plan/the-shelburne" data-reactid="582">The Shelburne</a></span>
+<a href="tel:2564793731" data-reactid="604">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-02.html b/collectors/legacy-al/fixtures/homes/home-02.html
new file mode 100644
index 00000000..1f77f4cf
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-02.html
@@ -0,0 +1,10 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"203 Allegro Circle Harvest, AL, 35749","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"203 Allegro Circle","postalCode":"35749","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/harvest-al/riverstone-at-monrovia/203-allegro-circle","mainEntityOfPage":"https://www.legacyhomesal.com/homes/harvest-al/riverstone-at-monrovia/203-allegro-circle","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Riverstone At Monrovia","description":"Welcome to Harvest! Riverstone at Monrovia is located nearby the popular and growing area of Clift Farms with quick access to schools and local favorites like Village of Providence and MidCity District. This community will have our Liberty Series homes with craftsman full-brick exteriors, open concept interiors and loaded with amenities! Call today to learn how you can Build Your Legacy.® in Harvest, AL.","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"201 Allegro Circle","postalCode":"35749","@type":"PostalAddress"},"geo":{"@type":"GeoCoordinates","latitude":34.781966617463,"longitude":-86.761994115056}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21921774/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.780914,"longitude":-86.761627},"offers":[{"@type":"Offer","price":432900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"MOVE-IN READY! FORMER MODEL HOME NOW FOR SALE! The Raleigh plan offers 4 BEDROOMS PLUS an OFFICE AND a BONUS room! It has a nice open layout featuring our lifestyle triangle with plenty of space for entertaining. Standard features throughout the home include granite counters & stainless-steel appliances in the kitchen, smooth ceilings, LVP throughout the main living spaces, covered back porch, & much more. Come check out the BRAND-NEW RIVERSTONE community which features large CUL-DE-SAC lots! ONLY 5 Minutes from Clift Farms which features amazing Restaurants, 5 Minutes from Madison Hospital, & 10 Minutes from Village of Providence! 100% FINANCING available!","productId":"664f95764db048034ff6edc8","sku":"664f95764db048034ff6edc8"}</script>
+<li class="DetailOverview_listItem" data-reactid="455"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="456"/><span class="DetailOverview_listItemValue" data-reactid="457">4</span><span class="DetailOverview_listItemLabel" data-reactid="458">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="459"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="460"/><span class="DetailOverview_listItemValue" data-reactid="461">3</span><span class="DetailOverview_listItemLabel" data-reactid="462">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="463"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="464"/><span class="DetailOverview_listItemValue" data-reactid="465">2,583</span><span class="DetailOverview_listItemLabel" data-reactid="466">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="468"><!-- react-text: 469 -->Community: <!-- /react-text --><a class="" href="/communities/harvest-al/riverstone-at-monrovia" data-reactid="470">Riverstone At Monrovia</a></span>
+<span class="DetailOverview_sectionItem" data-reactid="471"><!-- react-text: 472 -->Floor Plan: <!-- /react-text --><a class="" href="/plan/the-rockdale" data-reactid="473">The Rockdale</a></span>
+<a href="tel:2568085522" data-reactid="495">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-03.html b/collectors/legacy-al/fixtures/homes/home-03.html
new file mode 100644
index 00000000..575f213d
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-03.html
@@ -0,0 +1,10 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"104 Speck Circle Meridianville, AL, 35759","address":{"addressLocality":"Meridianville","addressRegion":"AL","streetAddress":"104 Speck Circle","postalCode":"35759","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/meridianville-al/colonial-pointe-n/104-speck-circle","mainEntityOfPage":"https://www.legacyhomesal.com/homes/meridianville-al/colonial-pointe-n/104-speck-circle","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Colonial Pointe - N","description":"Legacy Homes invites you to Colonial Pointe!!! NOW SELLING PHASE 7!\nLegacy Homes is building quality, energy-efficient new homes in Huntsville off Patterson Lane in Meridianville. Quiet living and convenient location are just two of the reasons that make the Colonial Pointe community such a desirable place to live! Colonial Pointe is located in the highly sought after Hazel Green High School district and includes a brand new intermediate school: Moores Mill Intermediate School (4th-6th grade).","address":{"addressLocality":"Meridianville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"199 Balboa Road","postalCode":"35759"},"geo":{"@type":"GeoCoordinates","latitude":34.876265307754,"longitude":-86.585741888436}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21885737/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.872597,"longitude":-86.585873},"offers":[{"@type":"Offer","price":421900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"Rates as low as 3.99%- Move In Ready!!! The Lincoln- 4 Bed 3.5 Bath -Our Lifestyle Triangle joins living room, dining, & kitchen to create an open concept. Designer Kitchen features large Chef's island w/granite counters, SS appliances, & natural GAS! Large, secluded owner suite w/optional glamour bath & massive owner closet. Full brick exterior, w/large covered back patio! Large, fully sodded, flat lots. Come check out the Colonial Pointe community which features large lots, convenient access to Research Park & the Parkway, & just 15 minutes away from Downtown Huntsville! 100% FINANCING eligible area.","productId":"67f68d6c3c3e6ad99ca1a200","sku":"67f68d6c3c3e6ad99ca1a200"}</script>
+<li class="DetailOverview_listItem" data-reactid="505"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="506"/><span class="DetailOverview_listItemValue" data-reactid="507">4</span><span class="DetailOverview_listItemLabel" data-reactid="508">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="509"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="510"/><span class="DetailOverview_listItemValue" data-reactid="511">3</span><span class="DetailOverview_listItemLabel" data-reactid="512">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="513"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="514"/><span class="DetailOverview_listItemValue" data-reactid="515">1</span><span class="DetailOverview_listItemLabel" data-reactid="516">Half Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="517"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="518"/><span class="DetailOverview_listItemValue" data-reactid="519">3,156</span><span class="DetailOverview_listItemLabel" data-reactid="520">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="522"><!-- react-text: 523 -->Community: <!-- /react-text --><a class="" href="/communities/meridianville-al/colonial-pointe-n" data-reactid="524">Colonial Pointe - N</a></span>
+<a href="tel:2562269159" data-reactid="546">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-04.html b/collectors/legacy-al/fixtures/homes/home-04.html
new file mode 100644
index 00000000..ee2ffb84
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-04.html
@@ -0,0 +1,10 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"17367 Chelsea Street Athens, AL, 35611","address":{"addressLocality":"Athens","addressRegion":"AL","streetAddress":"17367 Chelsea Street","postalCode":"35611","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/athens-al/boardwalk-n/17367-chelsea-street","mainEntityOfPage":"https://www.legacyhomesal.com/homes/athens-al/boardwalk-n/17367-chelsea-street","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Boardwalk - N","description":"Experience Better Living in Athens at Boardwalk! Boardwalk is a pedestrian friendly community, featuring our exclusive Boardwalk Series rear-entry style plans. These homes offer one-of-a-kind craftsman elevations with true front-porch living to relax and enjoy your evenings. **Also directly across from the NEW Sunrise Park** featuring an Aquatix Splash Pad, custom playground and a massive Alpha Tower – perfect for your family to enjoy and a quick walk across the street from Boardwalk. We are also conveniently located behind the highly acclaimed Athens High School and just 2 minutes from the historic and popular Downtown Athens! Come see us and learn more about how you can Experience Better Living at Boardwalk!","address":{"addressLocality":"Athens","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"17357 Eastmoor Street","postalCode":"35611"},"geo":{"@type":"GeoCoordinates","latitude":34.808941,"longitude":-86.955442}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21886630/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.809764,"longitude":-86.953499},"offers":[{"@type":"Offer","price":349900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"<helmet-script/>5,000 FLEX CASH INCENTIVE AVAILABLE ON THIS HOME!! Welcome to BOARDWALK! Legacy's lifestyle community in the heart of Athens, close to downtown, a short walk from Publix, and right across from the new Sunrise Park off Pryor Street! This Whitestone is our 2 story 3 bed, 2.5 bath home with a downstairs master suite and 2 guest beds and bonus room on the second level. This home features granite countertops, a large island with front and rear cabinets, soft-close cabinetry, gas stove, stainless steel appliances, LVP flooring, hardwood stairs, full yard and flower bed irrigation, included window blinds, and much more! Come see what Boardwalk has to offer and Experience Better Living!","productId":"6802b005e25a4901cb0d76c7","sku":"6802b005e25a4901cb0d76c7"}</script>
+<li class="DetailOverview_listItem" data-reactid="374"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="375"/><span class="DetailOverview_listItemValue" data-reactid="376">3</span><span class="DetailOverview_listItemLabel" data-reactid="377">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="378"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="379"/><span class="DetailOverview_listItemValue" data-reactid="380">2</span><span class="DetailOverview_listItemLabel" data-reactid="381">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="382"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="383"/><span class="DetailOverview_listItemValue" data-reactid="384">1</span><span class="DetailOverview_listItemLabel" data-reactid="385">Half Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="386"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="387"/><span class="DetailOverview_listItemValue" data-reactid="388">2,487</span><span class="DetailOverview_listItemLabel" data-reactid="389">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="391"><!-- react-text: 392 -->Community: <!-- /react-text --><a class="" href="/communities/athens-al/boardwalk-n" data-reactid="393">Boardwalk - N</a></span>
+<a href="tel:6154987979" data-reactid="413">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-05.html b/collectors/legacy-al/fixtures/homes/home-05.html
new file mode 100644
index 00000000..f612b00d
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-05.html
@@ -0,0 +1,9 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"139 Hillis Lane Hazel Green, AL, 35750","address":{"addressLocality":"Hazel Green","addressRegion":"AL","streetAddress":"139 Hillis Lane","postalCode":"35750","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/hazel-green-al/townsend-farms/139-hillis-lane","mainEntityOfPage":"https://www.legacyhomesal.com/homes/hazel-green-al/townsend-farms/139-hillis-lane","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Townsend Farms","description":"NOW SELLING PHASE 2!\nLegacy Homes is now offering beautiful, full brick homes on large, private home sites in Hazel Green! Enjoy the peaceful setting of living in a new home with stunning amenities and a lot of space! With convenient access to Highway 231/431 and Hazel Green High School, Townsend is minutes away from the Redstone Arsenal, and top employers like Dynetics, Toyota, Polaris, and more.  Townsend is also only 4.9 miles away from the Publix Supermarket.\nHomes for sale in Townsend Liberty Series range from 1,556 square feet to 4,114 square feet and feature 3-5 bedrooms with two-car garages. \nBuild Your Legacy.®","address":{"addressLocality":"Hazel Green","addressRegion":"AL","streetAddress":"107 Coco Circle","postalCode":"35750","@type":"PostalAddress"},"geo":{"@type":"GeoCoordinates","latitude":34.937931,"longitude":-86.572663}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21893845/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.937545,"longitude":-86.579451},"offers":[{"@type":"Offer","price":328900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"Move-In-Ready Fixed Rates as low as 4.49%- Our Charleston plan offers a perfect lifestyle triangle with 3 bedrooms, 2 baths, and an office! With an open layout, its ideal for entertaining guests. You'll enjoy many standard features throughout the home, including granite counters and stainless steel appliances in the kitchen, smooth ceilings, and LVP flooring in the main living areas. Plus, there is a covered back porch for relaxing outside. Come see the Townsend Community which features large lots, convenient access to the Parkway, restaurants, shopping, and just 15 minutes away from Downtown Huntsville! Paid mortgage related closing cost with preferred lender","productId":"6871430c04c749074ef094cc","sku":"6871430c04c749074ef094cc"}</script>
+<li class="DetailOverview_listItem" data-reactid="446"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="447"/><span class="DetailOverview_listItemValue" data-reactid="448">4</span><span class="DetailOverview_listItemLabel" data-reactid="449">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="450"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="451"/><span class="DetailOverview_listItemValue" data-reactid="452">2</span><span class="DetailOverview_listItemLabel" data-reactid="453">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="454"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="455"/><span class="DetailOverview_listItemValue" data-reactid="456">2,303</span><span class="DetailOverview_listItemLabel" data-reactid="457">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="459"><!-- react-text: 460 -->Community: <!-- /react-text --><a class="" href="/communities/hazel-green-al/townsend-farms" data-reactid="461">Townsend Farms</a></span>
+<a href="tel:2566906869" data-reactid="481">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-06.html b/collectors/legacy-al/fixtures/homes/home-06.html
new file mode 100644
index 00000000..d658e969
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-06.html
@@ -0,0 +1,10 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"1610 Calistoga Circle Huntsville, AL, 35811","address":{"addressLocality":"Huntsville","addressRegion":"AL","streetAddress":"1610 Calistoga Circle","postalCode":"35811","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/hunstville-al/trailhead-n/1610-calistoga-circle","mainEntityOfPage":"https://www.legacyhomesal.com/homes/hunstville-al/trailhead-n/1610-calistoga-circle","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Trailhead - N","description":"Explore Better Living.\nLearn More At: https://trailheadhsv.com/\n\nExplore the beauty Trailhead has to offer with 150 acres of Mountain Nature Preserve.  You will find our Park and Cove series homes nestled into the base of Chapman Mountain. Among the Homesites you will find hiking trails that lead to Monte Sano State Park and over 2 miles of greenway with Trailhead parking.  You'll forget you're only a 6 minute drive from downtown Huntsville!\nAgency: Capstone Realty","address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"1617 Calistoga Circle","postalCode":"35811"},"geo":{"@type":"GeoCoordinates","latitude":34.76701344666,"longitude":-86.530769942774}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21895159/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.767424,"longitude":-86.528099},"offers":[{"@type":"Offer","price":449900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"MOVE IN READY! 4.99 INTEREST RATE AVAILABLE! Welcome to Trailhead! Huntsville's latest mixed-use community is in a prime location, close to downtown surrounded by beautiful mountain views. Built on a large premium lot with side entry garage, this Whitestone is our 3 bed 2.5 bath floor plan with a large first-floor living room full of windows for natural light, large master suite and 2 guest beds and bonus room upstairs. This home features a craftsman style brick and painted Hardie exterior, hardwood and tile throughout (NO CARPET!), stainless steel Whirlpool appliances with gas range, granite countertops, irrigation, crown molding, walk in attic, and much more! Explore Better Living!","productId":"688526144e08d5b34f31c54a","sku":"688526144e08d5b34f31c54a"}</script>
+<li class="DetailOverview_listItem" data-reactid="410"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="411"/><span class="DetailOverview_listItemValue" data-reactid="412">3</span><span class="DetailOverview_listItemLabel" data-reactid="413">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="414"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="415"/><span class="DetailOverview_listItemValue" data-reactid="416">2</span><span class="DetailOverview_listItemLabel" data-reactid="417">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="418"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="419"/><span class="DetailOverview_listItemValue" data-reactid="420">1</span><span class="DetailOverview_listItemLabel" data-reactid="421">Half Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="422"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="423"/><span class="DetailOverview_listItemValue" data-reactid="424">2,487</span><span class="DetailOverview_listItemLabel" data-reactid="425">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="427"><!-- react-text: 428 -->Community: <!-- /react-text --><a class="" href="/communities/hunstville-al/trailhead-n" data-reactid="429">Trailhead - N</a></span>
+<a href="tel:6154987979" data-reactid="449">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-07.html b/collectors/legacy-al/fixtures/homes/home-07.html
new file mode 100644
index 00000000..9db042df
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-07.html
@@ -0,0 +1,9 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"173 Saddle Street New Market, AL, 35761","address":{"addressLocality":"New Market","addressRegion":"AL","streetAddress":"173 Saddle Street","postalCode":"35761","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/new-market-al/bellview-n/173-saddle-street","mainEntityOfPage":"https://www.legacyhomesal.com/homes/new-market-al/bellview-n/173-saddle-street","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Bellview - N","description":"Welcome to New Market!\nLegacy Homes is building quality, energy-efficient new homes in Huntsville off Winchester Road in beautiful New Market, Alabama!  Located near Buckhorn High School, this brand new community will offer new homes starting in the $314's.  New Market is a hidden gem in North Alabama with picturesque views of the mountains to the East and the Flint River to the West.  With the highly acclaimed New Market BBQ just up the road (try the homemade banana pudding!), there are so many reasons to love this new Legacy Homes community.  Build Your Legacy.®","address":{"addressLocality":"New Market","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"104 Verizon Street","postalCode":"35761"},"geo":{"@type":"GeoCoordinates","latitude":34.880322,"longitude":-86.460687}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21906670/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.874332,"longitude":-86.45725},"offers":[{"@type":"Offer","price":400900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"MOVE IN READY! - Legacy's NEW floorpan, the Rockdale on a flat homesite w/Sprinkler System! This plan features our Lifestyle Triangle offering LARGE open living spaces for everyone to enjoy! 4 Bedrooms , 3 full bathrooms, Large Bonus room, and Private office space. With 3 bedrooms and an office downstairs, this home functions as a rancher with a bedroom, bonus and bed4/bath3 upstairs! The open kitchen has Granite counters, a large Chef's island, stainless steel appliances and a natural GAS 5 burner range. The primary suite has great natural light and a spacious master bath featuring a Marble shower and Bath. Enjoy your large walk-in closet w/ laundry connected and mud room!","productId":"695979b4cffd45986e1863ea","sku":"695979b4cffd45986e1863ea"}</script>
+<li class="DetailOverview_listItem" data-reactid="368"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="369"/><span class="DetailOverview_listItemValue" data-reactid="370">4</span><span class="DetailOverview_listItemLabel" data-reactid="371">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="372"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="373"/><span class="DetailOverview_listItemValue" data-reactid="374">3</span><span class="DetailOverview_listItemLabel" data-reactid="375">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="376"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="377"/><span class="DetailOverview_listItemValue" data-reactid="378">2,631</span><span class="DetailOverview_listItemLabel" data-reactid="379">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="381"><!-- react-text: 382 -->Community: <!-- /react-text --><a class="" href="/communities/new-market-al/bellview-n" data-reactid="383">Bellview - N</a></span>
+<a href="tel:2567241044" data-reactid="405">
+</body></html>
diff --git a/collectors/legacy-al/fixtures/homes/home-08.html b/collectors/legacy-al/fixtures/homes/home-08.html
new file mode 100644
index 00000000..b494347d
--- /dev/null
+++ b/collectors/legacy-al/fixtures/homes/home-08.html
@@ -0,0 +1,10 @@
+<!doctype html><html><body>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["Organization","LocalBusiness","HomeAndConstructionBusiness"],"address":{"addressLocality":"Huntsville","@type":"PostalAddress","addressCountry":"US","addressRegion":"AL","streetAddress":"2000 Andrew Jackson Way NE","postalCode":"35811"},"description":"Legacy Homes is your premier new home builder in Madison and Huntsville Alabama. Our communities feature our award-winning designs with stunning amenities, excellent schools, and convenient access to Redstone Arsenal, Bridge Street, and more.  We are committed to providing the absolute best value with more choices to home buyers seeking a quality, energy-efficient home.  With new homes for sale in Huntsville, Madison, Hampton Cove, Meridianville, and Monrovia, we offer several locations to Build Your Legacy.®","name":"Legacy Homes AL","telephone":"(256) 361 - 9104","image":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","logo":{"contentUrl":"https://s3.amazonaws.com/buildercloud/375e2a299df3352e9efefd6e6f6f7fcc.png","@type":"ImageObject","url":"https://www.legacyhomesal.com"},"geo":{"@type":"GeoCoordinates","latitude":34.749913,"longitude":-86.575353},"sameAs":["https://www.facebook.com/legacyhomesal","https://www.youtube.com/channel/UCF2WRa5iy57SwB8NFwQSKeg","https://www.instagram.com/legacyhomes?igsh=MThhamEyYnJ2c3p0Yw%3D%3D&utm_source=qr"],"url":"https://www.legacyhomesal.com"}</script>
+<script data-react-helmet="true" type="application/ld+json">{"@context":"http://schema.org","@type":["SingleFamilyResidence","Product"],"name":"28115 Caperton Drive Harvest, AL, 35749","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"28115 Caperton Drive","postalCode":"35749","@type":"PostalAddress"},"url":"https://www.legacyhomesal.com/homes/harvest-al/charleston/28115-caperton-drive","mainEntityOfPage":"https://www.legacyhomesal.com/homes/harvest-al/charleston/28115-caperton-drive","containedIn":{"@context":"http://schema.org","@type":["Place"],"additionalType":["http://www.productontology.org/id/Subdivision_(land)"],"name":"Charleston","description":"Now Selling!\nWelcome to Harvest!\nLegacy Homes is building quality, energy-efficient new homes off Capshaw Road in beautiful Harvest community!  Located near the intersection of East Limestone Road and Capshaw Road, this brand new community will offer our American Series Homes. Harvest is one of North Alabama's fastest growing communities. With the one-of-a-kind local eateries and shops and the new nearby Clift Farms, there are so many reasons to love this new Legacy Homes community. Charleston provides easy access to Madison and Huntsville. Build Your Legacy.®\nAgency: Capstone Realty","address":{"addressLocality":"Harvest","addressRegion":"AL","streetAddress":"28150 Ladson Street","postalCode":"35749","@type":"PostalAddress"},"geo":{"@type":"GeoCoordinates","latitude":34.773124,"longitude":-86.818738}},"image":"https://dvvjkgh94f2v6.cloudfront.net/4d7fac11/21903900/83dcefb7.jpeg","geo":{"@type":"GeoCoordinates","latitude":34.767797,"longitude":-86.82071},"offers":[{"@type":"Offer","price":344900,"priceCurrency":"USD"}],"brand":{"@type":"Brand","name":"Legacy Homes AL"},"description":"Move-in-Ready! 3.99% ARM PROGRAM OR 4.99% FHA/VA FIXED RATE PROGRAM AVAILABLE WHILE FUNDS LAST!! South-facing Homesite! Downstairs Owner's Suite! The 2800 Plan 4BD/3.5BA + Bonus! Our Lifestyle Triangle joins together the Living Room, Dining, & Kitchen to create an open concept. Chef's Kitchen features large Chef's island, granite counters, and SS appliances! Owner's Suite w/ large Glamour Bath & WIC. Direct Connect to Laundry! Full Brick exterior! Come see our Charleston community which features flat, scenic, fully sodded lots. Country feel with convenient city access. Only 8min to Clift Farm in Madison & 9min to Athens! High Speed Fiber Internet & Public Sewer! 100% Financing eligible!","productId":"69178d513e6d2fa9644f552e","sku":"69178d513e6d2fa9644f552e"}</script>
+<li class="DetailOverview_listItem" data-reactid="464"><img class="DetailOverview_listIcon" src="/images/icon-beds.svg" alt="beds icon" data-reactid="465"/><span class="DetailOverview_listItemValue" data-reactid="466">4</span><span class="DetailOverview_listItemLabel" data-reactid="467">Beds</span></li>
+<li class="DetailOverview_listItem" data-reactid="468"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="469"/><span class="DetailOverview_listItemValue" data-reactid="470">3</span><span class="DetailOverview_listItemLabel" data-reactid="471">Full Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="472"><img class="DetailOverview_listIcon mr-2" src="/images/icon-bath-2.png" alt="baths icon" data-reactid="473"/><span class="DetailOverview_listItemValue" data-reactid="474">1</span><span class="DetailOverview_listItemLabel" data-reactid="475">Half Baths</span></li>
+<li class="DetailOverview_listItem" data-reactid="476"><img class="DetailOverview_listIcon" src="/images/icon-sqft.svg" alt="sqft icon" data-reactid="477"/><span class="DetailOverview_listItemValue" data-reactid="478">2,762</span><span class="DetailOverview_listItemLabel" data-reactid="479">Sq Ft</span></li>
+<span class="DetailOverview_sectionItem" data-reactid="481"><!-- react-text: 482 -->Community: <!-- /react-text --><a class="" href="/communities/harvest-al/charleston" data-reactid="483">Charleston</a></span>
+<a href="tel:2567240111" data-reactid="503">
+</body></html>
diff --git a/collectors/legacy-al/package.json b/collectors/legacy-al/package.json
new file mode 100644
index 00000000..989bd78d
--- /dev/null
+++ b/collectors/legacy-al/package.json
@@ -0,0 +1,15 @@
+{
+  "name": "@homesonspec/collector-legacy-al",
+  "version": "0.1.0",
+  "private": true,
+  "type": "module",
+  "main": "./src/index.ts",
+  "types": "./src/index.ts",
+  "scripts": { "test": "vitest run --passWithNoTests", "typecheck": "tsc --noEmit" },
+  "dependencies": {
+    "@homesonspec/collectors-common": "workspace:*",
+    "@homesonspec/schemas": "workspace:*",
+    "@homesonspec/shared": "workspace:*"
+  },
+  "devDependencies": { "typescript": "^5.7.2", "vitest": "^4.0.0", "@types/node": "^22.10.5" }
+}
diff --git a/collectors/legacy-al/src/index.ts b/collectors/legacy-al/src/index.ts
new file mode 100644
index 00000000..46ab7fa2
--- /dev/null
+++ b/collectors/legacy-al/src/index.ts
@@ -0,0 +1,408 @@
+import type { ExtractedRecord, FieldValue } from "@homesonspec/schemas";
+import { normalizeStateCode } from "@homesonspec/shared";
+import {
+  fetchFixtures,
+  LiveFetcher,
+  type ExtractionOutput,
+  type FetchContext,
+  type RawPage,
+  type SourceAdapter,
+} from "@homesonspec/collectors-common";
+
+/**
+ * Legacy Homes Alabama adapter — the North Alabama site-built spec builder in
+ * Clayton Properties Group (slug "legacy-al"; recon +
+ * built 2026-08-30, TK-10487). Same architecture class as the goodall-homes and
+ * harris-doyle adapters: Clayton has no unified site-built feed, so each brand
+ * gets its own adapter on its own domain.
+ *
+ * SITE IDENTITY: https://www.legacyhomesal.com. The sitemap inventory spans
+ * Huntsville-area cities including Harvest, Meridianville, Athens, Hazel Green,
+ * New Market, and Huntsville. This is the Alabama CPG Legacy brand.
+ *
+ * HOST NOTE: the bare host redirects to the canonical www host. robots.txt is
+ * fully open and references the public sitemap.
+ *
+ * WIRE FORMAT: BuilderCloud React SSR. A normal GET returns complete product
+ * JSON-LD plus the primary home's DetailOverview markup; no browser is needed.
+ *
+ * MACHINE-READABLE SOURCE (preferred per the standing "own data over fragile
+ * DOM" lesson): each per-home page carries a per-home JSON-LD block typed
+ * ["SingleFamilyResidence","Product"] that is the authoritative carrier of the
+ * facts most prone to DOM rot —
+ *   - address (streetAddress / addressLocality / addressRegion / postalCode),
+ *   - geo (latitude / longitude),
+ *   - price (offers[].price, a real integer, NOT a "$" DOM string),
+ *   - community (containedIn.name, e.g. "Silver Stream" — NOT a slug-titlecased
+ *       URL segment, which is the trap that bit a sibling adapter),
+ *   - a STABLE per-home id (productId === sku, a 24-hex builder document id).
+ * We prefer JSON-LD for all of the above and fall back to the DOM only when a
+ * field is genuinely absent from it.
+ *
+ * DOM (only for facts JSON-LD does not carry): the PRIMARY home renders beds,
+ * full baths, half baths, stories and sqft in DetailOverview_listItem nodes,
+ * plus the floor plan in DetailOverview_sectionItem. We deliberately ignore
+ * sibling cards. The visible "Active" value is a sales state, not construction
+ * evidence, so constructionStatus remains null.
+ *
+ * Honest nulls (genuinely absent from the page, NOT fabricated):
+ *   - garageSpaces: Legacy's per-home page publishes no garage field → null.
+ *   - estCompletionDate: no per-home completion date on the page → null.
+ *
+ * Facts-only: images OMITTED (buildercloud photos exist but v1 stays images-off
+ * / mediaRights=NONE per HomesOnSpec policy). Plain HTTP; one detail page ==
+ * one inventory_home.
+ *
+ * Batch control: LEGACY_AL_PAGE_LIMIT caps per-home pages/run (default 40). Optional
+ * LEGACY_AL_AREA filters the sitemap URL list by the first /homes/{city-al} slug
+ * (comma-list, e.g. "harvest-al,athens-al").
+ */
+const BUILDER_SLUG = "legacy-al";
+const ORIGIN = "https://www.legacyhomesal.com";
+const SITEMAP = `${ORIGIN}/sitemap.xml`;
+const AREA_FILTER = (process.env.LEGACY_AL_AREA ?? "")
+  .toLowerCase()
+  .split(",")
+  .map((s) => s.trim())
+  .filter(Boolean);
+const PAGE_LIMIT = Number(process.env.LEGACY_AL_PAGE_LIMIT ?? "40");
+
+function fv<T>(value: T | null, raw: string | null, sourceUrl: string, evidenceText?: string | null): FieldValue<T> {
+  return { value, raw, evidenceText: evidenceText ?? raw, sourceUrl, confidence: value === null ? 0 : 1 };
+}
+
+// A positive finite integer, or null. Never guesses; 0 / negative / NaN → null.
+const posInt = (v: unknown): number | null => {
+  const n = typeof v === "number" ? v : typeof v === "string" ? Number(String(v).replace(/[^0-9]/g, "")) : NaN;
+  return Number.isFinite(n) && n > 0 ? Math.trunc(n) : null;
+};
+// A positive decimal (baths may be 2.5), or null. Tolerates Legacy's "2 .5" spacing.
+const posDec = (v: unknown): number | null => {
+  const n = typeof v === "number" ? v : typeof v === "string" ? Number(String(v).replace(/\s+/g, "").replace(/[^0-9.]/g, "")) : NaN;
+  return Number.isFinite(n) && n > 0 ? n : null;
+};
+const clean = (v: unknown): string | null => {
+  if (v == null) return null;
+  const s = String(v)
+    .replace(/<[^>]+>/g, "")
+    .replace(/&#x([0-9a-f]+);/gi, (_m, h) => String.fromCodePoint(parseInt(h, 16)))
+    .replace(/&#(\d+);/g, (_m, d) => String.fromCodePoint(parseInt(d, 10)))
+    .replace(/&apos;/g, "'")
+    .replace(/&amp;/g, "&")
+    .replace(/&quot;/g, '"')
+    .replace(/&nbsp;/g, " ")
+    .replace(/\s+/g, " ")
+    .trim();
+  return s || null;
+};
+
+interface LegacyHome {
+  url: string;
+  street: string | null;
+  city: string | null;
+  state: string | null;
+  zip: string | null;
+  community: string | null;
+  planName: string | null;
+  lotNumber: string | null;
+  price: number | null;
+  beds: number | null;
+  bathsTotal: number | null; // decimal, half-baths folded (site publishes a single "2.5")
+  sqft: number | null;
+  stories: number | null;
+  garages: number | null; // no garage field on the page → null (honest)
+  lat: number | null;
+  lon: number | null;
+  phone: string | null;
+  status: "PLANNED" | "MOVE_IN_READY" | "UNDER_CONSTRUCTION" | null;
+  builderInventoryId: string | null;
+}
+
+/** Pull every parsed JSON-LD object out of the page (flattening arrays + @graph). */
+function jsonLdObjects(html: string): Record<string, unknown>[] {
+  const out: Record<string, unknown>[] = [];
+  for (const b of html.matchAll(/<script[^>]*type="application\/ld\+json"[^>]*>([\s\S]*?)<\/script>/gi)) {
+    let data: unknown;
+    try {
+      data = JSON.parse(b[1]!.trim());
+    } catch {
+      continue;
+    }
+    const top = Array.isArray(data) ? data : [data];
+    for (const it of top) {
+      if (it && typeof it === "object") {
+        const g = (it as Record<string, unknown>)["@graph"];
+        if (Array.isArray(g)) {
+          for (const node of g) if (node && typeof node === "object") out.push(node as Record<string, unknown>);
+        } else {
+          out.push(it as Record<string, unknown>);
+        }
+      }
+    }
+  }
+  return out;
+}
+
+function hasType(obj: Record<string, unknown>, token: string): boolean {
+  const t = obj["@type"];
+  const types = Array.isArray(t) ? t : [t];
+  return types.some((x) => x === token);
+}
+
+/** The per-home ["SingleFamilyResidence","Product"] JSON-LD object, or null. */
+function homeJsonLd(html: string): Record<string, unknown> | null {
+  for (const o of jsonLdObjects(html)) {
+    if (hasType(o, "SingleFamilyResidence") || (hasType(o, "Product") && o["address"])) return o;
+  }
+  return null;
+}
+
+function asObj(v: unknown): Record<string, unknown> | null {
+  return v && typeof v === "object" && !Array.isArray(v) ? (v as Record<string, unknown>) : null;
+}
+function asNum(v: unknown): number | null {
+  const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
+  return Number.isFinite(n) ? n : null;
+}
+
+// Minimal ZIP3-range guard for Alabama. If a page
+// ever publishes a ZIP whose ZIP3 can't belong to the parsed state, drop it to
+// an honest null rather than propagate a self-contradictory fact. Extensible.
+const STATE_ZIP3: Record<string, [number, number][]> = {
+  AL: [[350, 369]],
+};
+function zipConsistentWithState(zip: string | null, state: string | null): boolean {
+  if (!zip || !state) return true;
+  const ranges = STATE_ZIP3[state.toUpperCase()];
+  if (!ranges) return true;
+  const z3 = Number(zip.slice(0, 3));
+  return ranges.some(([lo, hi]) => z3 >= lo && z3 <= hi);
+}
+
+/**
+ * Parse ONE Legacy per-home page into a home, or null if it isn't a resolvable
+ * per-home detail page. Address/geo/price/community/id come from the per-home
+ * JSON-LD (authoritative); beds/baths/stories/sqft/lot/plan come from the
+ * PRIMARY home's DetailOverview list (never a sibling card).
+ */
+export function parseHome(html: string, pageUrl: string): LegacyHome | null {
+  const ld = homeJsonLd(html);
+  if (!ld) return null; // no per-home Product JSON-LD → not a resolvable detail page
+
+  // ---- authoritative address from JSON-LD PostalAddress ----
+  const addr = asObj(ld["address"]);
+  const street = clean(addr?.["streetAddress"]);
+  if (!street) return null; // a Product block with no street isn't a home listing
+
+  const city = clean(addr?.["addressLocality"]);
+  const state = normalizeStateCode(clean(addr?.["addressRegion"]));
+  const zipRaw = (clean(addr?.["postalCode"]) ?? "").match(/\d{5}/)?.[0] ?? null;
+  const zip = zipConsistentWithState(zipRaw, state) ? zipRaw : null;
+
+  // ---- authoritative geo from JSON-LD GeoCoordinates ----
+  const geo = asObj(ld["geo"]);
+  const lat = asNum(geo?.["latitude"]);
+  const lon = asNum(geo?.["longitude"]);
+
+  // ---- authoritative price from JSON-LD offers[].price ----
+  const offers = ld["offers"];
+  const firstOffer = Array.isArray(offers) ? asObj(offers[0]) : asObj(offers);
+  const price = posInt(firstOffer?.["price"]);
+
+  // ---- authoritative community from JSON-LD containedIn.name ----
+  const containedIn = asObj(ld["containedIn"]);
+  const community = clean(containedIn?.["name"]);
+
+  // ---- authoritative stable per-home id from JSON-LD productId / sku ----
+  const builderInventoryId = clean(ld["productId"]) ?? clean(ld["sku"]);
+
+  // ---- PRIMARY home specs: the DetailOverview list (NOT sibling HomeCards) ----
+  // Each item contains dedicated value + label spans. Full and half baths are
+  // separate, so combine them only after parsing both explicit values.
+  let beds: number | null = null;
+  let bathsTotal: number | null = null;
+  let sqft: number | null = null;
+  let stories: number | null = null;
+  let lotNumber: string | null = null;
+  let fullBaths: number | null = null;
+  let halfBaths: number | null = null;
+  for (const m of html.matchAll(/<li\s+class="DetailOverview_listItem"[^>]*>([\s\S]*?)<\/li>/gi)) {
+    const item = m[1] ?? "";
+    const valueMatch = item.match(/class="DetailOverview_listItemValue"[^>]*>([\s\S]*?)<\/span>/i);
+    const value = clean(valueMatch?.[1] ?? null);
+    const label = (clean(item.match(/class="DetailOverview_listItemLabel"[^>]*>([\s\S]*?)<\/span>/i)?.[1] ?? null) ?? "").toLowerCase();
+    if (/^beds?\b/.test(label)) beds = posInt(value);
+    else if (/^full baths?\b/.test(label)) fullBaths = posDec(value);
+    else if (/^half baths?\b/.test(label)) halfBaths = posDec(value);
+    else if (/^stor(?:y|ies)\b/.test(label)) stories = posInt(value);
+    else if (/^sq\.?\s*ft\.?\b/.test(label)) sqft = posInt(value);
+    else if (/^lot\s*#/.test(label)) lotNumber = value;
+  }
+  if (fullBaths != null || halfBaths != null) bathsTotal = (fullBaths ?? 0) + (halfBaths ?? 0) * 0.5;
+
+  // ---- floor-plan name: the DetailOverview "Floor Plan" anchor ----
+  const planItem = html.match(/Floor Plan:\s*(?:<!--[\s\S]*?-->)?\s*<a[^>]*>([^<]+)<\/a>/i);
+  const planName = clean(planItem?.[1] ?? null);
+
+  // ---- status: the DetailHeader lead span under the h1 ----
+  // "Active" in the detail table is a sales listing state, not a construction
+  // state. No supported construction evidence is published on these pages.
+  const status = null;
+
+  // ---- sales phone: first tel: link on the page (consultant / office) ----
+  const phone = clean(html.match(/href="tel:(\+?[\d]+)"/i)?.[1] ?? null);
+
+  // garageSpaces: Legacy's per-home page publishes no garage field → honest null.
+  const garages = null;
+
+  return {
+    url: pageUrl,
+    street,
+    city,
+    state,
+    zip,
+    community,
+    planName,
+    lotNumber,
+    price,
+    beds,
+    bathsTotal,
+    sqft,
+    stories,
+    garages,
+    lat,
+    lon,
+    phone,
+    status,
+    builderInventoryId,
+  };
+}
+
+/**
+ * A per-home inventory DETAIL URL: /homes/{city-al}/{community}/{address}
+ * — exactly THREE path segments after /homes/. Rejects city/community listing
+ * pages and any /undefined/ partial.
+ */
+function isDetailUrl(u: string): boolean {
+  const tail = u.split("/homes/")[1];
+  if (!tail) return false;
+  const segs = tail.replace(/\/$/, "").split(/[?#]/)[0]!.split("/");
+  if (segs.length !== 3) return false;
+  return segs.every((s) => !!s && s !== "undefined");
+}
+
+export const legacyAlAdapter: SourceAdapter = {
+  key: "legacy-al-site",
+  version: "0.1.0",
+
+  async *fetch(ctx: FetchContext): AsyncIterable<RawPage> {
+    if (ctx.mode === "fixture") {
+      yield* fetchFixtures(ctx);
+      return;
+    }
+    const fetcher = new LiveFetcher(ctx.registry);
+    const index = await fetcher.fetch(SITEMAP);
+    let homeUrls = [...index.body.toString("utf8").matchAll(/<loc>\s*([^<\s]+)\s*<\/loc>/g)]
+      .map((m) => m[1]!)
+      .filter(isDetailUrl);
+    if (AREA_FILTER.length) {
+      homeUrls = homeUrls.filter((u) => {
+        const area = u.split("/homes/")[1]?.split("/")[0]?.toLowerCase();
+        return area ? AREA_FILTER.includes(area) : false;
+      });
+    }
+    for (const url of homeUrls.slice(0, PAGE_LIMIT)) {
+      try {
+        yield await fetcher.fetch(url);
+      } catch (error) {
+        console.warn(`  skip ${url}: ${error instanceof Error ? error.message : String(error)}`);
+      }
+    }
+  },
+
+  extract(page: RawPage): ExtractionOutput {
+    try {
+      const html = page.body.toString("utf8");
+      const h = parseHome(html, page.url);
+      if (!h || !h.street) return { records: [], errors: [] }; // not a resolvable detail page
+
+      const cname = h.community ?? "Unknown";
+      const records: ExtractedRecord[] = [];
+
+      // Community FIRST — publish creates the FK target the home record needs.
+      records.push({
+        entityType: "community",
+        canonicalHints: { builderSlug: BUILDER_SLUG, communityName: cname },
+        fields: {
+          name: fv(cname, cname, page.url),
+          street: fv<string>(null, null, page.url),
+          city: fv(h.city, h.city, page.url),
+          state: fv(h.state, h.state, page.url),
+          zip: fv(h.zip, h.zip, page.url),
+          county: fv<string>(null, null, page.url),
+          metro: fv<string>(null, null, page.url),
+          lat: fv(h.lat, h.lat != null ? String(h.lat) : null, page.url),
+          lon: fv(h.lon, h.lon != null ? String(h.lon) : null, page.url),
+          hoaFeeMonthly: fv<number>(null, null, page.url),
+          schoolDistrict: fv<string>(null, null, page.url),
+          ageRestricted: fv<boolean>(null, null, page.url),
+          salesPhone: fv(h.phone, h.phone, page.url),
+        },
+      });
+
+      records.push({
+        entityType: "inventory_home",
+        canonicalHints: {
+          builderSlug: BUILDER_SLUG,
+          communityName: cname,
+          // The REAL street address (never a "Lot X" fallback) — from the
+          // per-home JSON-LD PostalAddress.streetAddress. `?? h.url` never fires
+          // because parseHome already returned null when street was absent, but
+          // it keeps the hint type-safe. Parenthesized per the standing rule.
+          address: (h.street ?? h.url),
+          builderInventoryId: h.builderInventoryId ?? h.url,
+          planName: h.planName ?? undefined,
+          lotNumber: h.lotNumber ?? undefined,
+          lat: h.lat ?? undefined,
+          lon: h.lon ?? undefined,
+        },
+        fields: {
+          street: fv(h.street, h.street, page.url),
+          city: fv(h.city, h.city, page.url),
+          state: fv(h.state, h.state, page.url),
+          zip: fv(h.zip, h.zip, page.url),
+          price: fv(
+            h.price,
+            h.price != null ? `$${h.price}` : null,
+            page.url,
+            h.price != null ? `Offer price $${h.price}` : null,
+          ),
+          beds: fv(h.beds, h.beds != null ? String(h.beds) : null, page.url),
+          bathsTotal: fv(h.bathsTotal, h.bathsTotal != null ? String(h.bathsTotal) : null, page.url),
+          sqft: fv(h.sqft, h.sqft != null ? String(h.sqft) : null, page.url),
+          stories: fv(h.stories, h.stories != null ? String(h.stories) : null, page.url),
+          garageSpaces: fv(h.garages, h.garages != null ? String(h.garages) : null, page.url), // honest null
+          homeType: fv("SINGLE_FAMILY" as const, null, page.url, "Legacy Homes Alabama single-family inventory home"),
+          constructionStatus: fv<"PLANNED" | "UNDER_CONSTRUCTION" | "MOVE_IN_READY">(
+            h.status,
+            null,
+            page.url,
+            null,
+          ),
+          estCompletionDate: fv<string>(null, null, page.url), // no per-home completion date on the page
+          lotNumber: fv(h.lotNumber, h.lotNumber, page.url),
+          builderInventoryId: fv(h.builderInventoryId, h.builderInventoryId, page.url),
+          lat: fv(h.lat, h.lat != null ? String(h.lat) : null, page.url),
+          lon: fv(h.lon, h.lon != null ? String(h.lon) : null, page.url),
+          planName: fv(h.planName, h.planName, page.url),
+          // Facts-only: images intentionally omitted (mediaRights=NONE).
+          images: fv<string[]>([], null, page.url),
+        },
+      });
+
+      return { records, errors: [] };
+    } catch (error) {
+      return { records: [], errors: [{ url: page.url, reason: String(error) }] };
+    }
+  },
+};
diff --git a/collectors/legacy-al/src/selftest.test.ts b/collectors/legacy-al/src/selftest.test.ts
new file mode 100644
index 00000000..1ae5f15f
--- /dev/null
+++ b/collectors/legacy-al/src/selftest.test.ts
@@ -0,0 +1,92 @@
+import { readFileSync, readdirSync } from "node:fs";
+import { dirname, join } from "node:path";
+import { fileURLToPath } from "node:url";
+import { describe, expect, it } from "vitest";
+import { validatePayload } from "@homesonspec/schemas";
+import { legacyAlAdapter, parseHome } from "./index";
+
+const HERE = dirname(fileURLToPath(import.meta.url));
+const FX = join(HERE, "..", "fixtures", "homes");
+
+function urlMap(): Record<string, string> {
+  const out: Record<string, string> = {};
+  for (const line of readFileSync(join(FX, "_urls.tsv"), "utf8").split(/\r?\n/)) {
+    const [file, url] = line.split("\t");
+    if (file && url) out[file.trim()] = url.trim();
+  }
+  return out;
+}
+
+function mkPage(url: string, html: string) {
+  return { url, retrievedAt: new Date().toISOString(), contentType: "text/html", body: Buffer.from(html), contentHash: "test" };
+}
+
+describe("legacy-al adapter — real fixture E2E boundaries", () => {
+  const files = readdirSync(FX).filter((f) => f.endsWith(".html")).sort();
+  const urls = urlMap();
+
+  it("parses eight distinct Alabama inventory homes with honest nulls", () => {
+    const homes = files.map((file) => parseHome(readFileSync(join(FX, file), "utf8"), urls[file]!));
+    expect(homes).toHaveLength(8);
+    expect(homes.every(Boolean)).toBe(true);
+    const parsed = homes.filter((h) => h != null);
+    expect(new Set(parsed.map((h) => h.street)).size).toBe(8);
+    expect(new Set(parsed.map((h) => h.builderInventoryId)).size).toBe(8);
+    expect(parsed.filter((h) => h.stories != null).length).toBeGreaterThanOrEqual(1);
+    expect(parsed.filter((h) => h.planName != null).length).toBeGreaterThanOrEqual(2);
+    for (const h of parsed) {
+      expect(h.state).toBe("AL");
+      expect(h.zip).toMatch(/^3[5-6]\d{3}$/);
+      expect(h.street).toMatch(/^\d/);
+      expect(h.city).toBeTruthy();
+      expect(h.community).toBeTruthy();
+      if (h.planName != null) expect(h.planName).toMatch(/\S/);
+      expect(h.builderInventoryId).toBeTruthy();
+      expect(h.beds).toBeGreaterThan(0);
+      expect(h.bathsTotal).toBeGreaterThan(0);
+      expect(h.sqft).toBeGreaterThan(0);
+      if (h.stories != null) expect(h.stories).toBeGreaterThan(0);
+      expect(h.lat).toBeGreaterThan(30);
+      expect(h.lat).toBeLessThan(36);
+      expect(h.lon).toBeGreaterThan(-89);
+      expect(h.lon).toBeLessThan(-84);
+      if (h.price != null) expect(h.price).toBeGreaterThan(50_000);
+      expect(h.garages).toBeNull();
+      expect(h.lotNumber).toBeNull();
+      expect(h.status).toBeNull();
+    }
+  });
+
+  it("emits schema-valid community and inventory records with real address hints", () => {
+    let homeCount = 0;
+    for (const file of files) {
+      const html = readFileSync(join(FX, file), "utf8");
+      const url = urls[file]!;
+      const { records, errors } = legacyAlAdapter.extract(mkPage(url, html));
+      expect(errors).toEqual([]);
+      expect(records.map((r) => r.entityType)).toEqual(["community", "inventory_home"]);
+      for (const record of records) expect(validatePayload(record).ok).toBe(true);
+      const home = records[1]!;
+      homeCount++;
+      expect(home.canonicalHints.address).toBe(parseHome(html, url)!.street);
+      expect(home.canonicalHints.address).not.toMatch(/^lot\b|^https?:/i);
+      expect(home.fields.constructionStatus?.value).toBeNull();
+      expect(home.fields.garageSpaces?.value).toBeNull();
+    }
+    expect(homeCount).toBe(8);
+  });
+
+  it("rejects a page without per-home Product JSON-LD", () => {
+    const file = files[0]!;
+    const html = readFileSync(join(FX, file), "utf8");
+    const withoutJsonLd = html.replace(/<script[^>]*type="application\/ld\+json"[^>]*>[\s\S]*?<\/script>/gi, "");
+    expect(parseHome(withoutJsonLd, urls[file]!)).toBeNull();
+  });
+
+  it("does not invent a missing primary spec", () => {
+    const file = files[0]!;
+    const html = readFileSync(join(FX, file), "utf8");
+    const withoutBeds = html.replace(/<li\s+class="DetailOverview_listItem"[^>]*>[\s\S]*?Beds[\s\S]*?<\/li>/i, "");
+    expect(parseHome(withoutBeds, urls[file]!)?.beds).toBeNull();
+  });
+});
diff --git a/collectors/legacy-al/tsconfig.json b/collectors/legacy-al/tsconfig.json
new file mode 100644
index 00000000..e9bfc482
--- /dev/null
+++ b/collectors/legacy-al/tsconfig.json
@@ -0,0 +1 @@
+{ "extends": "../../tsconfig.base.json", "compilerOptions": { "noEmit": true }, "include": ["src/**/*.ts"] }
diff --git a/packages/database/prisma/seed-cpg-builders.ts b/packages/database/prisma/seed-cpg-builders.ts
index 1fb23c2e..61ee4422 100644
--- a/packages/database/prisma/seed-cpg-builders.ts
+++ b/packages/database/prisma/seed-cpg-builders.ts
@@ -3,7 +3,7 @@ import { prisma } from "../src/index.js";
 /**
  * Clayton Properties Group sub-brand adapters — batch 1 + 2 (TK-10487).
  * Built 2026-08-12 (batch 1: goodall/brohn/oakwood), 2026-08-17
- * (batch 2: summit-homes-kc), and 2026-08-30 (batch 2: mungo/chafin/harris-doyle).
+ * (batch 2: summit-homes-kc), and 2026-08-30 (batch 2: mungo/chafin/harris-doyle/legacy-al).
  * Parent builder slug: "clayton-properties" (already seeded).
  */
 
@@ -77,6 +77,14 @@ const CPG_BRANDS: {
     termsUrl: "https://www.claytonhomes.com/legal/",
     coverage: "Alabama and Florida",
   },
+  {
+    slug: "legacy-al",
+    name: "Legacy Homes Alabama",
+    legalName: "Legacy Homes Alabama",
+    website: "https://www.legacyhomesal.com",
+    termsUrl: "https://www.legacyhomesal.com/terms",
+    coverage: "North Alabama — Huntsville area",
+  },
 ];
 
 async function main() {
diff --git a/verification/TK-10487-legacy-al-e2e-proof.json b/verification/TK-10487-legacy-al-e2e-proof.json
new file mode 100644
index 00000000..7e75a22d
--- /dev/null
+++ b/verification/TK-10487-legacy-al-e2e-proof.json
@@ -0,0 +1,52 @@
+{
+  "ticket": "TK-10487",
+  "brand": "Legacy Homes Alabama",
+  "risk_tier": "R1",
+  "verified_at": "2026-08-30T18:13:00Z",
+  "scope": "local fixture-backed collector, worker registration, and seed definition only",
+  "journey": {
+    "entry": "eight compact fixtures captured from public per-home URLs",
+    "boundaries": [
+      "Product/SingleFamilyResidence JSON-LD -> parser",
+      "primary DetailOverview DOM -> parser",
+      "parser -> SourceAdapter community and inventory_home records",
+      "records -> published schema validator",
+      "collector package -> local worker CLI registry",
+      "brand definition -> CPG seed TypeScript boundary"
+    ],
+    "outcome": "8/8 distinct Alabama homes; 16 schema-valid records; worker and database typechecks green"
+  },
+  "assertions": {
+    "fixtures": 8,
+    "distinct_addresses": 8,
+    "distinct_builder_inventory_ids": 8,
+    "schema_valid_community_records": 8,
+    "schema_valid_inventory_home_records": 8,
+    "alabama_state_and_coordinate_sanity": true,
+    "real_address_canonical_hints": true,
+    "honest_nulls": ["garageSpaces", "lotNumber", "constructionStatus", "source-absent price/plan/stories"],
+    "negative_no_product_jsonld_rejected": true,
+    "negative_missing_beds_not_invented": true
+  },
+  "commands": [
+    {
+      "command": "collectors/mungo-homes/node_modules/.bin/vitest run collectors/legacy-al/src/selftest.test.ts --reporter verbose",
+      "exit": 0,
+      "result": "1 file passed; 4 tests passed"
+    },
+    {
+      "command": "collectors/mungo-homes/node_modules/.bin/tsc -p collectors/legacy-al/tsconfig.json --noEmit",
+      "exit": 0
+    },
+    {
+      "command": "collectors/mungo-homes/node_modules/.bin/tsc -p apps/workers/tsconfig.json --noEmit",
+      "exit": 0
+    },
+    {
+      "command": "collectors/mungo-homes/node_modules/.bin/tsc -p packages/database/tsconfig.json --noEmit",
+      "exit": 0
+    }
+  ],
+  "external_side_effects": [],
+  "gates_preserved": ["seed execution", "ingest", "source activation", "deploy", "DNS", "remote push"]
+}

← ea4d4aee auto-data-snapshot: 2026-08-30T10:57:58 (3 data files) — col  ·  back to Homesonspec  ·  feat(homesonspec): Arbor Homes (Indianapolis CPG) collector 9e1cea83 →