Default RdSAP 21.0.1 wet_rooms_count to 0 (fix NOT-NULL violation)

37 modelling_e2e properties failed on the 2026-06-23 run with
`NotNullViolation: null value in column "wet_rooms_count" of relation
"epc_property"`.

Root cause: 21.0.1 lodges `wet_rooms_count` as Optional, and
`from_rdsap_schema_21_0_1` passed it straight through
(`wet_rooms_count=schema.wet_rooms_count`). A cert omitting it mapped to
`EpcPropertyData.wet_rooms_count=None`. When a predicted EPC (which deep-copies
a comparable template's EpcPropertyData) inherited that None and was persisted,
it violated the `epc_property.wet_rooms_count` NOT-NULL column — and the calc's
`wet_rooms_count > 0` check would also raise `TypeError` on None.

Fix: coalesce to 0, matching every other mapper (RdSAP "not lodged" → the
calc's minimum 1 wet room). Regression test added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jun-te Kim 2026-06-24 07:42:34 +00:00
parent 09ec985f98
commit 4fe59b8e78
2 changed files with 20 additions and 1 deletions

View file

@ -2150,7 +2150,10 @@ class EpcPropertyDataMapper:
door_count=schema.door_count,
habitable_rooms_count=schema.habitable_room_count,
heated_rooms_count=schema.heated_room_count,
wet_rooms_count=schema.wet_rooms_count,
# 21.0.1 lodges wet_rooms_count as Optional; None violates the
# epc_property NOT-NULL column (and the calc's `> 0` check). Coalesce
# to 0 like every other mapper (RdSAP "not lodged" → calc minimum 1).
wet_rooms_count=schema.wet_rooms_count or 0,
extensions_count=schema.extensions_count,
open_chimneys_count=schema.open_chimneys_count,
insulated_door_count=schema.insulated_door_count,

View file

@ -379,6 +379,22 @@ class TestFromRdSapSchema21_0_1:
# --- general ---
def test_omitted_wet_rooms_count_defaults_to_zero_not_none(self) -> None:
# 21.0.1 lodges wet_rooms_count as Optional, so a cert that omits it
# mapped to EpcPropertyData.wet_rooms_count=None. That None then
# violated the epc_property.wet_rooms_count NOT-NULL constraint when a
# predicted EPC (which deep-copies a comparable template) was persisted,
# and would crash the calc's `wet_rooms_count > 0` check. 37 modelling_e2e
# properties failed on the 2026-06-23 run for this reason. Default to 0,
# matching every other mapper (RdSAP 0 → calc's Table-?? minimum 1 fan).
data = load("21_0_1.json")
data.pop("wet_rooms_count", None)
schema = from_dict(RdSapSchema21_0_1, data)
result = EpcPropertyDataMapper.from_rdsap_schema_21_0_1(schema)
assert result.wet_rooms_count == 0
def test_uprn(self, result: EpcPropertyData) -> None:
assert result.uprn == 12457