diff --git a/src/app/db/schema/property.ts b/src/app/db/schema/property.ts index 58ed1d4c..be78f0d1 100644 --- a/src/app/db/schema/property.ts +++ b/src/app/db/schema/property.ts @@ -174,6 +174,10 @@ export const property = pgTable( uniqueIndex("uq_property_portfolio_uprn") .on(table.portfolioId, table.uprn) .where(sql`${table.uprn} IS NOT NULL`), + // Plain `portfolio_id = ?` filters (reporting, portfolio list) — the + // partial unique above only covers rows WHERE uprn IS NOT NULL, so the + // planner can't use it for these. + index("ix_property_portfolio").on(table.portfolioId), ], ); @@ -782,6 +786,11 @@ export const epcBuildingPart = pgTable( altWall2InsulationThickness: text("alt_wall_2_insulation_thickness"), altWall2IsSheltered: boolean("alt_wall_2_is_sheltered"), // nullable (null when no alt wall) }, + (table) => [ + // Per-EPC part lookups: the reporting age-band subquery and the + // condition-report / descriptor resolvers all filter on epc_property_id. + index("ix_epc_building_part_epc_property").on(table.epcPropertyId), + ], ); // ─── epc_floor_dimension ────────────────────────────────────────────────────── @@ -804,6 +813,11 @@ export const epcFloorDimension = pgTable( isExposedFloor: boolean("is_exposed_floor").notNull().default(false), isAbovePartiallyHeatedSpace: boolean("is_above_partially_heated_space").notNull().default(false), }, + (table) => [ + // Condition-report floor-height/storey lookups fetch all dimensions for + // one building part. + index("ix_epc_floor_dimension_building_part").on(table.epcBuildingPartId), + ], ); // ─── epc_window ─────────────────────────────────────────────────────────────── @@ -870,6 +884,10 @@ export const epcEnergyElement = pgTable( energyEfficiencyRating: integer("energy_efficiency_rating").notNull(), environmentalEfficiencyRating: integer("environmental_efficiency_rating").notNull(), }, + (table) => [ + // Condition-report fabric lookups fetch all elements for one EPC. + index("ix_epc_energy_element_epc_property").on(table.epcPropertyId), + ], ); // ─── epc_renewable_heat_incentive ─────────────────────────────────────────────