mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
67 lines
2.6 KiB
Python
67 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
from domain.property.properties import Properties
|
|
from domain.property.property import Property
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PropertyIdentityInsert:
|
|
"""One row inserted into the FE-owned ``property`` table at Finalise (ADR-0013).
|
|
|
|
Mirrors the exact column set today's Next.js ``/finalize`` writes: nine fields
|
|
plus ``creation_status='READY'``. ``address``/``postcode`` are the resolved
|
|
(matched ?? user-inputted) values and may be ``None``.
|
|
"""
|
|
|
|
portfolio_id: int
|
|
uprn: Optional[int]
|
|
landlord_property_id: Optional[str]
|
|
address: Optional[str]
|
|
postcode: Optional[str]
|
|
user_inputted_address: Optional[str]
|
|
user_inputted_postcode: Optional[str]
|
|
lexiscore: Optional[float]
|
|
creation_status: str = "READY"
|
|
|
|
|
|
class PropertyRepository(ABC):
|
|
"""Reads and writes the FE-owned ``property`` table.
|
|
|
|
Reads hydrate the Property aggregate whole — never half a Property — from the
|
|
identity row plus its source-data slices (EPC today; Site Notes / enrichments
|
|
as later slices land) (ADR-0002, ADR-0012). Writes bulk-insert identity rows at
|
|
Finalise (ADR-0013). One repository per aggregate.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def get(self, property_id: int) -> Property: ...
|
|
|
|
@abstractmethod
|
|
def get_many(self, property_ids: list[int]) -> Properties:
|
|
"""Load a batch of Properties whole, in a handful of per-table queries
|
|
rather than one round-trip per property (ADR-0012). Order follows the
|
|
input ids."""
|
|
...
|
|
|
|
@abstractmethod
|
|
def insert_all(self, rows: list[PropertyIdentityInsert]) -> int:
|
|
"""Bulk-insert identity rows, skipping any whose ``(portfolio_id, uprn)``
|
|
already exists (the FE partial unique index, ``WHERE uprn IS NOT NULL``).
|
|
Rows with no UPRN are always inserted. Returns the number actually
|
|
inserted; an empty list is a no-op returning 0 (ADR-0013)."""
|
|
...
|
|
|
|
@abstractmethod
|
|
def ids_by_uprn(self, portfolio_id: int, uprns: list[int]) -> dict[int, int]:
|
|
"""Map each given UPRN to its ``property.id`` within a portfolio.
|
|
|
|
Used by the finaliser to attach ``property_overrides`` to UPRN-matched
|
|
rows (ADR-0006) without a query per row — covers both rows just inserted
|
|
and pre-existing ones (re-found by ``(portfolio_id, uprn)``). UPRNs with
|
|
no matching property are simply absent from the result; an empty input is
|
|
a no-op returning ``{}``."""
|
|
...
|