mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-08-26 17:31:37 +00:00
* Add navi-offroute service (extraction #8 — the last one) Faithful port of recon's /api/offroute (POST) + /api/mvum (GET) and the runtime offroute modules into a new :8428 service. Closes the loop: after this, navi-frontend talks only to navi-backend. Ported: router.py (OffrouteRouter, EntryPointIndex, 4 route strategies, in-Python MCP_Geometric least-cost path, Valhalla integration, per-request osmium extract), mvum.py (MVUMReader over navi.db), cost.py, friction.py, trails.py, and barriers.py (runtime BarrierReader/WildernessReader only). NOT ported (per Phase A §3/§15): prototype.py (dead at runtime), barriers.py build_*_raster (offline GDB→raster prep). DEM imported from shared/dem.py (PR #9), not duplicated. Behaviour-faithful changes: hardcoded paths/URLs → env vars; the profile.offroute.* config (osm_pbf_path/postgis_dsn/densify_interval_m) → dedicated env vars (router drops deployment_config). Both routes public (no auth, matching recon). PADUS via libpq peer-auth DSN (dbname=padus) — NO secret. Owns no DB. 15 hermetic tests (offroute validation + mocked-router shape + close-always; fixture-SQLite MVUM roads/trails/fallback/null; admin auth + no-secrets + probe shape). Full suite 119 passed / 1 skipped. Adds scikit-image + rasterio. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * navi-offroute: PR #10 review cleanups (4 faithful-port deviations) 1. trails.py — drop recon-era "Run the Phase B rasterization script" reference from the not-found error (confusing in navi-offroute context). 2. friction.py — add FileNotFoundError-before-rasterio-open check to match barriers/trails consistency. 3. mvum.py — remove dead try/except shapely import + warnings.warn at 2 sites (shapely is a hard pyproject dep; the fallback was unreachable). 4. router.py — declare psutil in pyproject, drop the silent fallback; the MEMORY_LIMIT_GB safety check was silently disabled in prod. Adds test_friction_reader_raises_file_not_found_when_missing (16 navi-offroute tests; full suite 120 passed / 1 skipped). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: zvx-echo6 <mj@k7zvx.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4180d3513c
commit
ae82cee46a
17 changed files with 3960 additions and 0 deletions
30
backend/deploy/env/navi-offroute.env.example
vendored
Normal file
30
backend/deploy/env/navi-offroute.env.example
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# navi-offroute — /etc/navi-backend/navi-offroute.env
|
||||
# Faithful port of recon's /api/offroute + /api/mvum (extraction #8).
|
||||
# NO SECRETS — PADUS uses libpq peer-auth (dbname=padus, no password); all other
|
||||
# inputs are read-only paths/URLs. Owns no DB.
|
||||
|
||||
# Shared planet-DEM (via shared/dem.py — same file/var as navi-geo).
|
||||
NAVI_DEM_PMTILES=/mnt/nas/nav/planet-dem.pmtiles
|
||||
|
||||
# Offroute-specific read-only data (all stay external per data-ownership rule).
|
||||
NAVI_OFFROUTE_OSM_PBF=/mnt/nav/sources/idaho-latest.osm.pbf
|
||||
NAVI_OFFROUTE_NAVI_DB=/mnt/nav/navi.db
|
||||
NAVI_OFFROUTE_BARRIERS_TIF=/mnt/nav/worldcover/padus_barriers.tif
|
||||
NAVI_OFFROUTE_WILDERNESS_TIF=/mnt/nav/worldcover/wilderness.tif
|
||||
NAVI_OFFROUTE_TRAILS_TIF=/mnt/nav/worldcover/trails.tif
|
||||
NAVI_OFFROUTE_FRICTION_VRT=/mnt/nav/worldcover/friction/friction_conus.vrt
|
||||
|
||||
# PADUS PostGIS — peer-auth DSN, NO password. libpq connects via the local
|
||||
# socket as the service user (systemd User=zvx; verified zvx has padus access).
|
||||
# Queries the `entry_points` routing index (a different table than navi-landclass).
|
||||
NAVI_OFFROUTE_POSTGIS_DSN=dbname=padus
|
||||
|
||||
# Valhalla — recon-side network router (HTTP), for the on-network leg.
|
||||
NAVI_OFFROUTE_VALHALLA_URL=http://localhost:8002
|
||||
|
||||
# Cost-grid densification interval, metres (was profile.offroute.densify_interval_m).
|
||||
NAVI_OFFROUTE_DENSIFY_M=100
|
||||
|
||||
# HOST DEP: router.py shells out to `osmium extract` per route — the host needs
|
||||
# osmium-tool installed (`sudo apt-get install osmium-tool`). admin-info reports
|
||||
# its version (or 'not installed').
|
||||
33
backend/deploy/nginx/navi-offroute.conf.snippet
Normal file
33
backend/deploy/nginx/navi-offroute.conf.snippet
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# =============================================================================
|
||||
# navi-offroute — nginx integration for the navi.echo6.co vhost
|
||||
#
|
||||
# TWO blocks. Add INSIDE the existing
|
||||
# server { server_name navi.echo6.co; ... }
|
||||
# block, BEFORE the existing `location /api/ { ... }` catch-all.
|
||||
#
|
||||
# Both routes are PUBLIC (no forward_auth) — @public_api in Caddy already covers
|
||||
# them, so NO Caddy edit (extraction #8 / Phase A §12).
|
||||
#
|
||||
# KEY DELTA from other navi-* blocks: `^~ /api/offroute` needs a LONG
|
||||
# proxy_read_timeout (130s). Off-network routing runs an in-Python least-cost
|
||||
# search + Valhalla + a per-request `osmium extract` and can take up to ~2 min;
|
||||
# the frontend allows 120s (Phase A §8/§15.8). The matching gunicorn
|
||||
# `--timeout 130` is set in navi-offroute.service. /api/mvum is fast (default).
|
||||
# -----------------------------------------------------------------------------
|
||||
location ^~ /api/offroute {
|
||||
proxy_pass http://127.0.0.1:8428;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Authentik-Username $http_x_authentik_username;
|
||||
proxy_read_timeout 130s; # long-running routing (see above)
|
||||
add_header X-Cache-Status BYPASS;
|
||||
}
|
||||
|
||||
location ^~ /api/mvum {
|
||||
proxy_pass http://127.0.0.1:8428;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Authentik-Username $http_x_authentik_username;
|
||||
proxy_read_timeout 15s;
|
||||
add_header X-Cache-Status BYPASS;
|
||||
}
|
||||
18
backend/deploy/systemd/navi-offroute.service
Normal file
18
backend/deploy/systemd/navi-offroute.service
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[Unit]
|
||||
Description=navi-offroute — off-network router + MVUM API (Echo6 navi-backend, extraction #8)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
# User=zvx is REQUIRED: PADUS PostGIS access uses libpq peer-auth via the local
|
||||
# socket (dbname=padus, no password). zvx is verified to have padus access; a
|
||||
# different user would fail to connect at runtime.
|
||||
User=zvx
|
||||
WorkingDirectory=/home/zvx/projects/repos/navi-backend
|
||||
EnvironmentFile=/etc/navi-backend/navi-offroute.env
|
||||
ExecStart=/home/zvx/projects/repos/navi-backend/.venv/bin/gunicorn 'services.navi_offroute.app:create_app()' --bind 127.0.0.1:8428 --workers 2 --timeout 130
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Loading…
Add table
Add a link
Reference in a new issue