L13 Planung: Geocoding der Objekte über OpenStreetMap Nominatim

Provider-Interface (nominatim|none), strukturierte Suche mit User-Agent und Accept-Language, Drosselung 1/s je Prozess, Job geocode-site (Worker: Concurrency 1 + Limiter), Cache am Objekt, manuelle Koordinaten bleiben, Auslöser Anlage/Adressänderung/Import-Bestätigung nur per Queue, Backfill-Skript, Env-Beispiele. Tests mit Fake-Provider, Nominatim nie aufgerufen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 10:13:26 +02:00
co-authored by Claude Opus 5
parent 604f2bfdc5
commit 213bcca3a1
14 changed files with 600 additions and 2 deletions
+24
View File
@@ -0,0 +1,24 @@
/**
* Minimum-interval limiter: callers are released one after another with at least `intervalMs`
* between two slots (Nominatim policy: max. 1 request per second). Clock is injectable for tests.
*/
export type Clock = { now: () => number; sleep: (ms: number) => Promise<void> };
const realClock: Clock = { now: () => Date.now(), sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
export function createIntervalLimiter(intervalMs: number, clock: Clock = realClock) {
let next = 0;
return {
/** Waits for the next free slot and returns its timestamp. */
async acquire(): Promise<number> {
const now = clock.now();
const slot = Math.max(now, next);
next = slot + intervalMs;
if (slot > now) await clock.sleep(slot - now);
return slot;
},
};
}
/** Process-wide limiter for all Nominatim requests of this process (worker, backfill script). */
export const nominatimLimiter = createIntervalLimiter(1_000);