From 7841e4a5568c201d3f7d460d650566222f4df7c6 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 12 May 2026 13:12:14 +0000 Subject: [PATCH] xtracted duplicated removal state logic into a shared module. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created removalState.ts with two functions: deriveEffectiveRemovalState (single DB row → EffectiveRemovalState) and computeRemovalStatusByDeal (ordered rows → RemovalStatusByDeal map, owns deduplication). Created removalState.test.ts with 11 tests covering all 6 (type, status) combinations and the map-building edge cases (empty input, deduplication, none entries excluded). live/page.tsx: replaced a 14-line seen-set loop with a single computeRemovalStatusByDeal(removalRows) call. live/[dealId]/page.tsx: replaced an if/else block with deriveEffectiveRemovalState(removalRows[0]). --- .../your-projects/live/[dealId]/page.tsx | 18 +++++----------- .../(portfolio)/your-projects/live/page.tsx | 21 ++----------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/[dealId]/page.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/[dealId]/page.tsx index 08d2561..18dfe69 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/[dealId]/page.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/[dealId]/page.tsx @@ -10,7 +10,8 @@ import { portfolioCapabilities, portfolioUsers } from "@/app/db/schema/portfolio import { dealMeasureApprovals } from "@/app/db/schema/approvals"; import { propertyRemovalRequests } from "@/app/db/schema/removal_requests"; import { user as userTable } from "@/app/db/schema/users"; -import type { DocStatus, PortfolioCapabilityType, EffectiveRemovalState } from "../types"; +import type { DocStatus, PortfolioCapabilityType } from "../types"; +import { deriveEffectiveRemovalState } from "../removalState"; import { classifyDeals } from "../transforms"; import { fetchDocsByDealId, computeDocStatusMap } from "../docStatus"; import { coordinatorUser, designerUser, mapDbRowToHubspotDeal } from "../dealQuery"; @@ -131,7 +132,6 @@ export default async function DealDetailPage(props: { ); approvedMeasures.push(...approvalRows.map((r) => r.measureName)); - let removalState: EffectiveRemovalState = "none"; const removalRows = await db .select({ type: propertyRemovalRequests.type, @@ -147,17 +147,9 @@ export default async function DealDetailPage(props: { .orderBy(desc(propertyRemovalRequests.requestedAt)) .limit(1); - if (removalRows[0]) { - const row = removalRows[0]; - if (row.status === "pending") { - removalState = - row.type === "re_addition" ? "pending_re_addition" : "pending_removal"; - } else if (row.type === "removal" && row.status === "approved") { - removalState = "removed"; - } else if (row.type === "re_addition" && row.status === "declined") { - removalState = "removed"; - } - } + const removalState = removalRows[0] + ? deriveEffectiveRemovalState(removalRows[0]) + : "none"; const docsByDealId = await fetchDocsByDealId([hubspotDeal], [dealId]); const docStatusMap = computeDocStatusMap([hubspotDeal], docsByDealId, { [dealId]: approvedMeasures }); diff --git a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/page.tsx b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/page.tsx index 87a9a7a..6b50ee9 100644 --- a/src/app/portfolio/[slug]/(portfolio)/your-projects/live/page.tsx +++ b/src/app/portfolio/[slug]/(portfolio)/your-projects/live/page.tsx @@ -24,8 +24,8 @@ import type { ApprovalsByDeal, InstructedMeasuresByDeal, RemovalStatusByDeal, - EffectiveRemovalState, } from "./types"; +import { computeRemovalStatusByDeal } from "./removalState"; import { Card, CardContent } from "@/app/shadcn_components/ui/card"; import { Building2 } from "lucide-react"; @@ -206,8 +206,6 @@ export default async function LiveReportingPage(props: { } } - // Compute effective removal state per deal - const removalStatusByDeal: RemovalStatusByDeal = {}; const removalRows = await db .select({ hubspotDealId: propertyRemovalRequests.hubspotDealId, @@ -218,22 +216,7 @@ export default async function LiveReportingPage(props: { .where(eq(propertyRemovalRequests.portfolioId, BigInt(portfolioId))) .orderBy(desc(propertyRemovalRequests.requestedAt)); - // Keep only the most recent row per deal, then derive effective state - const seenDeals = new Set(); - for (const row of removalRows) { - if (seenDeals.has(row.hubspotDealId)) continue; - seenDeals.add(row.hubspotDealId); - let state: EffectiveRemovalState = "none"; - if (row.status === "pending") { - state = - row.type === "re_addition" ? "pending_re_addition" : "pending_removal"; - } else if (row.type === "removal" && row.status === "approved") { - state = "removed"; - } else if (row.type === "re_addition" && row.status === "declined") { - state = "removed"; - } - if (state !== "none") removalStatusByDeal[row.hubspotDealId] = state; - } + const removalStatusByDeal: RemovalStatusByDeal = computeRemovalStatusByDeal(removalRows); const docsByDealId = await fetchDocsByDealId(deals, dealIds); const docStatusMap = computeDocStatusMap(deals, docsByDealId, approvalsByDeal);