fix(map): complete live Cesium provider path
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Mission Core Map Page + Cesium integration plan
|
||||
|
||||
Status: proposed for product-owner acceptance, 2026-07-29
|
||||
Status: M0–M3 implemented for the local operator contour; operational
|
||||
acceptance in progress, 2026-07-29
|
||||
|
||||
## Objective
|
||||
|
||||
@@ -144,9 +145,9 @@ browser cache, per-application TileCache, Docker volume or a second Gateway.
|
||||
|
||||
### Shared renderer gate
|
||||
|
||||
`@nodedc/page-patterns` already publishes the runtime-neutral Map Page
|
||||
definition, but the Cesium adapter is not a published package. Production reuse
|
||||
requires a shared reviewed package for:
|
||||
`@nodedc/page-patterns` publishes the runtime-neutral Map Page definition and
|
||||
`@nodedc/map-cesium-react@0.1.0` now owns the shared Cesium adapter consumed by
|
||||
Mission Core. The package boundary covers:
|
||||
|
||||
- provider startup and independent imagery/terrain/buildings readiness;
|
||||
- Gateway-proxied Cesium resource creation;
|
||||
@@ -155,16 +156,17 @@ requires a shared reviewed package for:
|
||||
- elevated target and label presentation;
|
||||
- camera and cache-intent application.
|
||||
|
||||
Foundry and Mission Core must consume the same package revision. Copying the
|
||||
Foundry application renderer into Mission Core is rejected. Cesium remains a
|
||||
lazy chunk loaded only when the map workspace opens.
|
||||
Foundry and Mission Core must remain on the same reviewed package revision.
|
||||
Copying the Foundry application renderer into Mission Core remains rejected.
|
||||
Cesium is a lazy chunk loaded only when the map workspace opens.
|
||||
|
||||
## Credential and control-plane decision
|
||||
|
||||
Mission Core does not need to receive a Cesium token to render the map. The
|
||||
existing platform token remains owned by Platform Map Gateway, and Mission Core
|
||||
uses it only after Gateway reports a configured/verified state. The current
|
||||
network check did not independently verify that state.
|
||||
uses it only after Gateway reports a configured/verified state. The connected
|
||||
local Gateway reports `ionConfigured=true` and serves the canonical assets
|
||||
without exposing credentials.
|
||||
|
||||
The proposed `API и ключи` settings section is a write-only Platform
|
||||
control-plane client:
|
||||
@@ -335,15 +337,23 @@ unbounded reconnect loops.
|
||||
|
||||
## Current blockers and evidence
|
||||
|
||||
1. The Cesium adapter is not currently available through a published shared
|
||||
package; exact code reuse is blocked until that boundary exists.
|
||||
2. Mission Core lacks authenticated admin authority, so platform token rotation
|
||||
1. The shared Cesium adapter, Mission Core BFF and real map-first workspace are
|
||||
admitted. Browser acceptance on `127.0.0.1:8000` reports `Карта готова`;
|
||||
imagery, terrain and 3D buildings each report `Готов`, with no blocking map
|
||||
error.
|
||||
2. The connected Gateway is configured with assets `1`, `2` and `96188`.
|
||||
Rendering the acceptance viewport increased the persistent live-cache count
|
||||
from 3270 to 3282 without a browser credential or direct provider route.
|
||||
3. Mission Core lacks authenticated admin authority, so platform token rotation
|
||||
cannot be exposed safely yet.
|
||||
3. K1 currently has no admitted geodetic anchor, so live scanner targets are a
|
||||
4. K1 currently has no admitted geodetic anchor, so live scanner targets are a
|
||||
later data-contract slice.
|
||||
4. From the current Mac network, direct safe probes to the expected private
|
||||
5. From the current Mac network, direct safe probes to the expected private
|
||||
Synology Map Gateway/Platform/AMD health endpoints timed out. End-to-end
|
||||
acceptance requires the intended LAN route; no address will be hard-coded to
|
||||
NAS/cache-only acceptance still requires the intended LAN route. The
|
||||
currently connected development Gateway uses a persistent local Docker
|
||||
volume, so it proves the browser/BFF/Gateway/provider contract but not the
|
||||
final Synology failover path. No address is hard-coded in frontend state to
|
||||
hide this condition.
|
||||
|
||||
None of these blockers requires a new product window, Engine embedding,
|
||||
|
||||
@@ -22,6 +22,7 @@ ALLOWED_ION_ASSET_IDS: Final = frozenset({1, 2, 96188})
|
||||
SAFE_ERROR_CODE = re.compile(r"^[a-z][a-z0-9_]{0,95}$")
|
||||
MAX_JSON_RESPONSE_BYTES: Final = 1024 * 1024
|
||||
MAX_CACHE_TARGET_LENGTH: Final = 8192
|
||||
BING_GATEWAY_KEY_MARKER: Final = "nodedc-gateway"
|
||||
|
||||
REQUEST_HEADER_ALLOWLIST: Final = frozenset(
|
||||
{
|
||||
@@ -325,7 +326,11 @@ def _validate_cache_target(target_url: str) -> None:
|
||||
)
|
||||
if any(
|
||||
key.lower() in CREDENTIAL_QUERY_KEYS
|
||||
for key, _ in parse_qsl(parsed.query, keep_blank_values=True)
|
||||
and not (
|
||||
key.lower() == "key"
|
||||
and value == BING_GATEWAY_KEY_MARKER
|
||||
)
|
||||
for key, value in parse_qsl(parsed.query, keep_blank_values=True)
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
|
||||
@@ -250,6 +250,41 @@ def test_cache_rejects_credentials_non_https_and_non_loopback_clients() -> None:
|
||||
assert not requests
|
||||
|
||||
|
||||
def test_cache_accepts_only_the_public_bing_gateway_key_marker() -> None:
|
||||
service, requests = _service(
|
||||
lambda request: httpx.Response(
|
||||
200,
|
||||
headers={"content-type": "application/json"},
|
||||
content=b"{}",
|
||||
)
|
||||
)
|
||||
|
||||
accepted = asyncio.run(
|
||||
service.proxy_cache(
|
||||
_request("/api/v1/map/gateway/cache"),
|
||||
target_url=(
|
||||
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial"
|
||||
"?key=nodedc-gateway"
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
assert isinstance(accepted, StreamingResponse)
|
||||
assert requests[0].url.params["url"].endswith("key=nodedc-gateway")
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
asyncio.run(
|
||||
service.proxy_cache(
|
||||
_request("/api/v1/map/gateway/cache"),
|
||||
target_url=(
|
||||
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial"
|
||||
"?key=browser-secret"
|
||||
),
|
||||
)
|
||||
)
|
||||
assert exc_info.value.status_code == 422
|
||||
|
||||
|
||||
def test_asset_route_is_a_fixed_allowlist() -> None:
|
||||
service, requests = _service(
|
||||
lambda request: httpx.Response(
|
||||
|
||||
Reference in New Issue
Block a user