Normalize RdSAP MVHR PCDF index + duct type on the 21.0.0 path

PRD #1385 phase 2. The 21.0.0 mapper dropped mechanical_ventilation_index_number
and mechanical_vent_duct_type, unlike 21.0.1. cert_to_inputs reads both (PCDB
Table 4f/329 heat-recovery/SFP lookup + the Table 329 in-use factor), so an
MVHR/MEV cert on the 21.0.0 path fell back to the SAP default efficiency.

Mirrors 21.0.1 exactly -- only the two fields it actually maps. The other four
mechanical_vent_duct_* schema fields have no mapper OR calculator consumer even
on 21.0.1 (verified), so they're deliberately left alone rather than populating
dead domain fields.

Verification: new test 1 passed (harvested 21.0.0 sample lodges index=12,
duct_type=3); corpus 6002 passed; SAP-accuracy regressions pass; pyright
unchanged (39 -> 39).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jun-te Kim 2026-07-01 14:24:12 +00:00
parent e95c3cf906
commit 7ee33b9ce8
2 changed files with 49 additions and 0 deletions

View file

@ -2178,6 +2178,15 @@ class EpcPropertyDataMapper:
# unlike every other path (17.0/…/21.0.1). Understated the §2
# draughtproofing/infiltration credit.
percent_draughtproofed=schema.percent_draughtproofed,
# 21.0.0 lodges the MVHR/MEV PCDF index + duct type but the mapper
# dropped both, unlike 21.0.1. The index feeds the PCDB Table 4f/329
# heat-recovery/SFP lookup and duct_type selects the Table 329 in-use
# factor (1=Flexible / 2=Rigid) — without them an MVHR/MEV cert on the
# 21.0.0 path fell back to the SAP default efficiency.
mechanical_ventilation_index_number=(
schema.mechanical_ventilation_index_number
),
mechanical_vent_duct_type=schema.mechanical_vent_duct_type,
led_fixed_lighting_bulbs_count=schema.led_fixed_lighting_bulbs_count or 0,
cfl_fixed_lighting_bulbs_count=schema.cfl_fixed_lighting_bulbs_count or 0,
incandescent_fixed_lighting_bulbs_count=schema.incandescent_fixed_lighting_bulbs_count,

View file

@ -0,0 +1,40 @@
"""Regression: the RdSAP-Schema-21.0.0 mapper must carry the lodged MVHR/MEV PCDF
index + duct type, like the 21.0.1 path.
PRD #1385 phase 2. 21.0.0 dropped `mechanical_ventilation_index_number` and
`mechanical_vent_duct_type`, so an MVHR/MEV cert on this path lost its PCDB
Table 4f/329 heat-recovery lookup (`cert_to_inputs` reads both). Only the two
fields 21.0.1 actually maps are carried; the other four
`mechanical_vent_duct_*` schema fields have no mapper or calculator consumer even
on 21.0.1, so they are deliberately left alone.
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from datatypes.epc.domain.mapper import EpcPropertyDataMapper
# The harvested 21.0.0 sample lodges index_number=12, duct_type=3.
_FIXTURE = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.0/epc.json")
def _load() -> dict[str, Any]:
data: dict[str, Any] = json.loads(_FIXTURE.read_text())
assert data["schema_type"] == "RdSAP-Schema-21.0.0"
return data
def test_21_0_0_carries_mvhr_index_and_duct_type() -> None:
data = _load()
assert data["mechanical_ventilation_index_number"] == 12
assert data["mechanical_vent_duct_type"] == 3
epc = EpcPropertyDataMapper.from_api_response(data)
# Both were dropped to None on the 21.0.0 path; now carried through so
# cert_to_inputs can drive the PCDB heat-recovery lookup.
assert epc.mechanical_ventilation_index_number == 12
assert epc.mechanical_vent_duct_type == 3