Model/tests/harness
Khalim Conn-Kowlessar 9ef97be958 refactor(modelling): type measure_type fields as MeasureType
Tighten the recommendation/plan vocabulary off generic str:
MeasureOption.measure_type and PlanMeasure.measure_type are now MeasureType
(also _GlazingTarget.measure_type, MeasureDependency.triggers ->
frozenset[MeasureType], and the optimiser's chosen/required-type locals).
Because MeasureType is a StrEnum the change is transparent to persistence
(the `recommendation` varchar column), the optimiser group-by key, and every
`== "solar_pv"`-style comparison — so pyright now enforces the enum at every
construction site with no runtime behaviour change.

The catalogue boundary stays str: ProductRepository.get(measure_type: str)
and Product.measure_type are unchanged (they map arbitrary DB/JSON rows), so
the fake product repos in tests need no edit. Test construction helpers coerce
their str arg via MeasureType(...); direct constructions use members.

Suite green: tests/domain/modelling + orchestration + harness 253 pass + 3
xfail; pyright clean on production + tests (pre-existing moto + property-
override-rowcount baselines untouched).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:13:31 +00:00
..
__init__.py feat(modelling): sense-check table for a Plan in the DB-less harness 2026-06-04 08:06:53 +00:00
test_cohort.py feat(modelling): turnkey offline cohort script (tables + CSV) 2026-06-04 09:30:53 +00:00
test_console.py test: reflect ASHP winning more often after the Vaillant swap 2026-06-06 21:49:12 +00:00
test_epc_bulk.py feat(modelling): read the gov EPC bulk export via HTTP range requests 2026-06-04 12:16:18 +00:00
test_plan_table.py refactor(modelling): type measure_type fields as MeasureType 2026-06-08 20:13:31 +00:00
test_report.py test: reflect ASHP winning more often after the Vaillant swap 2026-06-06 21:49:12 +00:00