[object Object]

← back to Homesonspec

TK-10487: oakwood constructionStatus prefers authoritative KOVA Status (contrarian fix) with deterministic date fallback

4c9e0afcf04610a71cd5b3d6a89eafef471af2b7 · 2026-08-12 09:16:17 -0700 · Steve

Files touched

Diff

commit 4c9e0afcf04610a71cd5b3d6a89eafef471af2b7
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 12 09:16:17 2026 -0700

    TK-10487: oakwood constructionStatus prefers authoritative KOVA Status (contrarian fix) with deterministic date fallback
---
 collectors/oakwood-homes/src/index.ts | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/collectors/oakwood-homes/src/index.ts b/collectors/oakwood-homes/src/index.ts
index 81098fb9..4145ccac 100644
--- a/collectors/oakwood-homes/src/index.ts
+++ b/collectors/oakwood-homes/src/index.ts
@@ -161,6 +161,22 @@ function toIsoDate(raw: unknown): string | null {
   return `${m[1]}-${m[2]}-${m[3]}`;
 }
 
+/** Classify construction status from the authoritative KOVA Status string when it is an
+ * unambiguous signal; else fall back to the (deterministic) presence-of-completion-date
+ * heuristic. Never throws; unknown/empty Status -> heuristic. */
+function classifyStatus(
+  kovaStatus: unknown,
+  estCompletion: string | null,
+): OakHome["constructionStatus"] {
+  const s = (clean(kovaStatus) ?? "").toLowerCase();
+  if (/move.?in.?ready|available now|quick move|move.?in ready|finished|completed|ready now/.test(s))
+    return "MOVE_IN_READY";
+  if (/under construction|construction|building|in progress|framing|foundation|coming soon|started/.test(s))
+    return "UNDER_CONSTRUCTION";
+  // Ambiguous/absent Status (e.g. "Released") -> deterministic completion-date heuristic.
+  return estCompletion ? "UNDER_CONSTRUCTION" : "MOVE_IN_READY";
+}
+
 /**
  * Parse ONE Oakwood Homes per-home page (Nuxt SSR) into a home, or null if the
  * page carries no available-home object (a 404 / non-home page slipped through).
@@ -215,9 +231,11 @@ export function parseHome(html: string): OakHome | null {
     posNum(kova.NumBaths) ?? (fullBaths === null ? null : fullBaths + (halfBaths ?? 0) * 0.5);
 
   const estCompletion = toIsoDate(kova.EstComplDate);
-  const constructionStatus: OakHome["constructionStatus"] = estCompletion
-    ? "UNDER_CONSTRUCTION"
-    : "MOVE_IN_READY";
+  // Prefer the authoritative KOVA sales-order Status (deterministic, in the payload) when it
+  // carries an unambiguous signal; otherwise fall back to the presence-of-completion-date
+  // heuristic (kept deterministic — a wall-clock "is it future?" check would violate the
+  // same-bytes-in/same-records-out extract contract).
+  const constructionStatus = classifyStatus(kova.Status, estCompletion);
 
   const invId = kova.SlsOrdRID ?? home.sales_order_rid;
 

← d3c30ea1 TK-10487: build Goodall + Brohn + Oakwood CPG per-brand adap  ·  back to Homesonspec  ·  auto-data-snapshot: 2026-08-12T09:25:42 (2 data files) — col 1b56601e →