Model/datatypes/epc/schema
Khalim Conn-Kowlessar d501535cbc fix(mapper): map dropped §6.1 non-separated conservatory (API)
The gov API lodges a NON-SEPARATED conservatory (conservatory_type=4) as a
glazed "building part" carrying only {floor_area, room_height,
double_glazed, glazed_perimeter} — no fabric, no floor dimensions. The
four fields were undeclared on the 21.0.1 SapBuildingPart, so `from_dict`
dropped them and the conservatory was silently lost: it billed no §6.1
window/rooflight/floor and added nothing to TFA (5 corpus certs over-rated
— too little heat loss → SAP too high).

Fix (21.0.1 schema + mapper):
- declare the four glazed fields on `SapBuildingPart`;
- `_api_sap_conservatory` builds `EpcPropertyData.sap_conservatory` from
  the glazed BP (identified by a lodged `glazed_perimeter`; only type-4
  conservatories lodge it — separated ones, §6.2, lodge nothing);
- exclude the glazed BP from the fabric building-part loop (it is billed
  by the §6.1 cascade, not as a dwelling part);
- `_total_floor_area_from_building_parts` adds the conservatory floor area
  to TFA (drives occupancy → §4/§5 demand).

Validation is cross-mapper parity, NOT a corpus back-solve: the API mapper
feeds the SAME worksheet-validated §6.1 cascade (`conservatory_geometry`,
pinned to 1e-4 against the case-44 Summary) as the Elmhurst path — so the
API conservatory fabric is correct by construction. `from_api_response`
on an injected type-4 cert reproduces the glazed wall (perimeter × ground-
floor room height = 22.05), glazed roof (floor/cos20 = 12.77) and Table 25
double U_eff (2.758 wall / 2.993 roof); a separated (type 2/3) cert lodges
no glazed BP → disregarded per §6.2.

Gauges: corpus within-0.5 67.9% → 68.6% (MAE 0.959 → 0.942; floor 0.67→0.68,
ceiling 0.97→0.95); /tmp eval mean|err| 0.822 → 0.817. Harness 47/47
0-raised; regression = the 3 pre-existing fails; pyright net-zero (65=65).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 23:37:25 +00:00
..
tests Slice 44: flat_roof_insulation_thickness mapper fix — surface lodged value on SapBuildingPart 2026-05-24 15:28:10 +00:00
__init__.py first draft dataclasses with loading tests 2026-04-10 11:33:17 +00:00
common.py first draft dataclasses with loading tests 2026-04-10 11:33:17 +00:00
helpers.py slice 10.5: PhotovoltaicArray on SAP10 schema + EpcPropertyData 2026-05-16 16:00:25 +00:00
rdsap_schema_17_0.py Map RdSAP-Schema-17.0 certs to EpcPropertyData 🟩 2026-06-12 12:45:19 +00:00
rdsap_schema_17_1.py Dispatch and map RdSAP-Schema-17.1 certs end-to-end 🟩 2026-06-11 12:21:17 +00:00
rdsap_schema_18_0.py Map Not-Defined glazing code to a valid type for windowless 18.0 certs 🟩 2026-06-11 11:55:46 +00:00
rdsap_schema_19_0.py Map RdSAP-Schema-19.0 certs to EpcPropertyData 🟩 2026-06-12 12:29:36 +00:00
rdsap_schema_20_0_0.py fix(mapper): handle 'ND' multiple_glazing_type on RdSAP-Schema-20.0.0 2026-06-15 06:43:55 +00:00
rdsap_schema_21_0_0.py fix(mapper): map dropped §3.9.2 Simplified Type-2 room-in-roof (API) 2026-06-16 15:01:11 +00:00
rdsap_schema_21_0_1.py fix(mapper): map dropped §6.1 non-separated conservatory (API) 2026-06-16 23:37:25 +00:00