Expose AISHub as an optional ships-layer backup when AISStream is silent.

Wire AISHUB_USERNAME into API Keys and onboarding, and surface backup status on the AIS outage banner so operators can keep vessel coverage without changing the AISStream proxy.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
BigBodyCobain
2026-08-09 18:56:30 -06:00
co-authored by Cursor
parent 00f02c2687
commit dc0f69a0b9
12 changed files with 194 additions and 109 deletions
+13
View File
@@ -130,6 +130,7 @@ class TestHealthEndpointEscalation:
body = res.json()
assert body["ais_proxy"]["connected"] is False
assert body["ais_proxy"]["proxy_spawn_count"] == 5
assert "aishub_configured" in body["ais_proxy"]
# Without API_KEY this would stay "ok"; with it set + connected=false,
# we expect at least "degraded" (could be "error" if an SLO is also
# red, but never "ok").
@@ -138,6 +139,18 @@ class TestHealthEndpointEscalation:
f"got {body['status']!r}"
)
def test_health_reports_aishub_configured_flag(self, client, monkeypatch):
_reset_ais_module()
monkeypatch.setenv("AISHUB_USERNAME", "shadowbroker-test")
res = client.get("/api/health")
assert res.status_code == 200
assert res.json()["ais_proxy"]["aishub_configured"] is True
monkeypatch.delenv("AISHUB_USERNAME", raising=False)
res = client.get("/api/health")
assert res.status_code == 200
assert res.json()["ais_proxy"]["aishub_configured"] is False
def test_no_api_key_does_not_escalate(self, client, monkeypatch):
"""When AIS_API_KEY isn't set, the operator hasn't opted in. Don't
flag the system as degraded just because AIS isn't running — that's
@@ -0,0 +1,9 @@
from services.api_settings import ALLOWED_ENV_KEYS, API_REGISTRY
def test_aishub_username_is_in_api_registry():
entry = next((item for item in API_REGISTRY if item.get("env_key") == "AISHUB_USERNAME"), None)
assert entry is not None
assert entry["category"] == "Maritime"
assert entry["required"] is False
assert "AISHUB_USERNAME" in ALLOWED_ENV_KEYS