from __future__ import annotations from typing import ClassVar, Optional, cast from sqlmodel import Field, SQLModel from datatypes.epc.domain.epc import Epc from domain.property_baseline.property_baseline_performance import PropertyBaselinePerformance from domain.property_baseline.performance import Performance from domain.property_baseline.rebaseliner import RebaselineReason class PropertyBaselinePerformanceModel(SQLModel, table=True): """The ``property_baseline_performance`` row — one per Property (ADR-0004). Flat typed columns (not a JSONB blob) so the FE can both surface the block and query the lodged-vs-effective pair. The production migration is FE-owned (Drizzle); see docs/migrations/property-baseline-performance-table.md. """ __tablename__: ClassVar[str] = "property_baseline_performance" # pyright: ignore[reportIncompatibleVariableOverride] id: Optional[int] = Field(default=None, primary_key=True) property_id: int = Field(unique=True, index=True) lodged_sap_score: int lodged_epc_band: str lodged_co2_emissions_t_per_yr: float lodged_primary_energy_intensity_kwh_per_m2_yr: int effective_sap_score: int effective_epc_band: str effective_co2_emissions_t_per_yr: float effective_primary_energy_intensity_kwh_per_m2_yr: int rebaseline_reason: str space_heating_kwh: float water_heating_kwh: float @classmethod def from_domain( cls, baseline: PropertyBaselinePerformance, property_id: int ) -> "PropertyBaselinePerformanceModel": return cls( property_id=property_id, lodged_sap_score=baseline.lodged.sap_score, lodged_epc_band=baseline.lodged.epc_band.value, lodged_co2_emissions_t_per_yr=baseline.lodged.co2_emissions, lodged_primary_energy_intensity_kwh_per_m2_yr=baseline.lodged.primary_energy_intensity, effective_sap_score=baseline.effective.sap_score, effective_epc_band=baseline.effective.epc_band.value, effective_co2_emissions_t_per_yr=baseline.effective.co2_emissions, effective_primary_energy_intensity_kwh_per_m2_yr=baseline.effective.primary_energy_intensity, rebaseline_reason=baseline.rebaseline_reason, space_heating_kwh=baseline.space_heating_kwh, water_heating_kwh=baseline.water_heating_kwh, ) def to_domain(self) -> PropertyBaselinePerformance: return PropertyBaselinePerformance( lodged=Performance( sap_score=self.lodged_sap_score, epc_band=Epc(self.lodged_epc_band), co2_emissions=self.lodged_co2_emissions_t_per_yr, primary_energy_intensity=self.lodged_primary_energy_intensity_kwh_per_m2_yr, ), effective=Performance( sap_score=self.effective_sap_score, epc_band=Epc(self.effective_epc_band), co2_emissions=self.effective_co2_emissions_t_per_yr, primary_energy_intensity=self.effective_primary_energy_intensity_kwh_per_m2_yr, ), rebaseline_reason=cast(RebaselineReason, self.rebaseline_reason), space_heating_kwh=self.space_heating_kwh, water_heating_kwh=self.water_heating_kwh, )