"""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. Two rules for anything added here. **Sub-borough districts only.** A London borough is a local authority and already has a page at /schools/authority/[la] covering all of its schools; a locality defined by two or three outcodes would be a partial, near-duplicate subset of it. Hackney, Islington, Greenwich and Ealing were all in the first draft for that reason and have been removed. **The slug must not match a GIAS town.** "Richmond" did — GIAS has a Richmond in North Yorkshire with 37 schools — so the London one could never publish. The registry skips any locality that collides and logs it. """ # 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")), "camden-town": ("Camden Town", ("NW1",)), "wimbledon": ("Wimbledon", ("SW19",)), "putney": ("Putney", ("SW15",)), "fulham": ("Fulham", ("SW6",)), "chiswick": ("Chiswick", ("W4",)), "stratford": ("Stratford", ("E15",)), "walthamstow": ("Walthamstow", ("E17",)), "tooting": ("Tooting", ("SW17",)), "dulwich": ("Dulwich", ("SE21", "SE22")), }