from __future__ import annotations import enum from datetime import datetime from typing import ClassVar, Optional from sqlalchemy import Column, TIMESTAMP from sqlalchemy import Enum as SAEnum from sqlmodel import Field, SQLModel class MeasureType(enum.Enum): air_source_heat_pump = "air_source_heat_pump" boiler_upgrade = "boiler_upgrade" high_heat_retention_storage_heaters = "high_heat_retention_storage_heaters" secondary_heating = "secondary_heating" roomstat_programmer_trvs = "roomstat_programmer_trvs" time_temperature_zone_control = "time_temperature_zone_control" cylinder_thermostat = "cylinder_thermostat" cavity_wall_insulation = "cavity_wall_insulation" extension_cavity_wall_insulation = "extension_cavity_wall_insulation" external_wall_insulation = "external_wall_insulation" internal_wall_insulation = "internal_wall_insulation" loft_insulation = "loft_insulation" flat_roof_insulation = "flat_roof_insulation" room_roof_insulation = "room_roof_insulation" solid_floor_insulation = "solid_floor_insulation" suspended_floor_insulation = "suspended_floor_insulation" double_glazing = "double_glazing" secondary_glazing = "secondary_glazing" draught_proofing = "draught_proofing" mechanical_ventilation = "mechanical_ventilation" low_energy_lighting = "low_energy_lighting" solar_pv = "solar_pv" hot_water_tank_insulation = "hot_water_tank_insulation" sealing_open_fireplace = "sealing_open_fireplace" class InstalledMeasureModel(SQLModel, table=True): """The single SQLModel definition of the live ``installed_measure`` table (ADR-0017 amendment). ``measure_type`` is the ``MeasureType`` Postgres enum; the remaining NOT-NULLs are relaxed to nullable (mirror convention — the live constraints are owned by the Drizzle schema).""" __tablename__: ClassVar[str] = "installed_measure" # pyright: ignore[reportIncompatibleVariableOverride] id: Optional[int] = Field(default=None, primary_key=True) uprn: Optional[int] = Field(default=None, index=True) measure_type: MeasureType = Field( sa_column=Column( SAEnum( MeasureType, name="measure_type", values_callable=lambda cls: [m.value for m in cls], # pyright: ignore[reportUnknownLambdaType, reportUnknownMemberType, reportUnknownVariableType] create_type=False, ), nullable=False, ) ) installed_at: Optional[datetime] = Field( default=None, sa_column=Column(TIMESTAMP, nullable=True) ) sap_points: Optional[float] = Field(default=None) carbon_savings: Optional[float] = Field(default=None) kwh_savings: Optional[float] = Field(default=None) bill_savings: Optional[float] = Field(default=None) heat_demand_savings: Optional[float] = Field(default=None) source: Optional[str] = Field(default=None) is_active: bool = True