Repository navigation
fix(rate-limit): meter the gateway reverse-geocode RPC at 60/min - #6451
Merged
Merged
Conversation
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
koala73
added a commit
that referenced
this pull request
Aug 11, 2026
koala73
force-pushed
the
fix/reverse-geocode-rpc-rate-limit-6432
branch
from
August 11, 2026 06:40
ac5f98f to
5413d38
Compare
The gateway RPC server/worldmonitor/infrastructure/v1/reverse-geocode.ts fetches Nominatim directly but had no ENDPOINT_RATE_POLICIES entry, so it inherited the 600/min availability-first fallback - 10x the budget #6412 set on the sibling api/reverse-geocode.js edge route, against the same provider from the same egress IPs. - Register /api/infrastructure/v1/reverse-geocode at 60/min in ENDPOINT_RATE_POLICIES and FAIL_CLOSED_ENDPOINT_RATE_POLICY_REQUIRED (Nominatim enforces by egress-IP ban, so a Redis outage must 503 rather than inherit fail-open). - Make api/reverse-geocode.js cache writes unconditional so ocean and Antarctic cells populate the shared geocode: namespace instead of being 100% Nominatim passthrough, using the RPC's exact entry shape so either reader can serve the other. - Update docs/usage-rate-limits.mdx (+ zh mirror) and add regression tests for both the fail-closed policy and the ocean-cell cache write.
koala73
force-pushed
the
fix/reverse-geocode-rpc-rate-limit-6432
branch
from
August 11, 2026 06:52
5413d38 to
0378ab9
Compare
This branch was successfully deployed
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
GET /api/infrastructure/v1/reverse-geocodereaches Nominatim on a cache miss, but it had noENDPOINT_RATE_POLICIESentry, so it silently inherited the gateway's 600/min availability-first fallback. That is 10x the 60/min budget #6412 set on the siblingapi/reverse-geocode.jsedge route - from the same provider, the same egress IPs, against a provider that bans egress IPs. Half the exposure #6412 closed was still open.This closes it: the RPC is now registered at the same 60/min, and the edge route's cache no longer leaves ocean/Antarctic cells as unmetered passthrough.
What changed
'/api/infrastructure/v1/reverse-geocode': { limit: 60, window: '60 s' }inENDPOINT_RATE_POLICIES(server/_shared/rate-limit.ts). The gateway already runscheckEndpointRateLimitfor every route before consulting the registry, so the entry is the whole metering - no handler change needed. Because Nominatim enforces by egress-IP ban, it also goes intoFAIL_CLOSED_ENDPOINT_RATE_POLICY_REQUIRED, so a Redis outage returns 503 rather than inheriting the fail-open fallback.api/reverse-geocode.jswrote the sharedgeocode:cache only when a country resolved, so ocean and Antarctic coordinates were 100% Nominatim passthrough with no meter. The write is now unconditional and uses the RPC's complete entry shape{country, code, displayName, error}. Both routes use the same deployment-scoped 0.1-degree grid namespace, so either reader can serve the other without mixing preview and production entries.docs/usage-rate-limits.mdxand its Chinese translation gains the RPC row and corrects the now-false "none of them is routed through the gateway" claim.Residual
Both budgets are per-IP, so they bound any single caller but not aggregate egress to Nominatim. A global companion budget is still required and is not implemented by this PR.
Verification
tests/rate-limit.test.mts: 50/50 pass, including the 60/min registry contract, fail-closed Redis behavior, and the real gateway rejection path.tests/reverse-geocode-rate-limit.test.mjs: 6/6 pass, including preview-key interoperability, response normalization, and the complete seven-day negative-cache payload.tests/reverse-geocode-cache-contract.test.mts: 2/2 pass for preview reads and writes across the shared cache contract.tests/edge-functions.test.mjs: 252/252 pass.typecheck:api,enforce-rate-limit-policies, Biome, and Markdown lint pass.Fixes #6432