"""A Property's planning protections, resolved from geospatial reference data. Three distinct flags (never the legacy collapsed `restricted_measures` boolean — ADR-0020): a conservation area, a listed building, a heritage building. They gate retrofit measures differently — a conservation area blocks external work only, while listed/heritage protect the fabric itself — so the measure-specific interpretation (`blocks_external` / `blocks_internal`) lives here as derived queries. Sourced onto the Property from the geospatial layer (co-located with the coordinates); defaults to unrestricted. """ from dataclasses import dataclass @dataclass(frozen=True) class PlanningRestrictions: """The planning protections on a Property that gate wall insulation (ADR-0019). Defaults to unrestricted.""" in_conservation_area: bool = False is_listed: bool = False is_heritage: bool = False @property def blocks_external(self) -> bool: """External wall insulation is blocked by any protection (it alters the external appearance / protected fabric).""" return self.in_conservation_area or self.is_listed or self.is_heritage @property def blocks_internal(self) -> bool: """Internal wall insulation is blocked only where the fabric itself is protected — a listed or heritage building, not a plain conservation area.""" return self.is_listed or self.is_heritage