from __future__ import annotations from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Literal, Optional from datatypes.epc.domain.epc_property_data import EpcPropertyData if TYPE_CHECKING: from repositories.epc.epc_postgres_repository import EpcSaveRequest # Provenance of a persisted EPC picture (ADR-0031): a real "lodged" EPC, or a # "predicted" one synthesised by EPC Prediction. A property can hold one of each. EpcSource = Literal["lodged", "predicted"] class EpcRepository(ABC): """Persists and loads the structured EPC Property Data slice. `save` writes the `EpcPropertyData` to the `epc_property` parent row and its child tables; `get` reconstructs the persisted projection back into an `EpcPropertyData`. Round-trip fidelity over that projection is pinned by the Slice-1 round-trip test (Hestia-Homes/Model#1129). Each EPC carries a `source` so a lodged and a predicted picture coexist per property (ADR-0031). """ @abstractmethod def save( self, data: EpcPropertyData, property_id: int | None = None, portfolio_id: int | None = None, source: EpcSource = "lodged", ) -> int: ... @abstractmethod def save_batch(self, requests: "list[EpcSaveRequest]") -> list[int]: ... @abstractmethod def get(self, epc_property_id: int) -> EpcPropertyData: ... @abstractmethod def get_for_property(self, property_id: int) -> Optional[EpcPropertyData]: """The property's LODGED EPC (the predicted slot is read separately).""" ... @abstractmethod def get_predicted_for_property( self, property_id: int ) -> Optional[EpcPropertyData]: """The property's PREDICTED EPC (EPC Prediction gap-fill), or None.""" ... @abstractmethod def get_for_properties( self, property_ids: list[int] ) -> dict[int, EpcPropertyData]: """Bulk-hydrate a batch's LODGED EPCs, keyed by property_id (only those with one are present). A handful of per-table queries, not N per property.""" ... @abstractmethod def get_predicted_for_properties( self, property_ids: list[int] ) -> dict[int, EpcPropertyData]: """Bulk-hydrate a batch's PREDICTED EPCs (ADR-0031), keyed by property_id (only those with one are present).""" ...