Files
Florian-netz/docker-compose.geo.yml
Matthias Hochmeister e8bb75412b Workstream 4: Geo & Eintreffzeit-Sortierung (Phase 3)
Selbstgehostete Geo-Dienste (OSRM + Nominatim auf Österreich-Extrakt),
Geokodierung beim Speichern und ETA-Sortierung der Suchtreffer mit
vollständigem Haversine-Luftlinie-Fallback.

- src/lib/geo/types.ts, config.ts: reine Typen + zentrale Konfiguration
  (aus kanonischem env.ts; Defaults, kaputte URL wird weiterhin abgelehnt).
- haversine.ts: Luftlinie in Metern (rein). St. Pölten->Wien ~55 km verifiziert.
- nominatim.ts: kanonische, reine geocodeAddress(address) (countrycodes=at,
  Timeout/Abort, status ok/not_found/error; KEIN geocodeBrigade-Zweitpfad).
- osrm.ts: etaTable via /table (sources=0, lng,lat), wirft bei Fehler.
- eintreffzeit.ts: orderByEintreffzeit (OSRM-first, kompletter Haversine-
  Fallback bei Wurf, Kandidaten ohne Koordinaten ans Ende, stabile Sortierung;
  OSRM-Funktion injizierbar fuer Tests).
- candidates.ts: searchHitsToGeoCandidates (Adapter, laedt brigades.lat/lng)
  + reine filterAndCapCandidates (Bounding-Box-Vorfilter 60 km, max 100).
- API: /api/geo/geocode (POST, auth-gated 401, Zod-Body, 404 bei not_found)
  und /api/geo/health (GET, auth-gated; OSRM/Nominatim up/down) — beide
  default-deny ueber apiAuth.
- Komponenten: standort-input.tsx (Client, Geolocation + Geocode-Fetch),
  eta-badge.tsx (kennzeichnet Luftlinie-Fallback), optionale karte.tsx
  via next/dynamic (ssr:false).
- Infra: docker-compose.geo.yml (internes Netz, Healthchecks), docker/osrm/
  Dockerfile, scripts/prepare-osm-data.sh, infra/geo/{Makefile,README.md}.

WS4 legt KEINE Migration an (brigades-Geo-Spalten + brigades_latlng_idx
stammen aus WS2); drizzle-kit check bleibt sauber.

Offline verifiziert: tsc --noEmit (exit 0), next lint (0 Warnungen),
vitest run (54 passed / 7 skipped DB-roundtrip), next build (exit 0 mit
gesetzten env-Vars), drizzle-kit check ("Everything's fine").
Deferred (kein Postgres/Server im Sandbox): db:migrate, Live-OSRM/Nominatim,
Playwright-E2E.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:37:39 +02:00

67 lines
1.9 KiB
YAML

# Geo-Dienste (OSRM + Nominatim) auf Österreich-OSM-Extrakt.
# Zusammen mit der Basis verwenden:
# docker compose -f docker-compose.yml -f docker-compose.geo.yml up -d osrm nominatim
#
# WICHTIG: Vor dem ersten Start das OSRM-Preprocessing laufen lassen
# (scripts/prepare-osm-data.sh bzw. `make -C infra/geo data`) und den
# Nominatim-Import einplanen (Stunden, mehrere GB RAM/Disk).
services:
osrm:
build:
context: .
dockerfile: docker/osrm/Dockerfile
command: osrm-routed --algorithm mld /data/austria-latest.osrm
volumes:
- osrm-data:/data
networks:
- geo-internal
expose:
- "5000"
healthcheck:
# /table mit zwei nahen NÖ-Punkten; erwartet HTTP 200.
test:
- CMD-SHELL
- >-
wget -q -O - 'http://localhost:5000/table/v1/driving/15.6229,48.2079;16.3738,48.2082?sources=0'
| grep -q '"code":"Ok"'
interval: 30s
timeout: 5s
retries: 5
start_period: 60s
restart: unless-stopped
nominatim:
image: mediagis/nominatim:4.4
environment:
# Österreich-Extrakt (Geofabrik). Beim Erststart wird importiert.
PBF_URL: https://download.geofabrik.de/europe/austria-latest.osm.pbf
REPLICATION_URL: https://download.geofabrik.de/europe/austria-updates/
IMPORT_STYLE: address
NOMINATIM_PASSWORD: nominatim
volumes:
- nominatim-data:/var/lib/postgresql/14/main
shm_size: 1g
networks:
- geo-internal
expose:
- "8080"
healthcheck:
test:
- CMD-SHELL
- "wget -q -O - 'http://localhost:8080/status' | grep -q OK"
interval: 30s
timeout: 5s
retries: 5
start_period: 120s
restart: unless-stopped
volumes:
osrm-data:
nominatim-data:
networks:
# Internes Netz: Geo-Dienste sind nur für die App erreichbar, nicht öffentlich.
geo-internal:
internal: true