Model/repositories/spatial/spatial_repository.py
Khalim Conn-Kowlessar a1c60d2fba feat(spatial): per-UPRN cache repo for the OS spatial reference
Slice 3c.2. The OS Open-UPRN reference set is too large to host in Postgres, so
it lives in S3 and is cached per-UPRN in the existing `property_details_spatial`
table (ADR-0020). `PropertyDetailsSpatialRow` mirrors that table (uprn unique);
`SpatialRepository` / `SpatialPostgresRepository` upsert one shared row per UPRN
and read the planning protections back by UPRN (a null flag reads as
unrestricted; absent UPRNs are omitted so the caller defaults them).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:15:51 +00:00

27 lines
961 B
Python

from __future__ import annotations
from abc import ABC, abstractmethod
from domain.geospatial.planning_restrictions import PlanningRestrictions
from domain.geospatial.spatial_reference import SpatialReference
class SpatialRepository(ABC):
"""Caches the OS spatial reference data (coordinates + planning flags) by
UPRN — a per-UPRN write-through cache of the S3 reference lookup (ADR-0020).
Written by Ingestion, read by Modelling (which hydrates the planning
protections onto the Property). One shared row per UPRN; ``save`` upserts.
"""
@abstractmethod
def save(self, uprn: int, reference: SpatialReference) -> None: ...
@abstractmethod
def get_for_uprns(
self, uprns: list[int]
) -> dict[int, PlanningRestrictions]:
"""The planning protections for each covered UPRN, keyed by UPRN.
UPRNs with no cached row are omitted (the caller defaults them to
unrestricted)."""
...