From f3e00429f997fcfbab1b92f1b737cc21bfa4dae4 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 17 Jun 2026 01:07:00 +0000 Subject: [PATCH] fix(epc): source baseline carbon/energy/bills from lodged columns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per domain semantics: lodged_* on property_baseline_performance is the gov-registry (actual) figure, effective_* is the modelling-adjusted baseline. Use the lodged columns for the "current" carbon/primary-energy display and the individual cost columns (summed) for bills. Bills return NULL when no baseline row exists, so they're excluded from AVG/SUM rather than shown as £0. (property_baseline_performance is still unwritten DB-wide; this makes the reads correct for when the pipeline populates it.) Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app/portfolio/[slug]/utils.ts | 2 +- src/lib/services/epcSources.ts | 41 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/app/portfolio/[slug]/utils.ts b/src/app/portfolio/[slug]/utils.ts index 6025ebfd..316f67a8 100644 --- a/src/app/portfolio/[slug]/utils.ts +++ b/src/app/portfolio/[slug]/utils.ts @@ -778,7 +778,7 @@ export async function getProperties( epl.registration_date, epl.inspection_date, epl.total_floor_area_m2, - bp.effective_co2_emissions_t_per_yr, + bp.lodged_co2_emissions_t_per_yr, p.lexiscore LIMIT ${limit} OFFSET ${offset}; `); diff --git a/src/lib/services/epcSources.ts b/src/lib/services/epcSources.ts index 540f073c..b5c3d78a 100644 --- a/src/lib/services/epcSources.ts +++ b/src/lib/services/epcSources.ts @@ -73,22 +73,39 @@ export const newApproachJoins = sql` LEFT JOIN epc_property epp ON epp.property_id = p.id AND epp.source = 'predicted' `; -/** Baseline carbon (t CO₂/yr). New: effective performance. Legacy: e.co2_emissions. */ +/** + * Baseline carbon (t CO₂/yr). New: the lodged (gov-registry) value. Legacy: + * e.co2_emissions. Swap to `effective_co2_emissions_t_per_yr` if the + * modelling-adjusted baseline is wanted instead. + */ export const carbonSql = (e: Alias) => - sql`CASE WHEN ${isNewApproachSql} THEN bp.effective_co2_emissions_t_per_yr ELSE ${e}.co2_emissions END`; + sql`CASE WHEN ${isNewApproachSql} THEN bp.lodged_co2_emissions_t_per_yr ELSE ${e}.co2_emissions END`; -/** Primary energy intensity (kWh/m²/yr). New: effective performance. Legacy: e.primary_energy_consumption. */ +/** Primary energy intensity (kWh/m²/yr). New: lodged value. Legacy: e.primary_energy_consumption. */ export const energyConsumptionSql = (e: Alias) => - sql`CASE WHEN ${isNewApproachSql} THEN bp.effective_primary_energy_intensity_kwh_per_m2_yr ELSE ${e}.primary_energy_consumption END`; + sql`CASE WHEN ${isNewApproachSql} THEN bp.lodged_primary_energy_intensity_kwh_per_m2_yr ELSE ${e}.primary_energy_consumption END`; /** - * Annual energy bill (£). New: property_baseline_performance.total_annual_bill_gbp - * (NULL when the bill block hasn't been derived yet — excluded from AVG/SUM). - * Legacy: the old component-sum formula incl. standing charges and the - * installed-measures adjustment. + * Annual energy bill (£). New: sum of the individual cost columns on + * property_baseline_performance (NULL when no baseline row exists, so it's + * excluded from AVG/SUM rather than counted as £0). Legacy: the old + * component-sum formula incl. standing charges and the installed-measures + * adjustment. */ export const billsSql = (e: Alias) => - sql`CASE WHEN ${isNewApproachSql} THEN bp.total_annual_bill_gbp ELSE ( + sql`CASE WHEN ${isNewApproachSql} THEN ( + CASE WHEN bp.id IS NULL THEN NULL ELSE ( + COALESCE(bp.heating_cost_gbp, 0) + + COALESCE(bp.hot_water_cost_gbp, 0) + + COALESCE(bp.lighting_cost_gbp, 0) + + COALESCE(bp.appliances_cost_gbp, 0) + + COALESCE(bp.cooking_cost_gbp, 0) + + COALESCE(bp.pumps_fans_cost_gbp, 0) + + COALESCE(bp.cooling_cost_gbp, 0) + + COALESCE(bp.standing_charges_gbp, 0) - + COALESCE(bp.seg_credit_gbp, 0) + ) END + ) ELSE ( ${e}.heating_cost_current + ${e}.hot_water_cost_current + ${e}.lighting_cost_current + @@ -272,8 +289,8 @@ async function resolveNewConditionReport( energyTariff: null, currentEnergyDemand: sumKwh, primaryEnergyConsumption: - baseline?.effectivePrimaryEnergyIntensityKwhPerM2Yr ?? null, - co2Emissions: baseline?.effectiveCo2EmissionsTPerYr ?? null, + baseline?.lodgedPrimaryEnergyIntensityKwhPerM2Yr ?? null, + co2Emissions: baseline?.lodgedCo2EmissionsTPerYr ?? null, heatingEnergyCostCurrent: baseline?.heatingCostGbp ?? null, hotWaterEnergyCostCurrent: baseline?.hotWaterCostGbp ?? null, lightingEnergyCostCurrent: baseline?.lightingCostGbp ?? null, @@ -395,7 +412,7 @@ export async function resolveDetailsEpcMeta( return { currentEnergyDemand, - co2Emissions: baseline?.effectiveCo2EmissionsTPerYr ?? null, + co2Emissions: baseline?.lodgedCo2EmissionsTPerYr ?? null, estimated: !lodged && !!predicted, }; }