mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Final slice of ADR-0012: collapse the per-property read round-trips a batch made (Baseline hydrated ~8 queries x 30 properties one at a time) into a handful of per-table IN queries. - EpcPostgresRepository: extracted a shared `_compose(rows)` from `get` (the windows + floor-dim fetches are now passed in, not fetched inline), so both `get` and the new `get_for_properties(property_ids)` build EpcPropertyData from pre-fetched rows. `get_for_properties` fetches each child table once (`WHERE epc_property_id IN ...`), groups in memory, and composes — load-whole per ADR-0002. - PropertyRepository.get_many(property_ids) -> Properties: one query for the property rows + one bulk EPC hydration, composed in input order. - BaselineOrchestrator / IngestionOrchestrator read the batch via get_many instead of N x get. - Ports + fakes gain the bulk methods. The #1129 round-trip fidelity test stays green (the compose extraction is behaviour-preserving). New tests: bulk hydration correctness + round-trips are constant w.r.t. batch size (one-per-table, proven by query count). 123 pass; pyright strict clean; AAA. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
38 lines
1.2 KiB
Python
38 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Optional
|
|
|
|
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
|
|
|
|
|
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).
|
|
"""
|
|
|
|
@abstractmethod
|
|
def save(
|
|
self,
|
|
data: EpcPropertyData,
|
|
property_id: int | None = None,
|
|
portfolio_id: int | None = None,
|
|
) -> int: ...
|
|
|
|
@abstractmethod
|
|
def get(self, epc_property_id: int) -> EpcPropertyData: ...
|
|
|
|
@abstractmethod
|
|
def get_for_property(self, property_id: int) -> Optional[EpcPropertyData]: ...
|
|
|
|
@abstractmethod
|
|
def get_for_properties(
|
|
self, property_ids: list[int]
|
|
) -> dict[int, EpcPropertyData]:
|
|
"""Bulk-hydrate a batch's EPCs, keyed by property_id (only those with an
|
|
EPC are present). A handful of per-table queries, not N per property."""
|
|
...
|