Model/backend/documents_parser/tests
Khalim Conn-Kowlessar 5402dd17e1 Slice S0380.24: SAP code 631 → house coal secondary fuel — closes cert 2102 -15.81 → +5e-5
Per SAP 10.2 spec page 165 Table 4a Category 10 (Room heaters), the
600-range secondary-heating SAP codes split by fuel:
  601-613: Gas (mains gas / LPG / biogas) — column A is mains gas.
  621-625: Liquid fuel room heaters (oil / bioethanol).
  631-634: Solid fuel room heaters (open fire, closed room heater
           with/without boiler) — house coal is the modal default.
  691-699: Electric room heaters.

`_elmhurst_secondary_fuel_from_sap_code` previously mapped the entire
601-630 range to mains gas (API code 26). Two bugs:
  1. Codes 621-625 are oil heaters, not gas. (Cohort hasn't surfaced
     an oil-secondary cert yet — deferred until a fixture exercises.)
  2. Codes 631-634 are solid fuel, not gas, and weren't in the range
     at all. Cascade fell through to the secondary-fuel-None default
     (standard electricity at 13.19 p/kWh), over-charging cert 2102's
     "Open fire in grate" secondary by ~£340/yr.

Narrow the gas range to 601-613 (per the spec) and add 631-634 → API
fuel code 11 (Coal in `_ELMHURST_MAIN_FUEL_TO_SAP10`) → Table 32
direct lookup returns 3.67 p/kWh (house coal), matching worksheet
(242) "Space heating - secondary 3585.2401 × 3.6700 = 131.58".

Cohort-2 outcome (38 certs, Summary path):
  exact (<1e-4): 20 → **21**  (+1: cert 2102 -15.81 → +5e-5)
  ±5+:           1 → **0**    (last big-gap closed)

Cert 2102 verified end-to-end:
  - secondary_heating_type=631 → secondary_fuel_type=11 → 3.67 p/kWh
  - Cascade SAP 63.8732 vs worksheet 63.8732 (delta +5e-5)
  - Cascade total fuel cost £787.03 = worksheet £787.03 exactly

Pyright net-zero on both touched files (mapper.py 32→32, test 0→0).

Tests: 703 → 704 pass (+1 new SAP-code-631 secondary-fuel routing
test), 10 expected fails unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 16:28:46 +00:00
..
fixtures Slice S0380.19: count Elmhurst shower outlets by type (no more hardcoded 1) 2026-06-01 16:28:46 +00:00
__init__.py Map to RdSapSiteNotes from site notes JSON 🟥 2026-04-16 13:54:03 +00:00
test_elmhurst_end_to_end.py Slice S0380.17: map Elmhurst §11 glazing-type labels to SAP10 codes 2026-06-01 16:28:46 +00:00
test_elmhurst_extractor.py extract window frame details from elmhurst site notes 🟥 2026-04-27 15:50:25 +00:00
test_end_to_end.py P6.1 follow-on: unbox BuildingPartIdentifier at backend boundaries 2026-05-20 09:58:23 +00:00
test_extractor.py Handle wall thickness "Unmeasurable" 🟩 2026-04-30 16:41:16 +00:00
test_pdf.py rename example site notes to PasHub_ and add Elmhurst example 2026-04-24 13:01:51 +00:00
test_summary_pdf_mapper_chain.py Slice S0380.24: SAP code 631 → house coal secondary fuel — closes cert 2102 -15.81 → +5e-5 2026-06-01 16:28:46 +00:00