From 61be9a477c6fccc0288b28547438513dcba93f03 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 19 May 2026 08:17:17 +0000 Subject: [PATCH 1/6] pas significance file is not expected --- .../portfolio/[slug]/(portfolio)/your-projects/live/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts index e1be10c1..f453b08e 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts @@ -239,7 +239,6 @@ export const EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES = [ "rd_sap_site_note", "pas_2023_ventilation", "pas_2023_condition", - "pas_significance", "par_photo_pack", "pas_2023_property", "pas_2023_occupancy", @@ -251,6 +250,7 @@ export const SURVEY_ALL_DOC_TYPES = new Set([ "ecmk_site_note", "ecmk_rd_sap_site_note", "ecmk_survey_xml", + "pas_significance", ]); // Per-measure document upload progress From f99374a16ff90ba3ab14c6e8c05e7ab1ecddcbc0 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 19 May 2026 08:30:57 +0000 Subject: [PATCH 2/6] list coordination and design documents in their own sections --- .../live/PropertyDocumentsContent.tsx | 45 +++++++++++++++++-- .../live/propertyDocuments.test.ts | 10 ++--- .../your-projects/live/propertyDocuments.ts | 10 ++++- .../(portfolio)/your-projects/live/types.ts | 11 +++++ 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx index 102c2fb5..50a9410e 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx @@ -59,6 +59,9 @@ export const DOC_TYPE_LABELS: Record = { installer_qualifications: "Installer Qualifications", installer_feedback: "Installer Feedback", contractor_other: "Other", + improvement_option_evaluation: "Improvement Option Evaluation", + medium_term_improvement_plan: "Medium Term Improvement Plan", + retrofit_design_doc: "Retrofit Design Document" }; function formatDocDate(iso: string): string { @@ -172,8 +175,8 @@ export default function PropertyDocumentsContent({ return next; }); - const { retrofitDocs, installDocs } = splitDocumentsByType(documents); - const missingRetrofitTypes = getMissingRetrofitTypes(retrofitDocs); + const { docs: surveyDocs, coordinationDocs, designDocs, installDocs } = splitDocumentsByType(documents); + const missingRetrofitTypes = getMissingRetrofitTypes(surveyDocs); const hasDocuments = documents.length > 0; const isContractor = userCapability?.includes("contractor") ?? false; @@ -258,9 +261,9 @@ export default function PropertyDocumentsContent({

Retrofit Assessment Documents

- {retrofitDocs.length > 0 ? ( + {surveyDocs.length > 0 ? (
- {retrofitDocs.map((doc) => ( + {surveyDocs.map((doc) => ( ))}
@@ -287,6 +290,40 @@ export default function PropertyDocumentsContent({ )} + {/* Coordination Documents */} + +

+ Coordination Documents +

+ {coordinationDocs.length > 0 ? ( +
+ {coordinationDocs.map((doc) => ( + + ))} +
+ ) : ( +

None uploaded yet.

+ )} +
+ + {/* Design Documents */} + +

+ Design Documents +

+ {designDocs.length > 0 ? ( +
+ {designDocs.map((doc) => ( + + ))} +
+ ) : ( +

None uploaded yet.

+ )} +
+ + + {/* Install Documents */}

diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts index c81eb93b..36503d65 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts @@ -35,21 +35,21 @@ function makeMeasureProgress(overrides: Partial = {}): Measu describe("splitDocumentsByType", () => { it("puts survey doc types in retrofitDocs", () => { const doc = makeDoc({ docType: "photo_pack" }); - const { retrofitDocs, installDocs } = splitDocumentsByType([doc]); + const { docs: retrofitDocs, installDocs } = splitDocumentsByType([doc]); expect(retrofitDocs).toHaveLength(1); expect(installDocs).toHaveLength(0); }); it("puts install doc types in installDocs", () => { const doc = makeDoc({ docType: "pre_photo" }); - const { retrofitDocs, installDocs } = splitDocumentsByType([doc]); + const { docs: retrofitDocs, installDocs } = splitDocumentsByType([doc]); expect(retrofitDocs).toHaveLength(0); expect(installDocs).toHaveLength(1); }); it("includes optional ecmk types in retrofitDocs", () => { const doc = makeDoc({ docType: "ecmk_site_note" }); - const { retrofitDocs } = splitDocumentsByType([doc]); + const { docs: retrofitDocs } = splitDocumentsByType([doc]); expect(retrofitDocs).toHaveLength(1); }); @@ -60,13 +60,13 @@ describe("splitDocumentsByType", () => { makeDoc({ id: "3", docType: "site_note" }), makeDoc({ id: "4", docType: "post_photo" }), ]; - const { retrofitDocs, installDocs } = splitDocumentsByType(docs); + const { docs: retrofitDocs, installDocs } = splitDocumentsByType(docs); expect(retrofitDocs).toHaveLength(2); expect(installDocs).toHaveLength(2); }); it("returns empty arrays for empty input", () => { - const { retrofitDocs, installDocs } = splitDocumentsByType([]); + const { docs: retrofitDocs, installDocs } = splitDocumentsByType([]); expect(retrofitDocs).toHaveLength(0); expect(installDocs).toHaveLength(0); }); diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts index 65a5e9e5..84962476 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts @@ -1,15 +1,21 @@ import { SURVEY_ALL_DOC_TYPES, EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES, + COORDINATION_DOC_TYPES, + DESIGN_DOC_TYPES, } from "./types"; import type { PropertyDocument, MeasureDocProgress } from "./types"; export function splitDocumentsByType(docs: PropertyDocument[]): { - retrofitDocs: PropertyDocument[]; + docs: PropertyDocument[]; + coordinationDocs: PropertyDocument[]; + designDocs: PropertyDocument[]; installDocs: PropertyDocument[]; } { return { - retrofitDocs: docs.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.docType)), + docs: docs.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.docType)), + coordinationDocs: docs.filter((d) => COORDINATION_DOC_TYPES.has(d.docType)), + designDocs: docs.filter((d) => DESIGN_DOC_TYPES.has(d.docType)), installDocs: docs.filter((d) => !SURVEY_ALL_DOC_TYPES.has(d.docType)), }; } diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts index f453b08e..47bb9fba 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts @@ -253,6 +253,17 @@ export const SURVEY_ALL_DOC_TYPES = new Set([ "pas_significance", ]); +// Coordination doc types +export const COORDINATION_DOC_TYPES = new Set([ + "improvement_option_evaluation", + "medium_term_improvement_plan" +]); + +// Design doc types +export const DESIGN_DOC_TYPES = new Set([ + "retrofit_design_doc" +]); + // Per-measure document upload progress export type MeasureDocProgress = { measureName: string; From d292bb53c1ec309084fceddbc2e9bb4cec8d47c8 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 19 May 2026 10:30:59 +0000 Subject: [PATCH 3/6] coordination and design docs not listed under install --- .../(portfolio)/your-projects/live/propertyDocuments.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts index 84962476..f8f3cae8 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts @@ -16,7 +16,12 @@ export function splitDocumentsByType(docs: PropertyDocument[]): { docs: docs.filter((d) => SURVEY_ALL_DOC_TYPES.has(d.docType)), coordinationDocs: docs.filter((d) => COORDINATION_DOC_TYPES.has(d.docType)), designDocs: docs.filter((d) => DESIGN_DOC_TYPES.has(d.docType)), - installDocs: docs.filter((d) => !SURVEY_ALL_DOC_TYPES.has(d.docType)), + installDocs: docs.filter( + (d) => + !SURVEY_ALL_DOC_TYPES.has(d.docType) && + !COORDINATION_DOC_TYPES.has(d.docType) && + !DESIGN_DOC_TYPES.has(d.docType), + ), }; } From d75529904323d952c96787ff468d2c0c51ba991c Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 19 May 2026 10:32:18 +0000 Subject: [PATCH 4/6] Correctly separate install document categories --- .../[slug]/(portfolio)/your-projects/live/docStatus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/docStatus.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/docStatus.ts index 1bb7960d..9472b88b 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/docStatus.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/docStatus.ts @@ -93,7 +93,7 @@ export function computeDocStatusMap( approved.length > 0 ? approved : (deal.proposedMeasures ?? "") - .split(",") + .split(/[,;]/) .map((m) => m.trim()) .filter(Boolean); measuresByDealId.set(deal.dealId, measures); From c533bb3e80d326557036af22adf2f09ad8a97aac Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 19 May 2026 10:35:15 +0000 Subject: [PATCH 5/6] specify certain variables as survey --- .../live/PropertyDocumentsContent.tsx | 16 ++++++++-------- .../your-projects/live/propertyDocuments.test.ts | 10 +++++----- .../your-projects/live/propertyDocuments.ts | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx index 50a9410e..f8ff6d59 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/PropertyDocumentsContent.tsx @@ -16,7 +16,7 @@ import { } from "lucide-react"; import type { PropertyDocument, DocStatus } from "./types"; import { EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES } from "./types"; -import { splitDocumentsByType, getMissingRetrofitTypes, getUnassignedInstallDocs } from "./propertyDocuments"; +import { splitDocumentsByType, getMissingSurveyDocTypes, getUnassignedInstallDocs } from "./propertyDocuments"; import ContractorUploadModal from "./ContractorUploadModal"; import type { ClassifiedDeal, PortfolioCapabilityType } from "./types"; @@ -176,7 +176,7 @@ export default function PropertyDocumentsContent({ }); const { docs: surveyDocs, coordinationDocs, designDocs, installDocs } = splitDocumentsByType(documents); - const missingRetrofitTypes = getMissingRetrofitTypes(surveyDocs); + const missingSurveyDocTypes = getMissingSurveyDocTypes(surveyDocs); const hasDocuments = documents.length > 0; const isContractor = userCapability?.includes("contractor") ?? false; @@ -235,9 +235,9 @@ export default function PropertyDocumentsContent({

- Missing Documents ({missingRetrofitTypes.length}) + Missing Documents ({missingSurveyDocTypes.length})

- {missingRetrofitTypes.map((t) => ( + {missingSurveyDocTypes.map((t) => (
{/* Retrofit Assessment */} - +

Retrofit Assessment Documents

@@ -270,12 +270,12 @@ export default function PropertyDocumentsContent({ ) : (

None uploaded yet.

)} - {missingRetrofitTypes.length > 0 && ( + {missingSurveyDocTypes.length > 0 && (

- Missing ({missingRetrofitTypes.length}) + Missing ({missingSurveyDocTypes.length})

- {missingRetrofitTypes.map((t) => ( + {missingSurveyDocTypes.map((t) => (
{ describe("getMissingRetrofitTypes", () => { it("returns all mandatory types when no docs uploaded", () => { - const missing = getMissingRetrofitTypes([]); + const missing = getMissingSurveyDocTypes([]); expect(missing).toHaveLength(9); }); it("excludes types that have been uploaded", () => { const uploaded = [makeDoc({ docType: "photo_pack" })]; - const missing = getMissingRetrofitTypes(uploaded); + const missing = getMissingSurveyDocTypes(uploaded); expect(missing).not.toContain("photo_pack"); expect(missing).toHaveLength(8); }); @@ -91,12 +91,12 @@ describe("getMissingRetrofitTypes", () => { "pas_2023_condition", "pas_significance", "par_photo_pack", "pas_2023_property", "pas_2023_occupancy", ].map((docType, i) => makeDoc({ id: String(i), docType })); - expect(getMissingRetrofitTypes(uploaded)).toHaveLength(0); + expect(getMissingSurveyDocTypes(uploaded)).toHaveLength(0); }); it("does not count ecmk types as mandatory", () => { const uploaded = [makeDoc({ docType: "ecmk_site_note" })]; - const missing = getMissingRetrofitTypes(uploaded); + const missing = getMissingSurveyDocTypes(uploaded); expect(missing).not.toContain("ecmk_site_note"); expect(missing).toHaveLength(9); }); diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts index f8f3cae8..e9ebf415 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.ts @@ -25,8 +25,8 @@ export function splitDocumentsByType(docs: PropertyDocument[]): { }; } -export function getMissingRetrofitTypes(retrofitDocs: PropertyDocument[]): string[] { - const present = new Set(retrofitDocs.map((d) => d.docType)); +export function getMissingSurveyDocTypes(surveyDocs: PropertyDocument[]): string[] { + const present = new Set(surveyDocs.map((d) => d.docType)); return EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES.filter((t) => !present.has(t)); } From e22833041dd7f3e44ff10374c675c7cd92604843 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Wed, 20 May 2026 09:00:32 +0000 Subject: [PATCH 6/6] Correct required file type count in tests --- .../your-projects/live/propertyDocuments.test.ts | 6 +++--- .../[slug]/(portfolio)/your-projects/live/types.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts index 703ae6ee..76ba0136 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/propertyDocuments.test.ts @@ -75,14 +75,14 @@ describe("splitDocumentsByType", () => { describe("getMissingRetrofitTypes", () => { it("returns all mandatory types when no docs uploaded", () => { const missing = getMissingSurveyDocTypes([]); - expect(missing).toHaveLength(9); + expect(missing).toHaveLength(8); }); it("excludes types that have been uploaded", () => { const uploaded = [makeDoc({ docType: "photo_pack" })]; const missing = getMissingSurveyDocTypes(uploaded); expect(missing).not.toContain("photo_pack"); - expect(missing).toHaveLength(8); + expect(missing).toHaveLength(7); }); it("returns empty array when all mandatory types uploaded", () => { @@ -98,7 +98,7 @@ describe("getMissingRetrofitTypes", () => { const uploaded = [makeDoc({ docType: "ecmk_site_note" })]; const missing = getMissingSurveyDocTypes(uploaded); expect(missing).not.toContain("ecmk_site_note"); - expect(missing).toHaveLength(9); + expect(missing).toHaveLength(8); }); }); diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts index 47bb9fba..7f19cd2e 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/types.ts @@ -278,7 +278,7 @@ export type DocStatus = { // Retrofit assessment docs presentSurveyTypes: string[]; hasSurveyDocs: boolean; - isSurveyComplete: boolean; // all 9 EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES present (ecmk not counted) + isSurveyComplete: boolean; // all 8 EXPECTED_RETROFIT_ASSESSMENT_DOC_TYPES present (ecmk not counted) // Install docs hasInstallDocs: boolean; installStatus: "none" | "partial" | "hasDocs" | "all";