[object Object]

← back to Homesonspec

kb-home: capture listing photos (ThumbnailImage/GalleryPhotos are objects, not strings)

cb83a522dd7d8a173ca4bbeeb8bffd8829290cd5 · 2026-07-28 20:17:45 -0700 · Steve Abrams

KB's feed stores images as objects {Image,Caption,…} (ThumbnailImage) and an
array of them (GalleryPhotos); the URL lives under .Image (a relative /globalassets
path). The adapter read them via str()/split() -> both null -> 0 photos on all 526
homes. Fixed to read .Image, build thumb+gallery, absolutize, drop coming-soon
placeholders. National FORCE_REEXTRACT backfill: 0 -> 521/526 (99.0%), 212 w/ galleries.

Verified: URL loads 200; KB detail + search cards render, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit cb83a522dd7d8a173ca4bbeeb8bffd8829290cd5
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 28 20:17:45 2026 -0700

    kb-home: capture listing photos (ThumbnailImage/GalleryPhotos are objects, not strings)
    
    KB's feed stores images as objects {Image,Caption,…} (ThumbnailImage) and an
    array of them (GalleryPhotos); the URL lives under .Image (a relative /globalassets
    path). The adapter read them via str()/split() -> both null -> 0 photos on all 526
    homes. Fixed to read .Image, build thumb+gallery, absolutize, drop coming-soon
    placeholders. National FORCE_REEXTRACT backfill: 0 -> 521/526 (99.0%), 212 w/ galleries.
    
    Verified: URL loads 200; KB detail + search cards render, 0 broken.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 collectors/kb-home/src/index.ts | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/collectors/kb-home/src/index.ts b/collectors/kb-home/src/index.ts
index 2fb0529a..ca7066a5 100644
--- a/collectors/kb-home/src/index.ts
+++ b/collectors/kb-home/src/index.ts
@@ -123,8 +123,18 @@ export const kbHomeAdapter: SourceAdapter = {
         const address = str(r.Address);
         const communityName = str(r.CommunityName);
         if (!address || !communityName) continue;
-        const thumb = str(r.ThumbnailImage) ?? str(r.GalleryPhotos)?.split(",")[0]?.trim() ?? null;
-        const image = thumb ? (thumb.startsWith("http") ? thumb : ORIGIN + thumb) : null;
+        // KB's ThumbnailImage is an OBJECT {Image,Caption,…} and GalleryPhotos an ARRAY
+        // of such objects — the URL lives under `.Image` (a site-relative /globalassets
+        // path), NOT the object itself. The old str()/split() read both as null, so KB
+        // had 0 photos. Build thumb-first + gallery, absolutize, drop "coming soon"
+        // placeholders (worse than the clean gradient fallback). [recon 2026-07-28]
+        const imgUrl = (o: unknown): string | null => str((o as Record<string, unknown> | undefined)?.Image);
+        const gallery = Array.isArray(r.GalleryPhotos) ? (r.GalleryPhotos as unknown[]) : [];
+        const rawImgs = [imgUrl(r.ThumbnailImage), ...gallery.map(imgUrl)].filter((u): u is string => !!u);
+        const images = [...new Set(rawImgs)]
+          .filter((u) => !/photo-coming-soon|\/images\/default\//i.test(u))
+          .map((u) => (u.startsWith("http") ? u : ORIGIN + u))
+          .slice(0, 8);
         const lot = str(r.Homesite) ?? str(r.MLSNumber);
         const homeType = /town|condo|attached/i.test(str(r.HomeType) ?? "") ? "TOWNHOME" : "SINGLE_FAMILY";
         records.push({
@@ -154,7 +164,7 @@ export const kbHomeAdapter: SourceAdapter = {
             builderInventoryId: fv(lot, lot, page.url),
             planName: fv(str(r.FloorPlanName), str(r.FloorPlanName), page.url),
             availabilityStatus: fv(str(r.MoveInDateCopy), str(r.MoveInDateCopy), page.url),
-            images: fv<string[]>(image ? [image] : [], null, page.url, image ? "builder listing photo" : null),
+            images: fv<string[]>(images, null, page.url, images.length ? "builder listing photo" : null),
           },
         });
       }

← d9241682 collectors: add LGI, Shea, Century, Beazer, Drees adapters (  ·  back to Homesonspec  ·  david-weekley: capture per-home ElevationRendering photos fr 7f27ee91 →