fix(seo): global geographic resilience with admin_level_1 and Nominatim#177
Merged
fix(seo): global geographic resilience with admin_level_1 and Nominatim#177
Conversation
- Add admin_level_1 field to AedLocation for coordinate-derived region names - Add Nominatim reverse geocoding utility (src/lib/nominatim.ts) with concurrency-safe rate limiting for OSM public API - Enrich admin_level_1 on import (CSV and external sync processors) - Use admin_level_1 as primary region source in sitemap, country and region pages, with INE code fallback for non-enriched records - Add community name aliases (English variants from Nominatim) - Optimize communityForIneCode from O(n*m) to O(1) with Map - Fix resolveCityName: remove dangerous `contains` fallback that could match wrong cities non-deterministically - Fix legacy city redirect to use admin_level_1 when city_code is null - Fix redirects from 307 to 308 (permanentRedirect) for SEO - Deduplicate sitemap URLs and add 50K size bound - Fix safeJsonLd to escape & and > for XML parser compatibility - Fix falsy zero coordinate check (0.0 lat/lon treated as null) - Add error logging in sitemap catch block - Fix IndexNow key files to match protocol requirements - Add scripts/enrich-geography.ts for local bulk enrichment via Nominatim - Migration backfills admin_level_1 from existing INE province codes
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Filter sitemap city URLs by known communities to prevent 404s from foreign/unrecognized admin_level_1 values - Skip Nominatim reverse geocoding in updateAed when coordinates have not changed (avoids redundant API calls on repeated syncs) - Reduce Nominatim retries from 3 to 1 for server-side import calls to prevent blocking import processor ~20s/record when API is down (CLI script keeps retries=3 for thoroughness)
- Use PrismaPg adapter (consistent with other project scripts) - Pass DATABASE_URL via environment variable - Validate DATABASE_URL presence before starting
- Add nominatim_verified_at field to track which records have been verified via Nominatim (supports resume without reprocessing) - Skip records where Nominatim country != stored country_code (coordinates don't match country — excluded from enrichment) - Skip Null Island (0,0) coordinates, mark as verified - Cache geocode results for identical coordinates (saves API calls) - Generate wrong-country CSV report for manual review - Default --only-unverified: only processes records not yet verified - Use --all flag to reprocess everything
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
admin_level_1field to AedLocation — stores region/state derived from coordinates via Nominatim reverse geocoding (works worldwide, not just Spain)admin_level_1during CSV import and external sync using the public Nominatim APIadmin_level_1as the primary source for geographic hierarchy in sitemap, country page, and region pages (with INE code fallback for non-enriched records)Bug Fixes
resolveCityName: removed dangerouscontainsfallback that could match "Tor" → "Torrevieja"admin_level_1fallback whencity_codeis nullcommunityForIneCode: O(n*m) → O(1) via Mapif (lat && lon)→if (lat != null && lon != null)(0.0 was falsy)safeJsonLd: now escapes&and>for XML parser compatibilityNew Files
src/lib/nominatim.ts— Nominatim reverse geocoding utility (rate-limited, retry with backoff)scripts/enrich-geography.ts— CLI script for bulk enrichment of existing recordsprisma/migrations/20260414200000_add_admin_level_1/— Adds field + backfills from INE codespublic/{key}.txt— IndexNow key verification filesTest plan
npm run type-checkpasses (only pre-existing S3 module error)npm run lintpasses (0 errors, only pre-existing warnings)npx tsx scripts/enrich-geography.ts --limit 10 --reportto test enrichment