The GIAS town field puts 1,819 London schools under the single value 'London', so it cannot answer 'schools in Battersea' — a query that appears in the baseline. No single field can: parliamentary constituency gives Battersea but not Canary Wharf, admin_ward gives Canary Wharf but not Battersea, and neither gives Clapham or Shoreditch. So a locality is curated, defined by the postcode districts it covers, which needs no new ingestion. A locality may not shadow a published town: the registry raises rather than silently costing a page that carries real demand. One below the threshold is logged rather than raising, because a locality can legitimately be too small. The pipeline seed mirrors the module, with a test guarding the drift — the same arrangement gias_codes has, and for the same reason: the backend image does not contain pipeline/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
48 lines
2.4 KiB
Python
48 lines
2.4 KiB
Python
"""Curated London localities, defined by the postcode districts they cover.
|
|
|
|
The GIAS `town` field puts 1,819 London schools under the single value
|
|
"London", so it cannot answer "schools in Battersea" — a query that appears in
|
|
the Search Console baseline. No single field can: parliamentary constituency
|
|
gives Battersea but not Canary Wharf; postcodes.io's admin_ward gives Canary
|
|
Wharf but not Battersea; neither gives Clapham or Shoreditch, which are postal
|
|
and colloquial rather than administrative.
|
|
|
|
So this is curated. Where a locality ends is a judgement, not a fact, and a
|
|
reviewable file is the honest place for a judgement. No new ingestion is
|
|
needed — the corpus already carries postcodes.
|
|
|
|
This is the canonical copy. `pipeline/transform/seeds/locality_outcodes.csv`
|
|
mirrors it for anyone querying the warehouse directly; the backend image does
|
|
not contain `pipeline/`, which is why the module rather than the seed is
|
|
canonical. Same arrangement as `backend/gias_codes.py`.
|
|
|
|
A locality whose outcodes hold fewer than MIN_SCHOOLS schools is not
|
|
published, so a typo produces no page rather than an empty one. Places that
|
|
fail that check are logged at startup, because a locality you meant to publish
|
|
quietly not appearing is the failure worth hearing about.
|
|
"""
|
|
|
|
# slug -> (display name, outcodes)
|
|
LOCALITY_OUTCODES: dict[str, tuple[str, tuple[str, ...]]] = {
|
|
"battersea": ("Battersea", ("SW11",)),
|
|
"canary-wharf": ("Canary Wharf", ("E14",)),
|
|
"clapham": ("Clapham", ("SW4",)),
|
|
"shoreditch": ("Shoreditch", ("EC2A", "E1")),
|
|
"peckham": ("Peckham", ("SE15",)),
|
|
"brixton": ("Brixton", ("SW2", "SW9")),
|
|
"hackney": ("Hackney", ("E5", "E8", "E9")),
|
|
"islington": ("Islington", ("N1", "N5", "N7")),
|
|
"camden-town": ("Camden Town", ("NW1",)),
|
|
"greenwich": ("Greenwich", ("SE10",)),
|
|
"wimbledon": ("Wimbledon", ("SW19",)),
|
|
"putney": ("Putney", ("SW15",)),
|
|
"fulham": ("Fulham", ("SW6",)),
|
|
"chiswick": ("Chiswick", ("W4",)),
|
|
"ealing": ("Ealing", ("W5", "W13")),
|
|
"richmond": ("Richmond", ("TW9", "TW10")),
|
|
"stratford": ("Stratford", ("E15",)),
|
|
"walthamstow": ("Walthamstow", ("E17",)),
|
|
"tooting": ("Tooting", ("SW17",)),
|
|
"dulwich": ("Dulwich", ("SE21", "SE22")),
|
|
}
|