From 6faa5171aff623a12aba6d669ab8ef370ad15ad2 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 26 Jun 2026 18:54:43 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20reconstruct=20top-level=20extract=5Ffan?= =?UTF-8?q?s=5Fcount=20from=20its=20persisted=20mirror=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The deterministic calculator reads sap_ventilation.extract_fans_count (which already round-trips); the top-level epc.extract_fans_count is its mirror (the mapper sets both from one source). Reconstruct it from the same column so EpcPropertyData round-trips complete, dropping the allow-list exception. Co-Authored-By: Claude Opus 4.8 (1M context) --- repositories/epc/epc_postgres_repository.py | 6 ++++++ .../repositories/epc/test_epc_persistence_field_coverage.py | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/repositories/epc/epc_postgres_repository.py b/repositories/epc/epc_postgres_repository.py index 3f4e09b1..60383fd1 100644 --- a/repositories/epc/epc_postgres_repository.py +++ b/repositories/epc/epc_postgres_repository.py @@ -582,6 +582,12 @@ class EpcPostgresRepository(EpcRepository): else None ), multiple_glazed_proportion=p.multiple_glazed_proportion, + # Top-level mirror of sap_ventilation.extract_fans_count (the mapper + # sets both from the same source). The deterministic calculator reads + # the sap_ventilation copy, not this one; reconstruct it from the same + # column anyway so EpcPropertyData round-trips complete, with no + # allow-list exception for a field that trivially mirrors a persisted one. + extract_fans_count=p.ventilation_extract_fans_count, calculation_software_version=p.calculation_software_version, mechanical_vent_duct_placement=p.mechanical_vent_duct_placement, mechanical_vent_duct_insulation=p.mechanical_vent_duct_insulation, diff --git a/tests/repositories/epc/test_epc_persistence_field_coverage.py b/tests/repositories/epc/test_epc_persistence_field_coverage.py index 6f9481d8..4f0c8faa 100644 --- a/tests/repositories/epc/test_epc_persistence_field_coverage.py +++ b/tests/repositories/epc/test_epc_persistence_field_coverage.py @@ -35,10 +35,6 @@ from repositories.epc.epc_postgres_repository import EpcPostgresRepository # ``ClassName.field`` (a single field) or ``ClassName`` (the whole dataclass is # an un-persisted, tracked gap awaiting its FE columns / child table). _UNPERSISTED_ALLOWLIST: dict[str, str] = { - # Redundant top-level field: the calculator reads - # `sap_ventilation.extract_fans_count` (which round-trips via - # `_to_ventilation`), never this top-level duplicate. - "EpcPropertyData.extract_fans_count": "redundant; scoring uses sap_ventilation.extract_fans_count", # Not read by the calculator (dormant); no DB column yet. "EpcPropertyData.air_tightness": "dormant — not read by the calculator; no FE column", "EpcPropertyData.lzc_energy_sources": "dormant — not read by the calculator; no FE column",