mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Persist cylinder_heat_loss so it survives the DB round-trip 🟩
SapHeating.cylinder_heat_loss is read by the calculator (cert_to_inputs §4 cylinder loss) but had no column, so it was silently dropped on save: a dwelling reloaded from Postgres lost its lodged cylinder loss and fell back to the Table 2b age-band default — worst case -15.53 SAP over the corpus round-trip (#1665). Add heating_cylinder_heat_loss (nullable double precision) to EpcPropertyModel, write it in from_domain and reconstruct it in the SapHeating compose path, mirroring heating_cylinder_volume_measured_l. Remove the now-false _UNPERSISTED_ALLOWLIST entry ("dormant — not read by the calculator") so the ADR structural guard enforces it. Verified: worst cylinder cert 10091630692 round-trip -15.53 -> 0.0000. Companion assessment-model migration (heating_cylinder_heat_loss column) must land + be applied per-environment before the backend deploys (deploy gate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
164937b9e5
commit
6d2982f826
3 changed files with 5 additions and 1 deletions
|
|
@ -168,6 +168,9 @@ class EpcPropertyModel(SQLModel, table=True):
|
|||
)
|
||||
heating_cylinder_insulation_thickness_mm: Optional[int] = Field(default=None)
|
||||
heating_cylinder_volume_measured_l: Optional[int] = Field(default=None)
|
||||
# #1665: read by cert_to_inputs (§4 cylinder loss); dropping it billed the
|
||||
# cylinder at the Table 2b age-band default (worst case -15.53 SAP).
|
||||
heating_cylinder_heat_loss: Optional[float] = Field(default=None)
|
||||
heating_wwhrs_index_number_1: Optional[int] = Field(default=None)
|
||||
heating_wwhrs_index_number_2: Optional[int] = Field(default=None)
|
||||
heating_shower_outlet_type: Optional[Union[int, str]] = Field(
|
||||
|
|
@ -359,6 +362,7 @@ class EpcPropertyModel(SQLModel, table=True):
|
|||
heating_secondary_heating_type=h.secondary_heating_type,
|
||||
heating_cylinder_insulation_thickness_mm=h.cylinder_insulation_thickness_mm,
|
||||
heating_cylinder_volume_measured_l=h.cylinder_volume_measured_l,
|
||||
heating_cylinder_heat_loss=h.cylinder_heat_loss,
|
||||
heating_wwhrs_index_number_1=h.instantaneous_wwhrs.wwhrs_index_number1,
|
||||
heating_wwhrs_index_number_2=h.instantaneous_wwhrs.wwhrs_index_number2,
|
||||
heating_shower_outlet_type=shower.shower_outlet_type if shower else None,
|
||||
|
|
|
|||
|
|
@ -909,6 +909,7 @@ class EpcPostgresRepository(EpcRepository):
|
|||
secondary_heating_type=p.heating_secondary_heating_type,
|
||||
cylinder_insulation_thickness_mm=p.heating_cylinder_insulation_thickness_mm,
|
||||
cylinder_volume_measured_l=p.heating_cylinder_volume_measured_l,
|
||||
cylinder_heat_loss=p.heating_cylinder_heat_loss,
|
||||
number_baths=p.heating_number_baths,
|
||||
number_baths_wwhrs=p.heating_number_baths_wwhrs,
|
||||
electric_shower_count=p.heating_electric_shower_count,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ _UNPERSISTED_ALLOWLIST: dict[str, str] = {
|
|||
"SapRoomInRoofSurface": "FE child table pending — room-in-roof surface detail",
|
||||
# --- Nested gaps the calculator does NOT read (dormant); no FE column.
|
||||
"SapAlternativeWall.is_basement": "dormant — not read by the calculator; no FE column",
|
||||
"SapHeating.cylinder_heat_loss": "dormant — not read by the calculator; no FE column",
|
||||
# --- DELIBERATELY not persisted (#1656). These four ARE read by the
|
||||
# calculator (`heat_transmission.py:994` wall U, `:1068` roof U, `:1118`
|
||||
# floor U, `:955` basement wall) — do NOT re-label them "not read by the
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue