[object Object]

← back to Homesonspec

admin/business: link data points to REAL homes — Real-home-listings table (rows → /homes/[id]), KPIs → /search + /builders

15ce8717c53306e4518cd4d9af3e6cfbabd88a86 · 2026-07-28 13:13:04 -0700 · Steve

Files touched

Diff

commit 15ce8717c53306e4518cd4d9af3e6cfbabd88a86
Author: Steve <steve@designerwallcoverings.com>
Date:   Tue Jul 28 13:13:04 2026 -0700

    admin/business: link data points to REAL homes — Real-home-listings table (rows → /homes/[id]), KPIs → /search + /builders
---
 apps/admin/src/app/business/page.tsx | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/apps/admin/src/app/business/page.tsx b/apps/admin/src/app/business/page.tsx
index 702fe4dc..33ee2221 100644
--- a/apps/admin/src/app/business/page.tsx
+++ b/apps/admin/src/app/business/page.tsx
@@ -9,6 +9,7 @@ export const dynamic = "force-dynamic";
 const FEED = process.env.HOS_FEED ?? "http://127.0.0.1:9799";
 const USRE = process.env.USRE_FEED ?? "http://127.0.0.1:9796";
 const VIEWER = process.env.HOS_VIEWER ?? "http://127.0.0.1:9977";
+const WEB = process.env.HOS_WEB ?? "http://127.0.0.1:3100"; // consumer site — real home pages
 
 async function raw<T = any>(sql: string): Promise<T[]> {
   try { return (await prisma.$queryRawUnsafe(sql)) as T[]; } catch { return []; }
@@ -46,7 +47,11 @@ async function data() {
   const projects = (await raw(`select address, city, state, coalesce(valuation,0)::float8 valuation, permit_type, issued_date::text issued
     from building_permits where valuation is not null order by valuation desc limit 30`))
     .map((r: any) => ({ address: r.address, city: r.city, state: r.state, valuation: N(r.valuation), permit_type: r.permit_type, issued: r.issued }));
-  return { homes, builders, communities, enriched, permits, permitsGeo, commercial, byBuilder, byState, metros, projects };
+  const sampleHomes = (await raw(`select h.id, h.street, h.city, h.state, coalesce(h.price,0)::float8 price, h.beds, h.sqft, h."constructionStatus" status, b.name builder
+    from "InventoryHome" h join "Builder" b on b.id=h."builderId"
+    where h.status='PUBLISHED' and h.price is not null order by h."publishedAt" desc nulls last limit 60`))
+    .map((r: any) => ({ id: r.id, address: r.street, city: r.city, state: r.state, price: N(r.price), beds: N(r.beds), sqft: N(r.sqft), status: r.status, builder: r.builder }));
+  return { homes, builders, communities, enriched, permits, permitsGeo, commercial, byBuilder, byState, metros, projects, sampleHomes };
 }
 
 function Bar({ items, unit }: { items: { label: string; value: number; href?: string }[]; unit?: string }) {
@@ -110,8 +115,8 @@ function Markdown({ text }: { text: string }) {
 export default async function BusinessPage() {
   const [d, doc] = await Promise.all([data(), loadDoc()]);
   const kpis = [
-    ["New-home listings", d.homes, `${FEED}/feed/homes?limit=200`],
-    ["Builders", d.builders, `${VIEWER}`],
+    ["New-home listings", d.homes, `${WEB}/search`],
+    ["Builders", d.builders, `${WEB}/builders`],
     ["Building permits", d.permits, `${FEED}/feed/permits?limit=200`],
     ["Permits geocoded", d.permitsGeo, `${FEED}/feed/permits?geo=1&limit=200`],
     ["Commercial + multifamily", d.commercial, `${FEED}/feed/permits?sector=commercial&limit=200`],
@@ -119,9 +124,16 @@ export default async function BusinessPage() {
   ] as const;
 
   const builderCols: Col[] = [
-    { key: "builder", label: "Builder", href: `${FEED}/feed/homes?limit=200` },
+    { key: "builder", label: "Builder", href: `${WEB}/builders` },
     { key: "homes", label: "Homes", num: true }, { key: "states", label: "States", num: true },
   ];
+  // real home listings — every row links to the actual /homes/[id] page on the consumer site
+  const homeCols: Col[] = [
+    { key: "address", label: "Address", href: `${WEB}/homes/{id}` },
+    { key: "city", label: "City" }, { key: "state", label: "ST" },
+    { key: "price", label: "Price", num: true, money: true }, { key: "beds", label: "Bd", num: true },
+    { key: "sqft", label: "Sqft", num: true }, { key: "status", label: "Status" }, { key: "builder", label: "Builder" },
+  ];
   const stateCols: Col[] = [
     { key: "state", label: "State", href: `${FEED}/feed/permits?state={state}&limit=200` },
     { key: "permits", label: "Permits", num: true }, { key: "commercial", label: "Commercial", num: true },
@@ -174,6 +186,7 @@ export default async function BusinessPage() {
 
       {/* Sortable field tables */}
       <div className="mt-6 space-y-6">
+        <section><h3 className="mb-2 text-sm font-semibold text-neutral-700">Real home listings <span className="text-neutral-400">— each row opens the live /homes page (click a header to sort)</span></h3><SortableTable cols={homeCols} rows={d.sampleHomes as Row[]} initialSort="price" /></section>
         <section><h3 className="mb-2 text-sm font-semibold text-neutral-700">Builders <span className="text-neutral-400">(click a header to sort)</span></h3><SortableTable cols={builderCols} rows={d.byBuilder as Row[]} initialSort="homes" /></section>
         <section><h3 className="mb-2 text-sm font-semibold text-neutral-700">Permits by state</h3><SortableTable cols={stateCols} rows={d.byState as Row[]} initialSort="permits" /></section>
         <section><h3 className="mb-2 text-sm font-semibold text-neutral-700">Top CRE development metros</h3><SortableTable cols={metroCols} rows={d.metros as Row[]} initialSort="total_valuation" /></section>

← 775ea10a build-loop: uncap CAP (download ALL homes per state) + 40 sw  ·  back to Homesonspec  ·  build-loop: fully uncapped (DRH/Lennar -> $CAP=100000) + 1h 74b6e755 →