Model/repositories/comparable_properties/comparable_properties_repository.py
Khalim Conn-Kowlessar 6979607ace feat(epc-prediction): slice-5b ComparableProperties repo port + adapter
Build the cohort IO port ADR-0029 deferred (ADR-0031 slice-5b):
`ComparablePropertiesRepository.candidates_for(postcode) -> list[Comparable]`,
with an EPC-API + geospatial adapter that lists the postcode's lodged certs
(search_by_postcode), fetches + maps each (get_by_certificate_number), and
resolves their UPRNs to coordinates in ONE batched read. Register metadata the
cert doesn't carry (address, registration date) is threaded off the search row;
a UPRN-less or unparseable-date cert is kept, just uncoordinated / unweighted.
The domain select_comparables then filters these candidates into the cohort.

Thin CohortEpcClient / CohortGeospatial Protocols keep the adapter testable
against fakes; EpcClientService + GeospatialS3Repository satisfy them
structurally (no changes). 3 tests; pyright strict clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 03:40:59 +00:00

24 lines
1 KiB
Python

"""The ComparableProperties repository port (ADR-0029 decision 3; ADR-0031).
Owns the cohort IO for EPC Prediction — given a target's postcode, return the
candidate `Comparable`s (the postcode's other lodged certs, mapped to
`EpcPropertyData` with their register metadata + resolved coordinates). The pure
domain `select_comparables` then filters these into the reference cohort, and
`EpcPrediction.predict` synthesises the picture. Kept a port so the orchestrator
depends on the cohort source abstractly and tests substitute a fake.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from domain.epc_prediction.comparable_properties import Comparable
class ComparablePropertiesRepository(ABC):
@abstractmethod
def candidates_for(self, postcode: str) -> list[Comparable]:
"""Every candidate neighbour in `postcode` — one `Comparable` per lodged
cert, carrying its `EpcPropertyData`, certificate number, address,
registration date, and resolved coordinates (None when unresolvable)."""
...