mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Slice 5a: the promotion. Replaces StubRebaseliner in production and collapses the
shadow runner into the rebaseliner (ADR-0013 amendment).
- CalculatorRebaseliner runs Sap10Calculator on every Property:
* sap_version < 10.2 -> Effective Performance IS the calculator output
(band via Epc.from_sap_score, CO2 kg->t, PEUI rounded), reason "pre_sap10".
* sap_version >= 10.2 -> Effective = lodged (API figures on-target), and the
calculator only logs divergence (SAP>0.5, PEUI/CO2 1%) as a validation signal.
* a calculator raise propagates -> batch aborts (ADR-0012); fix the cert at once.
- Rebaseliner.rebaseline gains property_id (for the divergence log).
- LoggingCalculatorShadow / the calculator_shadow seam removed from the
orchestrator; its divergence-comparison logic now lives in the rebaseliner.
- StubRebaseliner kept (signature updated) for orchestrator/repo unit tests.
The SapResult->EnergyBreakdown adapter + BillDerivation wiring (to populate the
bill block) follow once the appliances/cooking SapResult fields land.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
import pytest
|
|
|
|
from datatypes.epc.domain.epc import Epc
|
|
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
|
from domain.property_baseline.performance import Performance
|
|
from domain.property_baseline.rebaseliner import RebaselineNotImplemented, StubRebaseliner
|
|
|
|
|
|
def _epc(*, sap_version: Optional[float]) -> EpcPropertyData:
|
|
epc = object.__new__(EpcPropertyData)
|
|
epc.sap_version = sap_version
|
|
return epc
|
|
|
|
|
|
def _lodged() -> Performance:
|
|
return Performance(
|
|
sap_score=72, epc_band=Epc.C, co2_emissions=1.8, primary_energy_intensity=180
|
|
)
|
|
|
|
|
|
def test_sap10_epc_is_not_rebaselined_so_effective_equals_lodged() -> None:
|
|
# Arrange — a SAP 10.2 cert: no rebaselining trigger fires.
|
|
epc = _epc(sap_version=10.2)
|
|
lodged = _lodged()
|
|
rebaseliner = StubRebaseliner()
|
|
|
|
# Act
|
|
effective, reason = rebaseliner.rebaseline(10, epc, lodged)
|
|
|
|
# Assert — Effective Performance equals Lodged, reason "none".
|
|
assert effective == lodged
|
|
assert reason == "none"
|
|
|
|
|
|
def test_pre_sap10_epc_raises_because_rebaselining_is_not_implemented() -> None:
|
|
# Arrange — a cert lodged under a pre-SAP10 schema genuinely needs ML
|
|
# rebaselining, which does not exist yet; the stub must not fabricate a
|
|
# "none" answer for it.
|
|
epc = _epc(sap_version=9.94)
|
|
rebaseliner = StubRebaseliner()
|
|
|
|
# Act / Assert
|
|
with pytest.raises(RebaselineNotImplemented):
|
|
rebaseliner.rebaseline(10, epc, _lodged())
|