diff --git a/infrastructure/postgres/epc_property_table.py b/infrastructure/postgres/epc_property_table.py index c08e6c8c5..2cbe8c932 100644 --- a/infrastructure/postgres/epc_property_table.py +++ b/infrastructure/postgres/epc_property_table.py @@ -680,6 +680,11 @@ class EpcBuildingPartModel(SQLModel, table=True): # to the gov-API code-6 heuristic", `False` means "explicitly system-built, # do NOT apply the heuristic". Collapsing False to None inverts the answer. wall_is_basement: Optional[bool] = Field(default=None) + # #1665: lodged wall U (gov-EPC `wall_u_value`), authoritative over the + # derived default when present; dropped it fell back to the age-band default + # (-2.32 SAP). The prior allowlist "RdSAP uses defaults" was stale — the + # cascade does honour the lodged U on the API path. + wall_u_value: Optional[float] = Field(default=None) room_in_roof_floor_area: Optional[float] = Field(default=None) room_in_roof_construction_age_band: Optional[str] = Field(default=None) alt_wall_1_area: Optional[float] = Field(default=None) @@ -740,6 +745,7 @@ class EpcBuildingPartModel(SQLModel, table=True): roof_insulation_thickness=part.roof_insulation_thickness, rafter_insulation_thickness=part.rafter_insulation_thickness, wall_is_basement=part.wall_is_basement, + wall_u_value=part.wall_u_value, room_in_roof_floor_area=float(rir.floor_area) if rir else None, room_in_roof_construction_age_band=( rir.construction_age_band if rir else None diff --git a/repositories/epc/epc_postgres_repository.py b/repositories/epc/epc_postgres_repository.py index e4d16577f..b53fe81a1 100644 --- a/repositories/epc/epc_postgres_repository.py +++ b/repositories/epc/epc_postgres_repository.py @@ -1185,6 +1185,7 @@ class EpcPostgresRepository(EpcRepository): roof_insulation_thickness=bp.roof_insulation_thickness, rafter_insulation_thickness=bp.rafter_insulation_thickness, wall_is_basement=bp.wall_is_basement, + wall_u_value=bp.wall_u_value, # Reconstruct from the epc_room_in_roof child table (full geometry # incl. detailed_surfaces); the flat room_in_roof_* columns on # epc_building_part are superseded and dropped in a follow-up (#1664). diff --git a/tests/repositories/epc/test_epc_persistence_field_coverage.py b/tests/repositories/epc/test_epc_persistence_field_coverage.py index 440179dd6..a43ba20e7 100644 --- a/tests/repositories/epc/test_epc_persistence_field_coverage.py +++ b/tests/repositories/epc/test_epc_persistence_field_coverage.py @@ -59,7 +59,6 @@ _UNPERSISTED_ALLOWLIST: dict[str, str] = { # `wall_is_basement` is deliberately NOT in this list — it is a # disambiguation flag selecting which RdSAP default applies (§5.17/Table 23), # not a measured U-value, and it IS persisted. - "SapBuildingPart.wall_u_value": "deliberate — full-SAP only; RdSAP re-model uses default U-values (#1656)", "SapBuildingPart.roof_u_value": "deliberate — full-SAP only; RdSAP re-model uses default U-values (#1656)", "SapBuildingPart.floor_u_value": "deliberate — full-SAP only; RdSAP re-model uses default U-values (#1656)", }