feat(postcodes/LI): add Liechtenstein postcodes (#1039)#1401
Merged
Conversation
Adds the 13 Liechtenstein postal codes (range 9485-9498) covering the country's 11 municipalities. First country populated against the postcodes table introduced in #1398. Proves the file shape and validator path end-to-end. Mapping (state_code -> code -> locality): 01 Balzers -> 9496 Balzers 02 Eschen -> 9485 Nendeln, 9492 Eschen 03 Gamprin -> 9487 Bendern 04 Mauren -> 9486 Schaanwald, 9493 Mauren 05 Planken -> 9498 Planken 06 Ruggell -> 9491 Ruggell 07 Schaan -> 9494 Schaan 08 Schellenberg -> 9488 Schellenberg 09 Triesen -> 9495 Triesen 10 Triesenberg -> 9497 Triesenberg 11 Vaduz -> 9490 Vaduz source: "manual" — composed from common knowledge (LI postcodes are universally documented and stable); next country PRs will switch to automated pipelines (OpenPLZ, Wikidata, Census, etc.) once their adapters land. Validated: - All 13 records pass schema rules in .github/scripts/utils.js - All country_id/state_id FKs resolve - All state_code values match the corresponding state.iso2 - All codes match countries.postal_code_regex for LI (^(\\d{4})$) Refs: #1039 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
CSC Validation ReportPR Format
Labels applied: Schema Validation (13 records)✅ All records passed validation Cross-Reference Validation✅ 26 reference(s) verified Source URL Verification✅ 1 source URL(s) accessible ✅ All checks passed | Status: Ready for review |
There was a problem hiding this comment.
Pull request overview
Adds the first country dataset for the newly introduced postcodes contribution pipeline by populating Liechtenstein (LI) postcode records under contributions/postcodes/.
Changes:
- Add
contributions/postcodes/LI.jsoncontaining 13 LI postcodes (9485–9498, excluding 9489) mapped to existing LI municipalities viastate_id/state_code. - Populate
locality_name,type, andsourcemetadata per record.
7 tasks
dr5hn
added a commit
that referenced
this pull request
Apr 27, 2026
…1431) Adds two things in one PR (the script + its first run): 1. bin/scripts/sync/import_openplz_postcodes.py — pipeline that walks the OpenPLZ REST API hierarchy for Germany, Austria, and Switzerland, paginating Localities under each region. ODbL-1.0 licensed source matches this repo's licence exactly. 2. Three new contribution files: contributions/postcodes/DE.json (12,815 records, 2.5 MB) contributions/postcodes/AT.json (18,722 records, 4.0 MB) contributions/postcodes/CH.json ( 4,059 records, 840 KB) Total: 35,596 postcodes across DACH with 100% state_id resolution. How state resolution works - DE/CH: exact case-insensitive name match against states.json (with light umlaut normalisation and a few translation aliases: Luzern->Lucerne, Genève->Geneva, Basel-Landschaft->Basel-Land, Fribourg/Freiburg->Fribourg, etc.) - AT: name match catches the directly-spelt provinces (Salzburg, Vorarlberg, Burgenland) and aliases handle translations (Wien->Vienna, Tirol->Tyrol, Steiermark->Styria, Kärnten->Carinthia, Niederösterreich->Lower Austria, Oberösterreich->Upper Austria). A postcode-prefix fallback covers the rest (1xxx=Wien, 8xxx=Steiermark, 9xxx=Kärnten, etc.) — Austrian Post's well-documented prefix scheme is more reliable than fuzzy multilingual name matching. LI deliberately omitted - contributions/postcodes/LI.json is already curated (#1401) with 13 high-quality 1:1 commune-to-code rows. OpenPLZ's per-code endpoint returns multiple sub-localities per code (e.g. Vaduz-Triesen, Vaduz-Schaan) that would muddy the existing clean mapping. Validation (zero errors across 35,596 records) - All codes match countries.postal_code_regex for their ISO2 - All country_id/state_id foreign keys resolve - All state_code values agree with state.iso2 - No auto-managed fields present (id, created_at, updated_at, flag) - Idempotent re-runs preserve any future curated rows by (code, locality_name) License & attribution - Source: OpenPLZ (https://openplzapi.org), ODbL-1.0 - Each row: source: "openplz" for programmatic attribution Refs: #1039 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First country populated against the
postcodestable introduced in #1398. Adds Liechtenstein's 13 postal codes (range 9485–9498) covering the country's 11 municipalities.Mapping
(Bold = secondary locality within the municipality.)
Source
source: "manual"— composed from common knowledge. Liechtenstein's postcodes are universally documented and stable for decades. Subsequent country PRs will use automated pipelines (OpenPLZ for DACH, Wikidata SPARQL, Census ZCTA for US, etc.) once their adapter scripts land.Validation
.github/scripts/utils.jscountry_id/state_idforeign keys resolve against existing datastate_codevalues match the correspondingstate.iso2codevalues matchcountries.postal_code_regexfor LI (^(\d{4})$)id,created_at,updated_at,flag) presentOut of scope
latitude/longitude— left null. Could be backfilled with municipality centroids in a follow-up.wikiDataIdper postcode — left null. Wikidata cross-reference is a separate enhancement.city_id— left null. Most LI postcodes serve a locality that may or may not be incities; resolving each is a separate sweep.Test plan
contributions/countries/countries.jsonandcontributions/states/states.jsonRefs: #1039
Builds on: #1398
🤖 Generated with Claude Code