navi/backend/pyproject.toml

27 lines
703 B
TOML
Raw Normal View History

[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "navi-backend"
version = "0.1.0"
description = "Echo6 navi-backend monorepo — Navi API services extracted from recon (decoupling project)."
requires-python = ">=3.10"
# Single workspace, single .venv. pytest is included so `pip install -e .` is the
# only setup step needed before running the test suite.
dependencies = [
"Flask>=3.0",
"gunicorn>=21",
"requests>=2.31",
Add navi-config service (extraction #2 PR-B) New services/navi_config/ on :8422, mirroring recon's /api/config contract: - config_route.py: GET /api/config -> jsonify(get_deployment_config()) with Cache-Control: public, max-age=300 (byte-for-byte recon's response). - config_loader.py: faithful port of recon lib/deployment_config.py. Reads RECON_PROFILE (default "home") and NAVI_CONFIG_PROFILES_DIR (default /opt/recon/config/profiles, so it serves the SAME files recon does during cutover). yaml.safe_load, module-level cache. Lazy load (vs recon's eager import-time load) so the module imports cleanly off-VM and a missing profile surfaces as HTTP 500 at request time rather than a failed import. - admin.py: /api/admin/navi-config/info per handoff §4.5, require_auth gated. env values (NAVI_CONFIG_PROFILES_DIR, RECON_PROFILE) are non-secret paths/ names, shown as-is (no mask_key); dependencies=[]; filesystem reports the active profile path + exists/readable. - app.py: create_app() factory mirroring navi_traffic, same metrics wiring; resets the loader cache per instance so each worker/test reloads fresh. Deploy artifacts: systemd unit (:8422) and an nginx snippet using `location ^~ /api/config` (the ^~ convention from extraction #1 so the asset .png/.css regex can't shadow it). No proxy_cache zone — the response is already cached in-process and via Cache-Control: max-age=300; emits a literal X-Cache-Status: BYPASS for parity with navi-traffic. Adds PyYAML>=6 to deps. Tests (services/navi_config/tests): 200 + parsed dict, Cache-Control header, RECON_PROFILE override, default=home, missing profile=500. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 08:25:06 -06:00
"PyYAML>=6",
Add navi-landclass service (extraction #4) (#4) New services/navi_landclass/ on :8424 — single blueprint, behavior-identical port of recon's lib/landclass.py + the /api/landclass handler. GET /api/landclass?lat=&lon= -> { lat, lon, classifications[], count, is_public, is_private, summary }; 400 on bad/out-of-range lat/lon. db.py: faithful port of recon's PostGIS module — lazy module-level psycopg2.pool.SimpleConnectionPool(minconn=1, maxconn=3) from PADUS_DB_* env; the ST_Intersects query on pad_units (antimeridian filter, acres-ordered, limit 10); all PAD-US code->label maps verbatim; graceful degradation (returns [] when PG is unreachable, never raises/500). Adds reset_pool() (create_app resets per worker) and probe_db() (SELECT 1) for admin health. No filesystem state — PostGIS is external. No DB-on-disk migration; only the 5 PADUS_DB_* env vars (PADUS_DB_PASSWORD is a real secret, masked in admin-info via mask_key; the other 4 shown plain). adds psycopg2-binary>=2.9. Decision — DROPPED the recon `has_landclass` profile-flag gate: the frontend already gates on its own has_landclass feature flag, and removing the cross-service config dependency keeps navi-landclass self-contained per the "only API" rule (the service's existence is the feature being available). navi-geo coupling (reverse-bundle needs landclass) — per Phase A, recommend Option B: navi-geo HTTP-calls /api/landclass and reads `.summary` (the endpoint already returns it); no shared module. Decided when #6 lands. Tests (8; recon had 2): point-with-coverage -> classification + decoded labels, ocean point -> empty, bad/missing/out-of-range lat/lon -> 400, PG down -> graceful 200 empty (not 500), format_summary unit. Full suite 46. Deploy: systemd unit (:8424) + nginx snippet (one ^~ /api/landclass block, no proxy_cache; /api/landclass is public so no Caddy edit — TIER 2 already routes through nginx since extraction #2). See ../recon_refactor/extraction-4-phase-a.md (which also corrects the handoff: /mnt/nav/padus/ is source GIS files, NOT a runtime path — this service has no /mnt/nav dependency, only PADUS_DB_* + PG network access). Co-authored-by: Matt Johnson <mj@k7zvx.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:08:58 -06:00
"psycopg2-binary>=2.9",
"pytest>=8",
]
[tool.setuptools.packages.find]
where = ["."]
include = ["shared*", "services*"]
namespaces = true
[tool.pytest.ini_options]
testpaths = ["services"]