From 939cfcbee5d2fdfa7e34ddbecedb8eb26e32f9fb Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 24 Jul 2026 13:50:30 +0000 Subject: [PATCH] =?UTF-8?q?Classify=20by=20design-document=20presence=20th?= =?UTF-8?q?rough=20the=20whole=20pipeline=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../your-projects/live/transforms.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/transforms.test.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/transforms.test.ts index fbd7b6d3..cec5ed4e 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/transforms.test.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/transforms.test.ts @@ -385,6 +385,15 @@ describe("resolveDisplayStage — after-coordination precedence (downstream evid ) ).toBe("At Post Survey"); }); + + it("does NOT return Installation in Progress for designStatus UPLOADED when the design document is absent (regression for the reported bug)", () => { + // The HubSpot designStatus flag can be set before — or without — the + // Retrofit Design Document ever being uploaded. It must no longer push a + // Property into Installation in Progress. + expect( + resolveDisplayStage(makeCoordinationCompleteDeal({ designStatus: "UPLOADED" }), false) + ).toBe("Design in Progress"); + }); }); describe("resolveDisplayStage — design-document presence drives the Design/Installation boundary", () => { @@ -435,6 +444,19 @@ describe("classifyDeals", () => { expect(result.dealId).toBe("abc-123"); expect(result.dealname).toBe("Test"); }); + + it("classifies a coordination-complete deal as Installation in Progress only when its id is in the design-document set", () => { + // Arrange + const withDoc = makeDeal({ dealId: "has-doc", coordinationStatus: "(V1) IOE/MTP COMPLETE" }); + const withoutDoc = makeDeal({ dealId: "no-doc", coordinationStatus: "(V1) IOE/MTP COMPLETE" }); + + // Act + const [a, b] = classifyDeals([withDoc, withoutDoc], new Set(["has-doc"])); + + // Assert + expect(a.displayStage).toBe("Installation in Progress"); + expect(b.displayStage).toBe("Design in Progress"); + }); }); // ----------------------------------------------------------------------- @@ -701,6 +723,25 @@ describe("computeLiveTrackerData", () => { expect(result.projects).toHaveLength(0); expect(result.totalDeals).toBe(0); }); + + it("reflects design-document presence in the project roll-up stage counts", () => { + // Arrange — two coordination-complete deals in one project, one with a + // Retrofit Design Document and one without. + const deals = [ + makeDeal({ projectCode: "PROJ-A", dealId: "has-doc", coordinationStatus: "(V1) IOE/MTP COMPLETE" }), + makeDeal({ projectCode: "PROJ-A", dealId: "no-doc", coordinationStatus: "(V1) IOE/MTP COMPLETE" }), + ]; + + // Act + const result = computeLiveTrackerData(deals, new Set(["has-doc"])); + + // Assert + const stageProgress = result.projects[0].progress.stageProgress; + const design = stageProgress.find((s) => s.stage === "Design in Progress")!; + const install = stageProgress.find((s) => s.stage === "Installation in Progress")!; + expect(design.count).toBe(1); + expect(install.count).toBe(1); + }); }); describe("hasMajorConditionIssue", () => {